WAVEWATCH III  beta 0.0.1
mod_xnl4v5.f90
Go to the documentation of this file.
1 
6 
7 !------------------------------------------------------------------------------
13 
14 module m_xnldata
15 !------------------------------------------------------------------------------
16 ! module for computing the quadruplet interaction
17 ! Created by Gerbrant van Vledder
18 !
19 ! version 1.01 16/02/1999 Initial version
20 ! 2.01 01/10/2001 various extensions added
21 ! 3.1.01 01/10/2001 Array's for k4 -locus added
22 ! 3.2 12/05/2002 Triplet data added
23 ! 4.00 08/08/2002 Upgrade to version 4.0
24 ! 4.01 19/08/2002 Various modifications for consistency reasons
25 ! 5.01 9/09/2002 Length of strings aqname and bqname modified
26 ! q_dstep added, step for BQF files
27 ! 11/09/2002 Filtering variables added
28 ! 5.02 12/04/2003 Switch for triplet variables corrected
29 ! 5.03 26/05/2003 Switch for lumping along locus added
30 ! 04/06/2003 Switch for Gauss-Legendre integration added
31 ! 06/06/2003 Switch iq_xdia added and NXDIA removed
32 ! 12/06/2003 Loop indices ik1,ia1,ik3,ia1 added
33 ! 16/06/2003 Switch IQ_SYM introduced
34 ! 04/09/2003 Version string set in subroutine q_version
35 ! 09/09/2003 Parameter id_facmax introduced
36 !------------------------------------------------------------------------------------
37 implicit none
38 !
39 character(len=60) q_version
40 !
41 character(len=20) sub_name
42 character(len=20) qbase
43 character(len=20) qf_error
44 !
45 integer iufind
46 integer iscreen
47 !
48 ! unit numbers for I/O
49 !
50 integer luq_bqf
51 integer luq_cfg
52 integer luq_err
53 integer luq_fil
54 integer luq_grd
55 integer luq_int
56 integer luq_loc
57 integer luq_log
58 integer luq_prt
59 integer luq_trf
60 integer luq_tst
61 integer luq_txt
62 integer luq_t13
63 !------------------------------------------------------------------------------
64 ! physical coefficients, to be obtained through interface XNL_INIT
65 !------------------------------------------------------------------------------
66 real q_grav
67 real qf_tail
69 !------------------------------------------------------------------------------
70 ! filtering coefficients
71 !------------------------------------------------------------------------------
72 real qf_krat
73 real qf_dmax
74 real qf_frac
75 !
76 ! program switches, optionally to be reset in routine Q_SETCONFIG
77 !
78 integer iq_compact
81 !
82 integer iq_cple
88 !
89 integer iq_disp
93 !
94 integer iq_dscale
98 !
99 integer iq_filt
102 !
103 integer iq_gauleg
106 !
107 integer iq_geom
111 !
112 integer iq_grid
116 !
117 integer iq_integ
122 !
123 integer iq_interp
126 !
127 integer iq_locus
131 !
132 integer iq_log
135 !
136 integer iq_lump
139 !
140 integer iq_make
144 !
145 integer iq_mod
148 !
149 integer iq_prt
152 !
153 integer iq_search
156 !
157 integer iq_screen
160 !
161 integer iq_sym
164 !
165 integer iq_test
169 !
170 integer iq_trace
174 !
175 integer iq_trf
178 !
179 integer iq_t13
182 !
183 integer iq_xdia
187 !---------------------------------------------------------------------------------------
188 !
189 !
190 ! grid administration
191 !
192 character(len=13) aqname
193 character(len=13) bqname
194 character(len=13) lastquadfile
195 character(len=21) q_header
196 character(len=21) r_header
197 logical lq_grid
198 !
199 integer nkq
200 integer naq
201 integer ncirc
202 !
203 integer ia_k1,ik_k1
204 integer ia_k3,ik_k3
205 !
206 real fqmin
207 real fqmax
210 !
211 integer, parameter :: mq_stack=10
212 !
213 integer mlocus
214 integer nlocus0
215 integer nlocus1
216 integer klocus
219 integer nlocus
220 integer nlocusx
221 !
222 real kqmin
223 real kqmax
224 real wk_max
225 !
226 real k0x,k0y,dk0
228 real k1x,k1y
229 real k2x,k2y
230 real k3x,k3y
231 real k4x,k4y
232 real px,py
233 real pmag
234 real pang
235 real sang
236 real xang
237 real q
240 real kmid
241 real kmidx
242 real kmidy
245 real loc_xz
246 real loc_yz
247 !
248 ! data for extended input k-grid, necessary when input grid is smaller than
249 ! internal k-grid.
250 !
251 ! real fackx ! geometric spacing factor of input grid
252 ! integer nkx ! new number of k-rings of extended input grid
253 ! real, allocatable :: kx(:) ! extended k-grid
254 ! real, allocatable :: nspecx(:,:) ! extended action density spectrum
255 !
256 ! information about pre_computed locus, only half the angles need to be saved
257 !
258 !
259 integer, allocatable :: quad_nloc(:,:)
260 integer, allocatable :: quad_ik2(:,:,:)
261 integer, allocatable :: quad_ia2(:,:,:)
262 integer, allocatable :: quad_ik4(:,:,:)
263 integer, allocatable :: quad_ia4(:,:,:)
264 real, allocatable :: quad_w1k2(:,:,:)
265 real, allocatable :: quad_w2k2(:,:,:)
266 real, allocatable :: quad_w3k2(:,:,:)
267 real, allocatable :: quad_w4k2(:,:,:)
268 real, allocatable :: quad_w1k4(:,:,:)
269 real, allocatable :: quad_w2k4(:,:,:)
270 real, allocatable :: quad_w3k4(:,:,:)
271 real, allocatable :: quad_w4k4(:,:,:)
272 real, allocatable :: quad_zz (:,:,:)
273 !
274 ! characteristic of computed locus
275 !
276 real, allocatable :: x2_loc(:)
277 real, allocatable :: y2_loc(:)
278 real, allocatable :: z_loc(:)
279 real, allocatable :: s_loc(:)
280 real, allocatable :: x4_loc(:)
281 real, allocatable :: y4_loc(:)
282 real, allocatable :: ds_loc(:)
283 real, allocatable :: jac_loc(:)
284 real, allocatable :: cple_loc(:)
285 real, allocatable :: sym_loc(:)
286 !
287 real, allocatable :: k_pol(:)
288 real, allocatable :: c_pol(:)
289 real, allocatable :: a_pol(:)
290 !
291 ! characteristics of modified locus, result
292 !
293 real, allocatable :: x2_mod(:)
294 real, allocatable :: y2_mod(:)
295 real, allocatable :: x4_mod(:)
296 real, allocatable :: y4_mod(:)
297 real, allocatable :: z_mod(:)
298 real, allocatable :: s_mod(:)
299 real, allocatable :: ds_mod(:)
300 real, allocatable :: jac_mod(:)
301 real, allocatable :: cple_mod(:)
302 real, allocatable :: sym_mod(:)
303 !
304 real, allocatable :: k2m_mod(:)
305 real, allocatable :: k2a_mod(:)
306 real, allocatable :: k4m_mod(:)
307 real, allocatable :: k4a_mod(:)
308 !
309 ! result of subroutine Q_weight
310 !
311 real, allocatable :: wk_k2(:)
312 real, allocatable :: wk_k4(:)
313 real, allocatable :: wa_k2(:)
314 real, allocatable :: wa_k4(:)
315 real, allocatable :: wt_k2(:)
316 real, allocatable :: wt_k4(:)
317 !
318 integer, allocatable :: t_ik2(:)
319 integer, allocatable :: t_ia2(:)
320 integer, allocatable :: t_ik4(:)
321 integer, allocatable :: t_ia4(:)
322 real, allocatable :: t_w1k2(:)
323 real, allocatable :: t_w2k2(:)
324 real, allocatable :: t_w3k2(:)
325 real, allocatable :: t_w4k2(:)
326 real, allocatable :: t_w1k4(:)
327 real, allocatable :: t_w2k4(:)
328 real, allocatable :: t_w3k4(:)
329 real, allocatable :: t_w4k4(:)
330 real, allocatable :: t_zz(:)
331 !
332 ! corresponding declarations
333 !
334 integer, allocatable :: r_ik2(:)
335 integer, allocatable :: r_ia2(:)
336 integer, allocatable :: r_ik4(:)
337 integer, allocatable :: r_ia4(:)
338 real, allocatable :: r_w1k2(:),r_w2k2(:),r_w3k2(:),r_w4k2(:)
339 real, allocatable :: r_w1k4(:),r_w2k4(:),r_w3k4(:),r_w4k4(:)
340 real, allocatable :: r_zz(:),r_jac(:),r_cple(:),r_sym(:),r_ws(:)
341 !
342 real, allocatable :: dt13(:)
343 !
344 real, allocatable :: q_xk(:)
345 real, allocatable :: q_sk(:)
346 real sk_max
347 !
348 real, allocatable :: q_k(:)
349 real, allocatable :: q_dk(:)
350 real, allocatable :: q_kpow(:)
351 real, allocatable :: q_f(:)
352 real, allocatable :: q_df(:)
353 real, allocatable :: q_sig(:)
354 real, allocatable :: q_dsig(:)
355 real, allocatable :: q_cg(:)
356 real, allocatable :: q_a(:)
357 real, allocatable :: q_ad(:)
358 real, allocatable :: a(:,:)
359 real, allocatable :: nspec(:,:)
360 real, allocatable :: nk1d(:)
361 real, allocatable :: qnl(:,:)
362 !
363 integer id_facmax
370 !
371 real eps_q
372 real eps_k
373 real rel_k
374 !
375 integer iq_stack
376 character(len=21) cstack(mq_stack)
377 !
378 ! characteristics of locus
379 !
380 real crf1
381 !---------------------------------------------------------------------------------
382 !
383 ! information about type of grid
384 !
385 integer iaref
386 integer iamax
387 integer iaq1,iaq2
388 integer iag1,iag2
392 !
393 real q_ffac
394 real q_kfac
397 !
398 !-----------------------------------------------------------------------------
399 !
400 !!/R real wq2(4) ! interpolation weights for k2
401 !!/R real wq4(4) ! interpolation weights for k4
402 !!/R real wqw ! overall weight of contribution
403 !!/R real wtriq(40) ! triplet weights
404 !!/R integer ikq2(4) ! wave number index for k2
405 !!/R integer idq2(4) ! angle index for k2
406 !!/R integer ikq4(4) ! wave number index for k4
407 !!/R integer idq4(4) ! angle index for k4
408 !!/R integer iktriq(40,3) ! k-indices of triplets
409 !!/R integer idtriq(40,3) ! direction indices of triplets
410 
411 !
412 !============== General settings =================
413 !
414 integer iq_type
421 !
422 integer iq_err
427 !
428 integer iq_warn
429 !
430 ! indices for test output of actual integration
431 ! these values are set and optionally modified in Q_SETCONFIG
432 !
433 contains
434 !----------------------------------------------------------------------------------
435 
461 !------------------------------------------------------------------------------
462 
463 subroutine xnl_init(sigma,dird,nsigma,ndir,pftail,x_grav,depth,ndepth, &
464 & iquad,iqgrid,iproc,ierr)
465 !------------------------------------------------------------------------------
466 !
467 ! +-------+ ALKYON Hydraulic Consultancy & Research
468 ! | | Gerbrant van Vledder
469 ! | +---+
470 ! | | +---+ Last update: 4 September 2003
471 ! +---+ | | Release: 5.03
472 ! +---+
473 !
474 use m_fileio
475 use m_constants
476 ! do not use m_xnldata
477 !
478 implicit none
479 !
480 ! 0. Update history
481 !
482 ! 10/01/2001 Initial version
483 ! 14/02/2001 Release 3
484 ! 06/11/2001 Depth forced to 1000 when iquad ==1,2
485 ! 08/08/2002 Upgrade to version 4
486 ! 19/08/2002 Extra test output
487 ! 22/08/2002 User defined directions stored in Quad-system
488 ! 26/08/2002 Minimum water depth in variable q_mindepth
489 ! 09/09/2002 Initialized LASTQUADFILE
490 ! 10/09/2002 Initialisation of Q_DSTEP
491 ! 11/09/2002 Called of Q_ALLOC moved to location after Q_SETCFG
492 ! Output unit luq_fil added
493 ! 16/09/2002 Parameter IPROC added to take are of MPI
494 ! 25/09/2002 Check added for directions of sector grid
495 ! 25/04/2003 name q_alloc changed to q_allocate
496 ! 04/06/2003 variable IQ_INT renamed IQ_INTEG
497 ! 11/06/2003 Call to Q_SETCFG changed into Q_SETCONFIG
498 ! Call to Q_CHKCFG changed into Q_CHKCONFIG
499 ! Call to subroutine Q_SUMMARY added
500 ! Compute size of points on locus, stored in KLOCUS
501 ! 13/06/2003 Test parameters moved to Q_SETCONFIG
502 ! 04/09/2003 Routine Q_SETVERSION added
503 !
504 ! 1. Purpose:
505 !
506 ! Initialize coefficients, integration space, file i/o for computation
507 ! nonlinear quadruplet wave-wave interaction
508 !
509 ! 2. Method
510 !
511 ! Set version number
512 ! Set unit unit numbers
513 ! Open quad related files
514 ! Optionally reset configuration by a back door option
515 ! Compute integration spaces for given water depths
516 !
517 ! 3. Parameter list:
518 !
519 !Type I/O Name Description
520 !------------------------------------------------------------------------------
521 integer, intent(in) :: nsigma ! Number of sigma values
522 integer, intent(in) :: ndir ! Number of directions
523 integer, intent(in) :: ndepth ! Number of water depths
524 real, intent(in) :: sigma(nsigma) ! Radian frequencies
525 real, intent(in) :: dird(ndir) ! Directions (degrees)
526 real, intent(in) :: pftail ! power of spectral tail, e.g. -4 or -5
527 real, intent(in) :: depth(ndepth) ! depths for which integration space must be computed
528 real, intent(in) :: x_grav ! gravitational acceleration
529 integer, intent(in) :: iquad ! Type of method for computing nonlinear interactions
530 integer, intent(in) :: iqgrid ! Type of grid for computing nonlinear interactions
531 integer, intent(in) :: iproc ! Processor number, controls output file for MPI
532 integer, intent(out) :: ierr ! Error indicator. If no errors are detected IERR=0
533 !
534 ! 4. Error messages
535 !
536 ! An error message is produced within the QUAD system.
537 ! If no errors are detected IERROR=0
538 ! otherwise IERROR > 0
539 !
540 ! ierr Description of error
541 ! -------------------------------
542 ! 1 Invalid value of iquad
543 ! 2 Invalid value of iq_grid
544 ! 3 Incompatability between iq_grid and input directions
545 ! 4 Error in deleting *.ERR file
546 ! 5 Error generated by Q_SETCONFIG
547 ! 6 Error generated by Q_CHKCFG
548 ! 7 Error generated by Q_CTRGRID
549 !
550 ! 5. Called by:
551 !
552 ! host program, e.g. SWANQUAD4
553 !
554 ! 6. Subroutines used:
555 !
556 ! Q_SETVERSION
557 ! Q_SETCONFIG
558 ! Q_CHKCFG
559 ! Q_SUMMARY
560 ! Q_ALLOCATE
561 ! Q_CTRGRID
562 ! Q_INIT
563 !
564 ! 7. Remarks
565 !
566 ! 8. Structure
567 !
568 ! 9. Switches
569 !
570 ! 10. Source code
571 !---------------------------------------------------------------------------------------
572 !
573 ! Local parameters
574 !
575 integer iuerr
576 integer idepth
577 integer igrid
578 integer ia,ik
579 !
580 real depmin
581 real dstep
582 real dgap
583 !
584 call q_setversion ! set version number
585 !------------------------------------------------------------------------------
586 ! user defined settings
587 !------------------------------------------------------------------------------
588 q_mindepth = 0.1 ! Set minimum water depth
589 q_maxdepth = 2000 ! Set maximum water depth
590 q_dstep = 0.1 ! Set minimum step for coding depth files
591 iscreen = 6 ! Identifier for screen output (UNIX=0, WINDOWS=6)
592 iufind = 1 ! search for unit numbers automatically
593 !----------------------------------------------------------------------------
594 ! Initialisations
595 !
596 ierr = 0 ! set error condition
597 iq_stack = 0 ! initialize stack for tracing subroutines
598 qbase = 'xnl4v5' ! Base name for quadruplet files
599 qf_error = 'xnl5_errors.txt' ! Text file with error messages
600 lastquadfile = 'quad?????.bqf' ! Initialize name of last retrieved quad file
601 !
602 ! set values of physical quantities
603 ! and store them in quad data area
604 !
605 q_grav = x_grav ! gravitational acceleration
606 qf_tail = pftail ! Power of parametric spectral tail
607 iq_type = iquad ! Type of method to compute transfer
608 iq_interp = 1 ! apply bi-linear interpolation
609 iq_prt = 0 ! Print output on, to file /qbase/.prt
610 iq_test = 0 ! test level
611 iq_trace = 0 ! level of subroutine trace
612 iq_log = 0 ! Set logging of q_routines off
613 iq_grid = iqgrid ! Grid type for computation of nonlinear transfer
614 iq_screen = 0 ! enable output to screen
615 !
616 !------------------------------------------------------------------------------
617 ! Check input
618 !------------------------------------------------------------------------------
619 if(iq_type<1 .or. iq_type>3) then
620  ierr = 1
621  goto 9999
622 end if
623 !
624 if(iq_grid<1 .or. iq_grid>3) then
625  ierr = 2
626  goto 9999
627 end if
628 !
629 ! Retrieve size of spectral grid from input
630 !
631 fqmin = sigma(1)/(2.*pi) ! minimum frequency in Hz
632 fqmax = sigma(nsigma)/(2.*pi) ! maximum frequency in Hz
633 nkq = nsigma ! number of frequencies/wave numbers
634 naq = ndir ! number of directions
635 !
636 ! check if directions are given on full circle or in a symmetric sector
637 !----------------------------------------------------------------------------
638 ! 1: compute directional step
639 ! 2: compute gap between first and last
640 ! 3: compare gap with step
641 !
642 dstep = dird(2)-dird(1) ! directional step
643 dgap = 180.- abs(180.- abs(dird(1)-dird(ndir))) ! directional gap
644 !
645 !----------------------------------------------------------------------
646 if(iq_grid==1 .or. iq_grid==2) then
647 !
648 ! check if gap equal to step in the case of full circle
649 !
650  if(abs(dstep-dgap) < 0.001) then
651  ierr = 31
652  goto 9999
653  end if
654 !
655 ! check if sector is symmetric around zero in the case of sector grid
656 !
657  if(abs(dird(1)+dird(ndir)) > 0.01) then
658  ierr = 32
659  goto 9999
660  end if
661 end if
662 !
663 q_dird1 = dird(1)
664 q_dird2 = dird(ndir)
665 !
666 ! assign unit numbers for QUAD related files
667 !
668 ! If IUFIND=0, fixed prespecified unit numbers must be given
669 ! IUFIND=1, the numbers are searched automatically
670 !
671 if(iufind==0) then
672  luq_err = 103
673  luq_tst = 104
674  luq_int = 105
675  luq_log = 106
676  luq_prt = 107
677  luq_cfg = 108
678  luq_bqf = 109
679  luq_grd = 110
680  luq_txt = 111
681  luq_loc = 112
682  luq_trf = 113
683  luq_t13 = 114
684  luq_fil = 117
685 end if
686 !
687 ! delete old Error file, if it exists
688 !
689 call z_fileio(trim(qbase)//'.err','DF',iufind,luq_err,iuerr)
690 if(iuerr/=0) then
691  call q_error('e','FILEIO','Problem in deleting error file *.ERR')
692  ierr = 4
693  goto 9999
694 end if
695 !
696 ! create new files, first create logging file
697 !
698 call z_fileio(trim(qbase)//'.log','UF',iufind,luq_log,iuerr) ! logging
699 call z_fileio(trim(qbase)//'.prt','UF',iufind,luq_prt,iuerr) ! general print file
700 call z_fileio(trim(qbase)//'.tst','UF',iufind,luq_tst,iuerr) ! test output
701 !
702 !
703 write(luq_log,'(2a,i4)') 'XNL_INIT: ',trim(qbase)//'.log connected to :',luq_log
704 write(luq_log,'(2a,i4)') 'XNL_INIT: ',trim(qbase)//'.prt connected to :',luq_prt
705 write(luq_log,'(2a,i4)') 'XNL_INIT: ',trim(qbase)//'.tst connected to :',luq_tst
706 !
707 !
708 write(luq_prt,'(a)') '---------------------------------------------------------------'
709 write(luq_prt,'(a)') trim(q_version)
710 write(luq_prt,'(a)') 'Solution of Boltzmann integral using Webb/Resio/Tracy method'
711 write(luq_prt,'(a)') '---------------------------------------------------------------'
712 write(luq_prt,*)
713 write(luq_prt,'(a)') 'Initialisation'
714 write(luq_prt,*)
715 !
716 if(iproc >=0) write(luq_prt,'(a,i5)') '(MPI) processor number:',iproc
717 !---------------------------------------------------------------------------------
718 ! Reset configuration from file, using a backdoor
719 !---------------------------------------------------------------------------------
720 call q_setconfig(iquad)
721 if (iq_err /=0) then
722  ierr = 5
723  goto 9999
724 end if
725 !---------------------------------------------------------------------------------
726 ! check settings for inconsistencies
727 !---------------------------------------------------------------------------------
728 call q_chkconfig
729 if (iq_err /=0) then
730  ierr = 6
731  goto 9999
732 end if
733 !---------------------------------------------------------------------------------
734 ! determine minimum size of number of points on locus as stored in database
735 !---------------------------------------------------------------------------------
736 klocus = nlocus0
737 if(iq_gauleg > 0) klocus = min(iq_gauleg,klocus)
738 if(iq_lump > 0) klocus = min(iq_lump,klocus)
739 !---------------------------------------------------------------------------------
740 ! write summary of program settings
741 !---------------------------------------------------------------------------------
742 call q_summary
743 !----------------------------------------------------------------------------------
744 ! allocate data arrays
745 !-----------------------------------------------------------------------------
746 call q_allocate
747 !------------------------------------------------------------------------------
748 ! Generate interaction grid and coefficients for each valid water depth
749 ! Q_CTRGRID controls grid generation
750 !------------------------------------------------------------------------------
751 do idepth=1,ndepth
752  q_depth = depth(idepth)
753 !
754  if(iquad==1 .or. iquad==2) q_depth = q_maxdepth
755 !
756  if(q_depth < q_mindepth) then
757  call q_error('w','DEPTH','Invalid depth')
758  write(luq_err,'(a,e12.5,f10.2)') 'Incorrect depth & minimum:',q_depth,q_mindepth
759  else
760  call q_init
761  call q_ctrgrid(2,igrid)
762  if(iq_err /= 0) then
763  ierr = 7
764  goto 9999
765  end if
766  end if
767 !
768  if(iquad==1 .and. ndepth > 0) then
769  write(luq_prt,'(a)') 'XNL_INIT: For deep water only one grid suffices'
770  exit
771  end if
772 end do
773 !
774 !
775 ! Create or open triplet output data file if iq_triq > 0
776 !
777 !
778 9999 continue
779 !
780 !! if (iq_log ==0) call z_fileio(trim(qbase)//'.log','DF',iufind,luq_log,iuerr)
781 !! if (iq_prt ==0) call z_fileio(trim(qbase)//'.prt','DF',iufind,luq_prt,iuerr)
782 !
783 !
784 return
785 end subroutine xnl_init
786 
806 !-----------------------------------------------------------------------------!
807 
808 subroutine xnl_main(aspec,sigma,angle,nsig,ndir,depth,iquad,xnl,diag, &
809 & iproc, ierr)
810 !-----------------------------------------------------------------------------!
811 !
812 ! +-------+ ALKYON Hydraulic Consultancy & Research
813 ! | | Gerbrant Ph. van Vledder
814 ! | +---+
815 ! | | +---+ Last update: 27 Sept. 2002
816 ! +---+ | | Release: 5.0
817 ! +---+
818 !
819 ! do not use m_xnldata
820 use serv_xnl4v5
821 !
822 implicit none
823 !
824 ! 0. Update history
825 !
826 ! 25/02/1999 Initial version
827 ! 25/07/1999 Various restructurations
828 ! 12/10/1999 Error handling improved
829 ! 15/10/1999 Existing test file deleted
830 ! 25/10/1999 Parameter iq_filt added
831 ! 29/10/1999 iq_call renamed to i_qmain and save statement added
832 ! 08/12/1999 Call to CHKLAW included
833 ! 16/12/1999 Extra output and check for wave number range
834 ! 27/12/1999 Expansion of k-grid now in new subroutine Q_EXPAND
835 ! 06/01/2000 Deallocate of KX and NSPECX removed
836 ! 08/01/2000 Recontructed, subroutine Q_WRTVV splitted off
837 ! 12/01/2000 Diagonal term added to interface
838 ! 26/06/2000 Name changed to XNL_MAIN
839 ! 01/02/2001 Interface change, spectrum must be given as Action density(sigma,theta)
840 ! 06/11/2001 Water depth forced to 1000 when IQUAD==1,2
841 ! 13/08/2002 Upgrade to release 4.0
842 ! 20/08/2002 Action density array copied to internal A-array
843 ! 09/09/2002 Upgrade to release 5
844 ! 16/09/2002 Parameter IPROC included to take care of MPI processors
845 ! 27/09/2002 Description of input argument SIGMA corrected
846 !
847 ! 1. Purpose:
848 !
849 ! Compute nonlinear transfer for a given action density spectrum
850 ! on a given sigma and direction grid
851 !
852 ! 2. Method
853 !
854 ! Webb/Resio/Tracy/Van Vledder
855 !
856 ! 3. Parameter list:
857 !
858 ! Type I/O Name Description
859 !---------------------------------------------------------------------------------------------
860 integer,intent(in) :: nsig ! number of frequencies (sigma)
861 integer,intent(in) :: ndir ! number of directions
862 integer,intent(in) :: iquad ! method of computing nonlinear quadruplet interactions
863 integer, intent(in) :: iproc ! MPI processor number
864 !
865 real, intent(in) :: aspec(nsig,ndir) ! Action density spectrum as a function of (sigma,theta)
866 real, intent(in) :: sigma(nsig) ! radian frequencies
867 real, intent(in) :: angle(ndir) ! directions in radians (sector or full circle)
868 real, intent(in) :: depth ! water depth
869 real, intent(out) :: xnl(nsig,ndir) ! nonlinear quadruplet interaction computed with
870 ! a certain exact method (k,theta)
871 real, intent(out) :: diag(nsig,ndir) ! diagonal term for semi-implicit integration
872 integer, intent(out) :: ierr ! error indicator
873 !
874 !--------------------------------------------------------------------------------
875 !
876 ! 4. Error messages
877 !
878 ! 5. Called by:
879 !
880 ! host program
881 !
882 ! 6. Subroutines used
883 !
884 ! Q_DSCALE WAM depth scaling
885 ! Q_XNL4V4 Xnl using Webb/Resio/Tracy/VanVledder
886 ! Q_STACK Stack administration
887 ! Q_CHKCONS Check conservation of energy, action and momentum
888 !
889 ! 7. Remarks
890 !
891 ! 8. Structure
892 !
893 ! 9. Switches
894 !
895 ! 10. Source code:
896 !--------------------------------------------------------------------------------
897 ! local variables
898 !
899 integer, save :: i_qmain
900 integer i_qlast
901 !
902 integer isig
903 integer idir
904 real q_dfac
905 !
906 real sum_e
907 real sum_a
908 real sum_mx
909 real sum_my
910 !
911 data i_qmain /0/
912 data i_qlast /0/
913 !
914 !--------------------------------------------------------------------------------
915 !
916 iq_stack =0 ! initialize stack order every time qmain is called
917 !
918 call q_stack('+xnl_main')
919 !
920 i_qmain = i_qmain + 1
921 !
922 if(iq_prt>=1) then
923  write(luq_prt,*)
924  write(luq_prt,'(a,i4,f16.3,i4)') 'XNL_MAIN: Input arguments: iquad depth iproc:',&
925 & iquad,depth,iproc
926 end if
927 !
928 ! initialisations for error handling
929 !
930 iq_err = 0 ! No errors detected at start
931 q_depth = depth ! water depth to be used in computation
932 !
933 if(iquad==1 .or. iquad==2) q_depth=1000.
934 ! !
935 ! check water depth to be used in computation
936 !
937 if(q_depth < q_mindepth) then
938  xnl = 0.
939  call q_error('w','DEPTH','Zero transfer returned')
940  goto 9999
941 end if
942 !
943 ! check if iquad has changed since last call, this is no more allowed
944 !
945 !!if (iquad /= i_qlast .and. i_qmain/=1) then
946 !! call q_error('e','IQUAD','Value of IQUAD differs from initial value')
947 !! ierr = 1
948 !! goto 9999
949 !!end if
950 !-----------------------------------------------------------------------------+
951 ! main choice between various options |
952 !-----------------------------------------------------------------------------+
953 !
954 if(iquad>=1 .and. iquad <=3) then
955 !
956  a = aspec
957  call q_xnl4v4(aspec,sigma,angle,nsig,ndir,depth,xnl,diag,ierr)
958 !
959  if(ierr/=0) then
960  call q_error('e','wrtvv','Problem in Q_XNL4V4')
961  goto 9999
962  end if
963 !------------------------------------------------------------------------------
964 ! compute scale factor to include WAM depth scaling
965 !------------------------------------------------------------------------------
966 !
967  if(iq_dscale ==1) then
968  call q_dscale(aspec,sigma,angle,nsig,ndir,depth,q_grav,q_dfac)
969 !
970  xnl = xnl*q_dfac
971 !
972  if(iq_prt >=1) write(luq_prt,'(a,f7.4)') 'XNL_MAIN depth scale factor:',q_dfac
973  end if
974 end if
975 !
976 ! check conservation laws
977 !
978  call q_chkcons(xnl,nsig,ndir,sum_e,sum_a,sum_mx,sum_my)
979 !
980  if(iq_prt >= 1) then
981  write(luq_prt,'(a)') 'XNL_MAIN: Conservation checks'
982  write(luq_prt,'(a,4e13.5)') 'XNL_MAIN: E/A/MOMX/MOMY:',sum_e,sum_a,sum_mx,sum_my
983  end if
984 !
985 9999 continue
986 !
987 ierr = iq_err
988 !
989 if(iq_log >= 1) then
990  write(luq_log,*)
991  write(luq_log,'(a,i4)') 'XNL_MAIN: Number of warnings:',iq_warn
992  write(luq_log,'(a,i4)') 'XNL_MAIN: Number of errors :',iq_err
993 end if
994 !
995 !!i_qlast = iquad
996 !
997 call q_stack('-xnl_main')
998 !
999 return
1000 end subroutine
1001 !------------------------------------------------------------------------------
1002 
1010 
1011 subroutine q_allocate
1012 !------------------------------------------------------------------------------
1013 !
1014 ! +-------+ ALKYON Hydraulic Consultancy & Research
1015 ! | | Gerbrant van Vledder
1016 ! | +---+
1017 ! | | +---+ Last update: 8 August 2003
1018 ! +---+ | | Release: 5.0
1019 ! +---+
1020 !
1021 ! do not use m_xnldata
1022 implicit none
1023 !
1024 !
1025 ! 0. Update history
1026 !
1027 ! 05/10/1999 initial version
1028 ! 25/11/1999 logging output added
1029 ! 10/01/2001 Inconsistency fixed
1030 ! 01/10/2001 Array's for k4-locus added
1031 ! 08/08/2002 Upgrade to release 4.0
1032 ! 20/08/2002 Internal action density spectrum added A
1033 ! 11/09/2002 q_kpow added
1034 ! 25/04/2003 Name modified from q_alloc -> q_allocate
1035 ! Triplet array added
1036 ! 02/05/2003 Bug fixed in allocate of triplet arrays
1037 ! 11/06/2003 Array SYM_LOC added
1038 ! Parameter KLOCUS introduced for actual maximum size of locus
1039 ! 16/06/2003 Loci information included, moved from Q_XNL4V4
1040 ! 08/08/2003 Value of MLOCUS modified, now 1.3*NLOCUS0, was 1.2
1041 !
1042 ! 1. Purpose:
1043 !
1044 ! Check configuration for non-linear transfer
1045 !
1046 ! 2. Method
1047 !
1048 ! Allocate data arrays
1049 !
1050 ! 3. Parameters used
1051 !
1052 ! 4. Error messaged
1053 !
1054 ! 5. Called by:
1055 !
1056 ! XNL_INIT
1057 !
1058 ! 6. Subroutines used
1059 !
1060 ! Q_STACK
1061 !
1062 ! 7. Remarks
1063 !
1064 ! 8. Stucture
1065 !
1066 ! 9. Switches
1067 !
1068 ! /S Subroutine tracing
1069 !
1070 ! 10. Source code
1071 !-------------------------------------------------------------------------------
1072 !
1073 ! Local variables
1074 !-------------------------------------------------------------------------------
1075 integer maq
1076 integer mkq
1077 !-------------------------------------------------------------------------------
1078 call q_stack('+q_allocate')
1079 !
1080 if(iq_geom==0) then
1081  mkq = nkq*(nkq+1)/2
1082 else
1083  mkq = nkq
1084 end if
1085 !
1086 maq = naq/2+1
1087 mlocus = 1.3*nlocus0
1088 !
1089 if(iq_log >=1) write(luq_log,'(a,4i4)') &
1090 & 'Q_ALLOCATE: mkq maq mlocus klocus:',mkq,maq,mlocus,klocus
1091 !
1092 if (allocated (q_xk)) deallocate (q_xk) ; allocate(q_xk(0:nkq))
1093 if (allocated (q_sk)) deallocate (q_sk) ; allocate(q_sk(0:nkq))
1094 !
1095 if (allocated (quad_nloc)) deallocate (quad_nloc) ; allocate (quad_nloc(mkq,maq))
1096 if (allocated (quad_ik2)) deallocate (quad_ik2) ; allocate (quad_ik2(mkq,maq,klocus))
1097 if (allocated (quad_ia2)) deallocate (quad_ia2) ; allocate (quad_ia2(mkq,maq,klocus))
1098 if (allocated (quad_ik4)) deallocate (quad_ik4) ; allocate (quad_ik4(mkq,maq,klocus))
1099 if (allocated (quad_ia4)) deallocate (quad_ia4) ; allocate (quad_ia4(mkq,maq,klocus))
1100 if (allocated (quad_w1k2)) deallocate (quad_w1k2) ; allocate (quad_w1k2(mkq,maq,klocus))
1101 if (allocated (quad_w2k2)) deallocate (quad_w2k2) ; allocate (quad_w2k2(mkq,maq,klocus))
1102 if (allocated (quad_w3k2)) deallocate (quad_w3k2) ; allocate (quad_w3k2(mkq,maq,klocus))
1103 if (allocated (quad_w4k2)) deallocate (quad_w4k2) ; allocate (quad_w4k2(mkq,maq,klocus))
1104 if (allocated (quad_w1k4)) deallocate (quad_w1k4) ; allocate (quad_w1k4(mkq,maq,klocus))
1105 if (allocated (quad_w2k4)) deallocate (quad_w2k4) ; allocate (quad_w2k4(mkq,maq,klocus))
1106 if (allocated (quad_w3k4)) deallocate (quad_w3k4) ; allocate (quad_w3k4(mkq,maq,klocus))
1107 if (allocated (quad_w4k4)) deallocate (quad_w4k4) ; allocate (quad_w4k4(mkq,maq,klocus))
1108 if (allocated (quad_zz)) deallocate (quad_zz) ; allocate (quad_zz(mkq,maq,klocus))
1109 !
1110 if (allocated(x2_loc)) deallocate(x2_loc) ; allocate (x2_loc(mlocus))
1111 if (allocated(y2_loc)) deallocate(y2_loc) ; allocate (y2_loc(mlocus))
1112 if (allocated(x4_loc)) deallocate(x4_loc) ; allocate (x4_loc(mlocus))
1113 if (allocated(y4_loc)) deallocate(y4_loc) ; allocate (y4_loc(mlocus))
1114 if (allocated(z_loc)) deallocate(z_loc) ; allocate (z_loc(mlocus))
1115 if (allocated(s_loc)) deallocate(s_loc) ; allocate (s_loc(mlocus))
1116 if (allocated(ds_loc)) deallocate(ds_loc) ; allocate (ds_loc(mlocus))
1117 if (allocated(jac_loc)) deallocate(jac_loc) ; allocate (jac_loc(mlocus))
1118 if (allocated(cple_loc)) deallocate(cple_loc) ; allocate (cple_loc(mlocus))
1119 if (allocated(a_pol)) deallocate(a_pol) ; allocate (a_pol(mlocus))
1120 if (allocated(c_pol)) deallocate(c_pol) ; allocate (c_pol(mlocus))
1121 if (allocated(k_pol)) deallocate(k_pol) ; allocate (k_pol(mlocus))
1122 if (allocated(sym_loc)) deallocate (sym_loc) ; allocate (sym_loc(mlocus))
1123 !
1124 if (allocated(x2_mod)) deallocate (x2_mod) ; allocate (x2_mod(mlocus))
1125 if (allocated(y2_mod)) deallocate (y2_mod) ; allocate (y2_mod(mlocus))
1126 if (allocated(x4_mod)) deallocate (x4_mod) ; allocate (x4_mod(mlocus))
1127 if (allocated(y4_mod)) deallocate (y4_mod) ; allocate (y4_mod(mlocus))
1128 if (allocated(z_mod)) deallocate (z_mod) ; allocate (z_mod(mlocus))
1129 if (allocated(s_mod)) deallocate (s_mod) ; allocate (s_mod(mlocus))
1130 if (allocated(ds_mod)) deallocate (ds_mod) ; allocate (ds_mod(mlocus))
1131 if (allocated(jac_mod)) deallocate (jac_mod) ; allocate (jac_mod(mlocus))
1132 if (allocated(cple_mod)) deallocate (cple_mod) ; allocate (cple_mod(mlocus))
1133 if (allocated(sym_mod)) deallocate (sym_mod) ; allocate (sym_mod(mlocus))
1134 !
1135 if (allocated(k2m_mod)) deallocate (k2m_mod) ; allocate (k2m_mod(mlocus))
1136 if (allocated(k2a_mod)) deallocate (k2a_mod) ; allocate (k2a_mod(mlocus))
1137 if (allocated(k4m_mod)) deallocate (k4m_mod) ; allocate (k4m_mod(mlocus))
1138 if (allocated(k4a_mod)) deallocate (k4a_mod) ; allocate (k4a_mod(mlocus))
1139 !
1140 if (allocated(wk_k2)) deallocate(wk_k2) ; allocate (wk_k2(mlocus))
1141 if (allocated(wa_k2)) deallocate(wa_k2) ; allocate (wa_k2(mlocus))
1142 if (allocated(wt_k2)) deallocate(wt_k2) ; allocate (wt_k2(mlocus))
1143 if (allocated(wk_k4)) deallocate(wk_k4) ; allocate (wk_k4(mlocus))
1144 if (allocated(wa_k4)) deallocate(wa_k4) ; allocate (wa_k4(mlocus))
1145 if (allocated(wt_k4)) deallocate(wt_k4) ; allocate (wt_k4(mlocus))
1146 !
1147 !if (allocated(t_wk2)) deallocate (t_wk2) ; allocate (t_wk2(mlocus))
1148 !if (allocated(t_wa2)) deallocate (t_wa2) ; allocate (t_wa2(mlocus))
1149 !if (allocated(t_wt2)) deallocate (t_wt2) ; allocate (t_wt2(mlocus))
1150 !if (allocated(t_wk4)) deallocate (t_wk4) ; allocate (t_wk4(mlocus))
1151 !if (allocated(t_wa4)) deallocate (t_wa4) ; allocate (t_wa4(mlocus))
1152 !if (allocated(t_wt4)) deallocate (t_wt4) ; allocate (t_wt4(mlocus))
1153 !if (allocated(t_sym)) deallocate (t_sym) ; allocate (t_sym(mlocus))
1154 !if (allocated(t_grad)) deallocate (t_grad); allocate (t_grad(mlocus))
1155 !if (allocated(t_cple)) deallocate (t_cple); allocate (t_cple(mlocus))
1156 !if (allocated(t_s)) deallocate (t_s) ; allocate (t_s(mlocus))
1157 !if (allocated(t_ds)) deallocate (t_ds) ; allocate (t_ds(mlocus))
1158 !
1159 !------------------------------------------------------------------------------
1160 ! allocate data arrays for transformation of locus information
1161 ! and integration along locus
1162 !-----------------------------------------------------------------------------
1163 if (allocated(r_ik2)) deallocate (r_ik2) ; allocate (r_ik2(klocus))
1164 if (allocated(r_ia2)) deallocate (r_ia2) ; allocate (r_ia2(klocus))
1165 if (allocated(r_ik4)) deallocate (r_ik4) ; allocate (r_ik4(klocus))
1166 if (allocated(r_ia4)) deallocate (r_ia4) ; allocate (r_ia4(klocus))
1167 if (allocated(r_w1k2)) deallocate (r_w1k2) ; allocate (r_w1k2(klocus))
1168 if (allocated(r_w2k2)) deallocate (r_w2k2) ; allocate (r_w2k2(klocus))
1169 if (allocated(r_w3k2)) deallocate (r_w3k2) ; allocate (r_w3k2(klocus))
1170 if (allocated(r_w4k2)) deallocate (r_w4k2) ; allocate (r_w4k2(klocus))
1171 if (allocated(r_w1k4)) deallocate (r_w1k4) ; allocate (r_w1k4(klocus))
1172 if (allocated(r_w2k4)) deallocate (r_w2k4) ; allocate (r_w2k4(klocus))
1173 if (allocated(r_w3k4)) deallocate (r_w3k4) ; allocate (r_w3k4(klocus))
1174 if (allocated(r_w4k4)) deallocate (r_w4k4) ; allocate (r_w4k4(klocus))
1175 if (allocated(r_zz)) deallocate (r_zz) ; allocate (r_zz(klocus))
1176 !-------------------------------------------------------------------------------
1177 if (allocated(t_ik2)) deallocate (t_ik2) ; allocate (t_ik2(klocus))
1178 if (allocated(t_ia2)) deallocate (t_ia2) ; allocate (t_ia2(klocus))
1179 if (allocated(t_ik4)) deallocate (t_ik4) ; allocate (t_ik4(klocus))
1180 if (allocated(t_ia4)) deallocate (t_ia4) ; allocate (t_ia4(klocus))
1181 if (allocated(t_w1k2)) deallocate (t_w1k2) ; allocate (t_w1k2(klocus))
1182 if (allocated(t_w2k2)) deallocate (t_w2k2) ; allocate (t_w2k2(klocus))
1183 if (allocated(t_w3k2)) deallocate (t_w3k2) ; allocate (t_w3k2(klocus))
1184 if (allocated(t_w4k2)) deallocate (t_w4k2) ; allocate (t_w4k2(klocus))
1185 if (allocated(t_w1k4)) deallocate (t_w1k4) ; allocate (t_w1k4(klocus))
1186 if (allocated(t_w2k4)) deallocate (t_w2k4) ; allocate (t_w2k4(klocus))
1187 if (allocated(t_w3k4)) deallocate (t_w3k4) ; allocate (t_w3k4(klocus))
1188 if (allocated(t_w4k4)) deallocate (t_w4k4) ; allocate (t_w4k4(klocus))
1189 if (allocated(t_zz)) deallocate (t_zz) ; allocate (t_zz(klocus))
1190 !-------------------------------------------------------------------------------
1191 if (allocated(dt13)) deallocate (dt13) ; allocate(dt13(klocus))
1192 !
1193 !------------------- spectral grid data ------------------------
1194 !
1195 if (allocated(q_k)) deallocate (q_k) ; allocate (q_k(nkq))
1196 if (allocated(q_dk)) deallocate (q_dk) ; allocate (q_dk(nkq))
1197 if (allocated(q_kpow)) deallocate (q_kpow); allocate (q_kpow(nkq))
1198 if (allocated(q_f)) deallocate (q_f) ; allocate (q_f(nkq))
1199 if (allocated(q_df)) deallocate (q_df) ; allocate (q_df(nkq))
1200 if (allocated(q_sig)) deallocate (q_sig) ; allocate (q_sig(nkq))
1201 if (allocated(q_dsig)) deallocate (q_dsig); allocate (q_dsig(nkq))
1202 if (allocated(q_cg)) deallocate (q_cg); allocate (q_cg(nkq))
1203 if (allocated(q_a)) deallocate (q_a) ; allocate (q_a(naq))
1204 if (allocated(q_ad)) deallocate (q_ad) ; allocate (q_ad(naq))
1205 !
1206 !
1207 if (allocated(nspec)) deallocate (nspec) ; allocate (nspec(nkq,naq))
1208 if (allocated(a)) deallocate (a) ; allocate (a(nkq,naq))
1209 if (allocated(nk1d)) deallocate (nk1d) ; allocate (nk1d(nkq))
1210 !! if (allocated(qnl)) deallocate (qnl) ; allocate (qnl(nkq,naq))
1211 !
1212 if(iq_log >=1) then
1213  write(luq_log,'(a)') 'Q_ALLOCATE: size of arrays'
1214  write(luq_log,'(a,i4)') 'Q_ALLOCATE: mkq :',mkq
1215  write(luq_log,'(a,i4)') 'Q_ALLOCATE: maq :',maq
1216  write(luq_log,'(a,i4)') 'Q_ALLOCATE: nkq :',nkq
1217  write(luq_log,'(a,i4)') 'Q_ALLOCATE: naq :',naq
1218  write(luq_log,'(a,i4)') 'Q_ALLOCATE: mlocus:',mlocus
1219  write(luq_log,'(a,i4)') 'Q_ALLOCATE: klocus:',klocus
1220 end if
1221 !
1222 call q_stack('-q_allocate')
1223 !
1224 return
1225 end subroutine
1226 !------------------------------------------------------------------------------
1227 
1235 
1236 subroutine q_chkconfig
1237 !------------------------------------------------------------------------------
1238 !
1239 ! +-------+ ALKYON Hydraulic Consultancy & Research
1240 ! | | Gerbrant van Vledder
1241 ! | +---+
1242 ! | | +---+ Last update: 12 June 2003
1243 ! +---+ | | Release: 5.0
1244 ! +---+
1245 !
1246 !
1247 ! 0. Update history
1248 !
1249 ! 28/12/1999 Initial version
1250 ! 05/10/1999 Test for iq_filt included
1251 ! 01/11/1999 Implicit none introduced
1252 ! 12/11/1999 Update of tests
1253 ! 22/11/1999 Update of tests
1254 ! 28/12/1999 Check of IQ_LOCUS added
1255 ! 02/01/2000 IQ_START removed
1256 ! 05/01/2000 IQ_INT added
1257 ! 08/08/2002 Upgrade to release 4
1258 ! 22/08/2002 Extra checks included
1259 ! 04/06/2003 parameter IQ_INT renamed IQ_INTEG
1260 ! Switches IQ_GAULEG, IQ_LUMP added
1261 ! 11/06/2003 Name changed from Q_CHKCFG to Q_CHKCONFIG
1262 ! Parameter iq_space removed
1263 ! 12/06/2003 Extra check on IMOD, KLOCUS and NLOCUS0
1264 ! 16/06/2003 Switch IQ_SYM added
1265 !
1266 ! 1. Purpose:
1267 !
1268 ! Check configuration for computation of non-linear transfer
1269 !
1270 ! 2. Method
1271 !
1272 ! Check of each parameter setting
1273 !
1274 ! 3. Parameters used
1275 !
1276 ! 4. Error messages
1277 !
1278 ! 5. Called by:
1279 !
1280 ! XNL_INIT
1281 !
1282 ! 6. Subroutines used:
1283 !
1284 ! Q_ERROR
1285 !
1286 ! 7. Remarkds
1287 !
1288 ! 8. Structure
1289 !
1290 ! 9. Switches
1291 !
1292 ! /S enable subroutine tracing
1293 !
1294 ! 10. Source code
1295 !-------------------------------------------------------------------------------------------
1296 ! do not use m_xnldata
1297 implicit none
1298 !
1299 call q_stack('+Q_CHKCONFIG')
1300 !
1301 if(qf_tail > -1.) call q_error('e','CONFIG','Incorrect power of spectral: qf_tail')
1302 !
1303 if(iq_cple < 1 .or. iq_cple > 3) &
1304 & call q_error('e','CONFIG','Invalid option for coupling coefficient iq_cple')
1305 !
1306 if(iq_compact < 0 .or. iq_compact > 1) &
1307 & call q_error('e','CONFIG','iq_compact /= 0,1')
1308 !
1309 if(iq_filt < 0 .or. iq_filt > 1) &
1310 & call q_error('e','CONFIG','iq_filt /= 0,1')
1311 !
1312 if(iq_gauleg < 0) &
1313 & call q_error('e','CONFIG','iq_gauleg <0')
1314 !
1315 if(iq_geom < 0 .or. iq_geom > 1) &
1316 & call q_error('e','CONFIG','iq_geom /= 0,1')
1317 !
1318 if(iq_interp < 1 .or. iq_interp > 2) &
1319 & call q_error('e','CONFIG','iq_interp /= 1,2')
1320 !
1321 if(iq_disp > 1 .and. iq_geom ==1) then
1322  call q_error('e','CONFIG','Invalid combination of iq_disp & iq_geom')
1323  write(luq_err,'(1x,a,2i4)') 'iq_disp iq_geom:',iq_disp,iq_geom
1324 end if
1325 !
1326 if(iq_lump>0 .and. iq_gauleg>0) then
1327  call q_error('e','CONFIG','Lumping and Gauss-Legendre interpolation not together')
1328  write(luq_err,'(1x,a,2i4)') 'iq_lump iq_gauleg:',iq_lump,iq_gauleg
1329 end if
1330 !
1331 if(iq_dscale < 0 .or. iq_dscale > 1) &
1332 & call q_error('e','CONFIG','Incorrect value for IQ_DSCALE, (0,1)')
1333 !
1334 if(iq_disp < 1 .or. iq_disp >2 ) &
1335 & call q_error('e','CONFIG','Incorrect value for IQ_DISP [DISP],(1,2) ')
1336 !
1337 if(iq_grid <1 .or. iq_grid > 3) &
1338 & call q_error('e','CONFIG','Incorrect value for IQ_GRID, (1,2,3)')
1339 !
1340 if(iq_integ < 0 .or. iq_make > 3) then
1341  call q_error('e','CONFIG','Invalid value for iq_integ')
1342  write(luq_err,'(1x,a,2i4)') 'iq_integ:',iq_integ
1343 end if
1344 !
1345 if(iq_log < 0) &
1346 & call q_error('e','CONFIG','Incorrect value for IQ_LOG, (>=0) ')
1347 !
1348 if(iq_locus < 0 .or. iq_locus > 3) &
1349 & call q_error('e','CONFIG','Incorrect specifier for locus method')
1350 !
1351 if(iq_lump<0) then
1352  call q_error('e','CONFIG','Invalid value for iq_lump')
1353  write(luq_err,'(1x,a,2i4)') 'iq_lump:',iq_lump
1354 end if
1355 !
1356 if(iq_make < 1 .or. iq_make > 3) then
1357  call q_error('e','CONFIG','Invalid value for iq_make')
1358  write(luq_err,'(1x,a,2i4)') 'iq_make:',iq_make
1359 end if
1360 !
1361 if(iq_mod < 0 .or. iq_mod > 1) &
1362 & call q_error('e','CONFIG','Incorrect value for IQ_MOD [MOD] (0,1)')
1363 !
1364 if(iq_mod==0 .and. klocus<nlocus0) then
1365  call q_error('e','CONFIG','klocus < nlocus0')
1366  write(luq_err,'(a)') 'Lumping or Gauss-Integration enabled when IMOD=0'
1367 end if
1368 !
1369 if(iq_prt < 0) &
1370 & call q_error('e','CONFIG','Incorrect value for IQ_PRT, (>=0) ')
1371 !
1372 !!if(iq_search==1 .and. iq_type/=3) &
1373 !!& call q_error('w','CONFIG','search option only active when IQUAD=3')
1374 !
1375 if(iq_sym <0 .or. iq_sym > 1) &
1376  call q_error('e','CONFIG','Incorrect value of IQ_SYM /=[0,1]')
1377 !
1378 if(iq_test < 0) &
1379 & call q_error('e','CONFIG','Incorrect value for IQ_TEST, (>=0) ')
1380 !
1381 if(iq_trf < 0 .or. iq_trf > 3) &
1382 & call q_error('e','CONFIG','Incorrect value for IQ_TRF ')
1383 !
1384 ! parameter settings ------------------------------------------------
1385 !
1386 if(fqmin < 0) &
1387 & call q_error('e','CONFIG','Incorrect value for FQMIN')
1388 !
1389 if(fqmax < 0) &
1390 & call q_error('e','CONFIG','Incorrect value for FQMAX')
1391 !
1392 if(fqmax <= fqmin) &
1393 & call q_error('e','CONFIG','fmax <= fmin')
1394 !
1395 if(nkq < 1) &
1396 & call q_error('e','CONFIG','Number of wave numbers NKQ < 0')
1397 !
1398 if(naq < 1) &
1399 & call q_error('e','CONFIG','Number of directions NKQ < 0')
1400 !
1401 if(nlocus0 < 6) &
1402 & call q_error('e','CONFIG','Preferred number of points on locus NLOCUS0 < 6')
1403 !
1404 if(q_sector < 40. .or. q_sector > 180.) &
1405 & call q_error('e','CONFIG','Sector too small (<40) or too large (>180)')
1406 !
1407 call q_stack('-Q_CHKCONFIG')
1408 !
1409 return
1410 end subroutine
1411 !------------------------------------------------------------------------------
1412 
1433 
1434 subroutine q_chkcons(xnl,nk,ndir,sum_e,sum_a,sum_mx,sum_my)
1435 !------------------------------------------------------------------------------
1436 !
1437 ! +-------+ ALKYON Hydraulic Consultancy & Research
1438 ! | | Gerbrant van Vledder
1439 ! | +---+
1440 ! | | +---+ Last Update: 13 Aug. 2002
1441 ! +---+ | | Release: 4.0
1442 ! +---+
1443 !
1444 ! do not use m_xnldata
1445 implicit none
1446 !
1447 ! 0. Update history
1448 !
1449 ! 29/07/1999 Initial version
1450 ! 01/11/1999 Implicit none introduced
1451 ! 08/12/1999 Bug fixed in definition os momentum sum
1452 ! 13/08/2002 Upgrade to release 4.0
1453 !
1454 ! 1. Purpose:
1455 !
1456 ! Check conservation laws of non-linear transfer
1457 !
1458 ! 2. Method
1459 !
1460 ! The following conservation laws should be fulfilled:
1461 !
1462 ! Wave Energy SUME=0
1463 ! Wave Action SUMA=0
1464 ! Momentum vector SUMMX,SUMMY=0
1465 !
1466 !
1467 ! 3. Parameter list:
1468 !
1469 !Type I/O Name Description
1470 !
1471 integer, intent(in) :: nk ! number of wave numbers
1472 integer, intent(in) :: ndir ! number of directions
1473 real, intent(in) :: xnl(nk,ndir) ! transfer rate
1474 real, intent(out) :: sum_e ! sum of wave energy
1475 real, intent(out) :: sum_a ! sum of wave action
1476 real, intent(out) :: sum_mx ! sum of momentum in x-direction
1477 real, intent(out) :: sum_my ! sum of momentum in y-direction
1478 !
1479 ! 4. Error messages
1480 !
1481 ! 5. Called by:
1482 !
1483 ! XNL_MAIN
1484 !
1485 ! 6. Subroutines used
1486 !
1487 ! Q_STACK
1488 !
1489 ! 7. Remarks
1490 !
1491 ! 8. Structure
1492 !
1493 ! 9. Switches
1494 !
1495 ! 10. Source code
1496 !------------------------------------------------------------------------------
1497 ! Local variables
1498 !
1499 real aa ! action density
1500 real ee ! energy density
1501 real kk ! wave number
1502 real momx ! momentum in x-direction
1503 real momy ! momentum in y-direction
1504 real qq ! bin size
1505 !
1506 integer ia ! counter over directions
1507 integer ik ! counter over wave numbers
1508 !
1509 !------------------------------------------------------------------------------
1510 !
1511 call q_stack('+q_chklaw')
1512 !
1513 ! initialize summations
1514 !
1515 sum_a = 0.
1516 sum_e = 0.
1517 sum_mx = 0.
1518 sum_my = 0.
1519 !
1520 do ik=1,nkq
1521  qq = q_delta*q_dk(ik)
1522  kk = q_k(ik)
1523 !
1524  do ia = 1,naq
1525  aa = xnl(ik,ia)
1526  ee = aa*q_sig(ik)
1527  momx = aa*kk*cos(q_a(ia))
1528  momy = aa*kk*sin(q_a(ia))
1529 !
1530  sum_a = sum_a + aa*qq
1531  sum_e = sum_e + ee*qq
1532  sum_mx = sum_mx + momx*qq
1533  sum_my = sum_my + momy*qq
1534  end do
1535 end do
1536 !
1537 call q_stack('-q_chklaw')
1538 !
1539 return
1540 end subroutine
1541 !------------------------------------------------------------------------------
1542 
1572 
1573 subroutine q_chkres(k1x,k1y,k2x,k2y,k3x,k3y,k4x,k4y,dep,sum_kx,sum_ky,sum_w)
1574 !------------------------------------------------------------------------------
1575 !
1576 ! +-------+ ALKYON Hydraulic Consultancy & Research
1577 ! | | Gerbrant van Vledder
1578 ! | +---+
1579 ! | | +---+ Last update: 9 Aug. 2002
1580 ! +---+ | | Release: 4.0
1581 ! +---+
1582 !
1583 implicit none
1584 !
1585 ! 0. Update history
1586 !
1587 ! 16/02/2001 Initial version
1588 ! 01/11/2001 Implicit none introduced
1589 ! 09/08/2002 Upgrade to release 4.0
1590 !
1591 ! 1. Purpose:
1592 !
1593 ! Check resonance conditions of 4 interacting wave numbers
1594 ! for a given water depth and dispersion relation
1595 !
1596 ! 2. Method
1597 !
1598 ! The sum of wave number vectors and associated radian frequencies
1599 ! are computed:
1600 !
1601 ! k1 + k2 - (k3 + k4)
1602 ! w1 + w2 - (w3 + w4)
1603 !
1604 ! in which w_i = g k_i tanh(k_i d)
1605 !
1606 ! 3. Parameter list:
1607 !
1608 ! Type I/O Name Description
1609 !----------------------------------------------------------------------
1610 real, intent(in) :: k1x ! x-component of wave number vector k1
1611 real, intent(in) :: k1y ! y-component of wave number vector k1
1612 real, intent(in) :: k2x ! x-component of wave number vector k2
1613 real, intent(in) :: k2y ! y-component of wave number vector k2
1614 real, intent(in) :: k3x ! x-component of wave number vector k3
1615 real, intent(in) :: k3y ! y-component of wave number vector k3
1616 real, intent(in) :: k4x ! x-component of wave number vector k4
1617 real, intent(in) :: k4y ! y-component of wave number vector k4
1618 real, intent(in) :: dep ! depth in m
1619 real, intent(out) :: sum_kx ! sum of x-components of quadruplet
1620 real, intent(out) :: sum_ky ! sum of y-components of quadruplet
1621 real, intent(out) :: sum_w ! sum of radian frequencies
1622 !
1623 ! 4. Error messages
1624 !
1625 ! 5. Subroutines used
1626 !
1627 ! X_DISPER
1628 !
1629 ! 6. Called by:
1630 !
1631 ! Q_MAKEGRID
1632 !
1633 ! 7. Remarks
1634 !
1635 ! 8. Structure
1636 !
1637 ! 9. Switches
1638 !
1639 ! 10. Source code
1640 !------------------------------------------------------------------------------
1641 ! Local variables
1642 !
1643 real w1,w2,w3,w4 ! radian frequecies of wave numbers
1644 !!real x_disper ! dispersion relation
1645 sum_kx = (k1x + k2x) - (k3x + k4x)
1646 sum_ky = (k1y + k2y) - (k3y + k4y)
1647 !
1648 ! compute radian frequency on the basis of current dispersion relation
1649 !
1650 w1 = x_disper(sqrt(k1x**2 + k1y**2),dep)
1651 w2 = x_disper(sqrt(k2x**2 + k2y**2),dep)
1652 w3 = x_disper(sqrt(k3x**2 + k3y**2),dep)
1653 w4 = x_disper(sqrt(k4x**2 + k4y**2),dep)
1654 !
1655 sum_w = w1 + w2 - (w3 + w4)
1656 !
1657 return
1658 end subroutine q_chkres
1659 
1660 !------------------------------------------------------------------------------
1675 
1676 subroutine q_cmplocus(ka,kb,km,kw,loclen)
1677 !------------------------------------------------------------------------------
1678 !
1679 ! +-------+ ALKYON Hydraulic Consultancy & Research
1680 ! | | Gerbrant van Vledder
1681 ! | +---+
1682 ! | | +---+ Last update: 8 August 2003
1683 ! +---+ | | Release: 5.0
1684 ! +---+
1685 !
1686 ! do not use m_xnldata
1687 use m_constants
1688 use serv_xnl4v5
1689 implicit none
1690 !-------------------------------------------------------------------------------
1691 ! 0. Update history
1692 !
1693 ! Date Description
1694 !
1695 ! 18/11/1999 Initial version
1696 ! 08/12/1999 Tracing of locus updated and Q_TRACE included
1697 ! 22/12/1999 Option Q_POLAR included
1698 ! 05/01/2000 LOCLEN added in interface
1699 ! 09/08/2002 Upgrade to release 4.0
1700 ! 10/09/2002 g added to interface with X_CPLE
1701 ! test output modified
1702 ! 12/06/2003 Call to Z_POYAREA added to check POLAR2
1703 ! 08/08/2003 Check on areas only for loci with k3m/k1m < 100
1704 ! Otherwise machine accuracy plays a role
1705 !
1706 ! 1. Purpose:
1707 !
1708 ! Compute locus function used for the determination of the
1709 ! resonnance condition
1710 !
1711 ! 2. Method
1712 !
1713 ! See ALKYON, 1999
1714 !
1715 ! 3. Parameter list:
1716 !
1717 !Type I/O Name Description
1718 !----------!----------------------------------------------------------------------------
1719 real, intent(out) :: ka,kb ! lowest and highest wave number magnitude of k2-locus
1720 real, intent(out) :: km ! wave number magnitude at mid point
1721 real, intent(out) :: kw ! half width of locus
1722 real, intent(out) :: loclen ! estimated length of locus
1723 !
1724 ! 4. Error messages
1725 !
1726 ! 5. Called by:
1727 !
1728 ! Q_MAKEGRID
1729 !
1730 ! 6. Subroutines used
1731 !
1732 ! z_zero1
1733 !
1734 !
1735 !
1736 ! 7. Remarks
1737 !
1738 ! 8. Structure
1739 !
1740 ! 9. Switches
1741 !
1742 ! 10. Source code
1743 !-------------------------------------------------------------------------------
1744 ! Local variables
1745 !-------------------------------------------------------------------------------
1746 real k1m ! magnitude of wave number k1
1747 real k3m ! magnitude of wave number k3
1748 real pcos,psin ! cosine and sine of normalize angle of P
1749 real klen ! total length of line locus for case w1=w3
1750 !
1751 real kx_beg ! x-component at start point
1752 real ky_beg ! y-component at start point
1753 real kx_end ! x-component at end point
1754 real ky_end ! y-component at end point
1755 !
1756 real dsp,dsm ! distances in plus and minus direction
1757 real sum ! total length of locus
1758 !
1759 real w1,w3 ! radian frequencies of wave numbers k1 and k3
1760 real eps ! local accuracy for determination of roots
1761 real area1 ! area of locus as computed
1762 real area2 ! area of locus as based on LOCPOS and ellipse
1763 real ratio ! maximum ratio between area1 and area2
1764 !
1765 integer ierr ! local error level
1766 integer iloc,jloc ! counters along locus
1767 integer itest ! local test level for test output to unit luqtst
1768 integer ip1 ! index +1
1769 integer im1 ! index -1
1770 integer jj ! counter
1771 !------------------------------------------------------------------------------
1772 ! function declarations
1773 !
1774 !!real x_disper ! dispersion relation
1775 !!real x_cple ! coupling coefficient
1776 !!real x_jacobian ! Jacobian term
1777 !------------------------------------------------------------------------------
1778 call q_stack('+q_cmplocus')
1779 !
1780 ! set initial values
1781 !
1782 eps = 10.*epsilon(1.) ! set accuracy 10 times machine accuracy
1783 itest = iq_test ! assign test level from overall setting
1784 !! itest = 1 ! (re)set local test level
1785 !
1786 ! compute characteristics of configuration
1787 !
1788 px = k1x - k3x
1789 py = k1y - k3y
1790 pmag = sqrt(px**2 + py**2)
1791 xang = atan2(-px,py)
1792 pang = atan2(py,px)
1793 k1m = sqrt(k1x**2 + k1y**2)
1794 k3m = sqrt(k3x**2 + k3y**2)
1795 w1 = x_disper(k1m,q_depth)
1796 w3 = x_disper(k3m,q_depth)
1797 q = w1-w3
1798 !
1799 ! compute cosine and sine of direction of P-vector
1800 ! reverse direction for the case q<0
1801 !
1802 if(q < 0) then
1803  sang = pang+pi
1804  pcos = cos(pang+pi)
1805  psin = sin(pang+pi)
1806 else
1807  sang = pang
1808  pcos = cos(pang)
1809  psin = sin(pang)
1810 end if
1811 !
1812 !
1813 ! first solution along locus: k2 = k3
1814 !
1815 ! check for special case if q = 0
1816 !
1817 if (abs(q) < eps_q) then
1818 !
1820  nlocus1 = nlocus0
1821  ds_loc = s_loc(2)-s_loc(1)
1822  klen = s_loc(nlocus0)
1823  ka = 0.
1824  kb = 0.
1825  km = 0.
1826  kw = 0.
1827  sang = xang
1828 !
1829 else
1830 !------------------------------------------------------------------------------
1831 ! compute characteristics of locus, such as its position in
1832 ! wave number space
1833 !------------------------------------------------------------------------------
1834 !
1835  call q_locpos(ka,kb,km,kw,loclen)
1836  if(iq_err/=0) goto 9999
1837 !
1838 ! compute position of start and end point for tracing
1839 ! the locus
1840 !
1841  kx_beg = ka*pcos
1842  ky_beg = ka*psin
1843  kx_end = kb*pcos
1844  ky_end = kb*psin
1845 !
1846 ! compute position of locus using polar method
1847 ! see Van Vledder (2000)
1848 !
1849 !% call q_polar(ka,kb,kx_beg,ky_beg,kx_end,ky_end,loclen,ierr)
1850  call q_polar2(ka,kb,kx_beg,ky_beg,kx_end,ky_end,loclen,ierr)
1851 !
1852 ! check area of locus by a simple test (added 12 June 2003)
1853 !
1854  call z_polyarea(x2_loc,y2_loc,nlocus1,area1)
1855  area2 = pi*(kb-ka)*0.5*kw
1856  ratio = max(area1/area2,area2/area1)
1857 !
1858 !
1859  if(ratio>1.5 .and. k3m/k1m < 100.) then
1860  call q_error('e','LOCUS','Severe problem in POLAR2')
1861  write(luq_err,'(a)') 'Q_CMPLOCUS: ratio > 1.5'
1862 !
1863  goto 9999
1864  end if
1865 !
1866 ! 01/10/2001
1867 ! compute position of k4 locus by a simple translation
1868 !
1869  do iloc=1,nlocus1
1870  x4_loc(iloc) = x2_loc(iloc) + px
1871  y4_loc(iloc) = y2_loc(iloc) + py
1872  end do
1873 !
1874 end if
1875 !
1876 if (iq_test >=2) write(luq_tst,'(1x,a,4f12.5,i4)')&
1877 & 'Q_CMPLOCUS: k1x/y k3x/y nlocus:',k1x,k1y,k3x,k3y,nlocus1
1878 !----------------------------------------------------------------------------------
1879 ! compute characteristics around locus
1880 !----------------------------------------------------------------------------------
1881 !
1882 s_loc(1) = 0.
1883 sum = 0
1884 !
1885 do iloc=1,nlocus1
1886 !
1887 ! compute step sizes
1888 !
1889  if (abs(q) < eps_q) then
1890 !
1891 ! for this case the sum of ds_loc is unequal to s_loc(nlocus1)
1892 !
1893  sum = s_loc(nlocus1)
1894  else
1895 !
1896 ! compute indices of previous and next index on locus
1897 !
1898  ip1 = iloc+1
1899  if (ip1 > nlocus1) ip1 = 1
1900  im1 = iloc-1
1901  if (im1 < 1) im1 = nlocus1
1902 !
1903  dsp = sqrt((x2_loc(iloc)-x2_loc(ip1))**2 + (y2_loc(iloc)-y2_loc(ip1))**2)
1904  dsm = sqrt((x2_loc(iloc)-x2_loc(im1))**2 + (y2_loc(iloc)-y2_loc(im1))**2)
1905  if(iloc < nlocus1) s_loc(iloc + 1) = s_loc(iloc) + dsp
1906  ds_loc(iloc) = 0.5*(dsp + dsm)
1907  sum = sum+ds_loc(iloc)
1908  end if
1909 !
1910 ! compute gradient/Jacobian terms along locus
1911 !
1912  jac_loc(iloc) = x_jacobian(x2_loc(iloc),y2_loc(iloc),x4_loc(iloc),y4_loc(iloc))
1913 !
1914 ! compute coupling coefficients along locus
1915 !
1916  k2x = x2_loc(iloc)
1917  k2y = y2_loc(iloc)
1918  k4x = x4_loc(iloc)
1919  k4y = y4_loc(iloc)
1920 !
1922 !
1923 end do
1924 !
1925 !
1926 9999 continue
1927 !
1928 call q_stack('-q_cmplocus')
1929 !
1930 return
1931 end subroutine
1932 !------------------------------------------------------------------------------
1933 
1966 
1967 subroutine q_ctrgrid(itask,igrid)
1968 !------------------------------------------------------------------------------
1969 !
1970 ! +-------+ ALKYON Hydraulic Consultancy & Research
1971 ! | | Gerbrant van Vledder
1972 ! | +---+
1973 ! | | +---+ Last update: 13 Sept. 2003
1974 ! +---+ | | Release: 5.03
1975 ! +---+
1976 !
1977 ! do not use m_xnldata
1978 use m_fileio
1979 implicit none
1980 !------------------------------------------------------------------------------
1981 ! 0. Update history
1982 !
1983 ! Version Date Modification
1984 !
1985 ! 29/07/1999 Initial version
1986 ! 11/10/1999 Error messages via module
1987 ! 12/10/1999 File I/O of interaction grid files added, and consistency check
1988 ! 25/10/1999 Contents of q_header extended with iq_grid & iq_start & nlocus0
1989 ! 27/10/1999 Close statement after reading BQF file
1990 ! 01/11/1999 Close statments after call of Q_GRID
1991 ! 03/11/1999 Parameter IQ_MAKE included
1992 ! 22/11/1999 Use of z_fileio modified, use parameter IUERR if an attempt
1993 ! to open a non-existing file was made
1994 ! 30/11/1999 Extra messages to logging file when file are closed
1995 ! 03/01/2000 IQ_START replaced by IQ_LOCUS
1996 ! 12/01/2001 Output parameter IGRID added
1997 ! igrid=0: a proper grid exists or has been made, and will be read
1998 ! =1: grid file does not exist
1999 ! =2: grid file exists, but it is incorrect
2000 ! 8/08/2002 Upgrade to release 4.0
2001 ! 15/08/2002 Bug fixed ininitialisation of igrid
2002 ! 19/08/2002 header extended with parameter IQ_INTERP
2003 ! 20/08/2002 wave number array replaced by sigma array in grid file
2004 ! 22/08/2002 Extra i/o check when reading BQF file
2005 ! 23/08/2002 retrieve number of point on locus from BQF file
2006 ! 09/09/2002 aqfile and bqfile 5 units for depth
2007 ! 10/09/2002 new algorithm for coding depth
2008 ! Test added to avoid rereading of last read/generated BQF file
2009 ! 08/10/2002 Output to test file made conditional
2010 ! 05/09/2003 Water depth for creating and testing BQF file DSTEP dependend
2011 ! 09/09/2003 Bug fixed in assigning IGRID=0 when BQF still in memory
2012 ! 13/09/2003 When BFQ incorrupt, it is deleted and a new one is created
2013 ! Bug fixed in setting of s_depth when iq_disp==1
2014 !
2015 ! 1. Purpose:
2016 !
2017 ! Control of interaction grid administration
2018 !
2019 ! 2. Method
2020 !
2021 ! 3. Parameters used
2022 !
2023 integer, intent(in) :: itask
2024 integer, intent(out) :: igrid
2025 !
2026 ! 4. Error messages
2027 !
2028 ! 5. Called by:
2029 !
2030 ! XNL_INIT
2031 ! Q_SEARCHGRID
2032 !
2033 ! 6. Subroutines used
2034 !
2035 ! Q_STACK
2036 ! Q_ERROR
2037 ! Q_MAKEGRID
2038 !
2039 ! 7. Remarks
2040 !
2041 ! The generation of the database file depend on the control varaible of IQ_MAKE
2042 ! if IQ_MAKE==1, make a grid when needed
2043 ! 2, always make grid
2044 ! 3, make a grid and stop, useful for test purposes
2045 !
2046 ! The maximum number of points on the locus, as stored in the BQF file
2047 ! is read from the header and stored in the variable NLOCUS
2048 !
2049 ! 8. Structure
2050 !
2051 ! Make header of grid file
2052 ! Construct name of grid file
2053 ! Check existence of grid file
2054 ! if grid file exists
2055 ! read header
2056 ! check header
2057 ! read first data block
2058 ! check first data block
2059 ! - directions
2060 ! - wave numbers
2061 ! - depth
2062 ! set status of grid file
2063 ! else
2064 ! set status of grid file
2065 ! end if
2066 !
2067 ! set status of generating/reading grid file
2068 !
2069 ! if make new grid
2070 ! compute grid parameters
2071 ! write grid parameters to file
2072 ! else
2073 ! read grid parameters from file
2074 ! end if
2075 !
2076 !
2077 ! 9. Switches
2078 !
2079 ! 10. Source code
2080 !-------------------------------------------------------------------------------
2081 ! Local variables
2082 !
2083 integer iaz,ikz,jaz,jkz ! counters for checking header of BQF file
2084 integer iz_geom,iz_disp,iz_cple ! values as read in BQF file
2085 integer naz ! number of directions in BQF file
2086 integer nkz ! number of wave numbers in BQF file
2087 integer idep,jdep ! coding for depth in BQF file
2088 !
2089 logical lbqf ! flag for existence of BQF file
2090 real s_depth ! (stepped) depth
2091 real q_depth_saved ! save input water depth, needed after call to Q_MAKEGRID
2092 real z_depth ! water depth in BQF file
2093 real, allocatable :: z_ad(:),z_sig(:) ! directions and radian frequencies of grid in BQF file
2094 integer ierr,iuerr ! error variables
2095 !------------------------------------------------------------------------------
2096 !
2097 call q_stack('+q_ctrgrid')
2098 !
2099 ! echo input arguments
2100 !
2101 !
2102 q_depth_saved = q_depth
2103 !
2104 ! generate header of BQF file
2105 !
2106 q_header = '000000000000000000000'
2107 ! 123456789012345678901
2108 ! 1 2
2109 write(q_header,'(3i3.3,6i2.2)') naq,nkq,nlocus0,&
2111 !
2112 if(iq_prt>=2) then
2113  write(luq_prt,'(2a)') 'Q_CTRGRID: header info:',trim(q_header)
2114  write(luq_prt,'(a,3i5)') 'Q_CTRGRID: naq nkq nlocus0:',naq,nkq,nlocus0
2115  write(luq_prt,'(a,3i3)') 'Q_CTRGRID: iq_grid,iq_geom,iq_disp:',iq_grid,iq_geom,iq_disp
2116  write(luq_prt,'(a,3i3)') 'Q_CTRGRID: iq_cple,iq_locus,iq_interp:',iq_cple,iq_locus,iq_interp
2117 end if
2118 !
2119 !------------------------------------------------------------------------------
2120 ! construct name of grid file
2121 !
2122 if(iq_disp==1) then
2123  bqname = 'quad99999.bqf'
2124  s_depth = q_maxdepth
2125 !
2126 elseif(iq_disp==2) then
2127 !
2128 !---------------------------------------------------------------------------------------------
2129 ! generate code for actual depth
2130 !---------------------------------------------------------------------------------------------
2131  idep = int(q_depth/q_dstep+0.5)
2132  jdep = idep*int(10.*q_dstep)
2133  jdep = max(1,jdep)
2134  jdep = min(99999,jdep)
2135 !
2136  s_depth = real(idep)*q_dstep
2137 !
2138 !
2139  bqname = 'quad00000.bqf'
2140  write(bqname(5:9),'(i5.5)') min(int(q_maxdepth*10),jdep)
2141 !
2142 else
2143  call q_error('e','DISPER','Incorrect value for IQ_DISP')
2144  write(luq_err,'(a,i4)') 'IQ_DISP=',iq_disp
2145  goto 9999
2146 end if
2147 !
2148 !
2149 !-------------------------------------------------------------------------------------------
2150 ! Compare LASTQUADFILE with bqname
2151 ! if equal skip reading of BQF file, including checks of header
2152 !-------------------------------------------------------------------------------------------
2153 !
2154 if(lastquadfile==bqname) then
2155  if(iq_screen>0) write(iscreen,'(2a)') 'Q_CTRGRID: Rereading of bqfile skipped: ',lastquadfile
2156  igrid = 0
2157  goto 9999
2158 end if
2159 !-------------------------------------------------------------------------------------------
2160 if(iq_prt >= 2) then
2161  write(luq_prt,'(2a)') 'Q_CTRGRID: Header line of grid file:',trim(q_header)
2162  write(luq_prt,'(2a)') 'Q_CTRGRID: Name of BINARY grid file:',trim(bqname)
2163 end if
2164 !------------------------------------------------------------------------------
2165 !
2166 ! check if binary data file exists
2167 !
2168 call z_fileio(bqname,'OU',iufind,luq_bqf,iuerr) ! binary quadruplet file
2169 !
2170 if(iq_prt >= 2) write(luq_prt,'(2a,2x,2i4)') &
2171 & 'Q_CTRGRID: bqname:',trim(bqname),luq_bqf,iuerr
2172 !
2173 if(itask==2 .and. iq_make==2) luq_bqf=-1
2174 !
2175 ! if the file exists,
2176 ! read header information
2177 ! check header of file
2178 ! end
2179 !
2180 ! If header is incorrect, set flag IQ_GRID to TRUE for generating new grid
2181 !
2182 if(luq_bqf > 0 .and. iuerr ==0) then
2183  if(iq_prt >= 2) then
2184  write(luq_prt,'(2a)') 'Q_CTRGRID: Binary grid file detected: ',trim(bqname)
2185  write(luq_prt,'(a,i4)') 'Q_CTRGRID: Connected to unit:',luq_bqf
2186  end if
2187 !
2188 !
2189 ! grid file exists, unless proven otherwise
2190 !---------------------------------------------------------------------------------
2191 !
2192  lq_grid = .false.
2193  igrid = 0
2194  read(luq_bqf,iostat=ierr) r_header
2195  if(ierr/=0) then
2196  call q_error('w','READBQF','Read error for header in BQF file')
2197  write(luq_err,'(a)') 'BQF file deleted'
2198  call z_fileio(bqname,'DU',iufind,luq_bqf,iuerr) ! binary quadruplet file
2199  igrid = 3
2200  lq_grid = .true.
2201  else
2202  read(r_header,'(6x,i3)') nlocus
2203 !
2204  end if
2205 !-----------------------------------------------------------------------------
2206 ! check header of grid file
2207 !-----------------------------------------------------------------------------
2208 !
2209  if(trim(r_header)/=trim(q_header).and. .not.lq_grid) then
2210  lq_grid = .true.
2211  igrid = 2
2212  if(iq_prt >=2) then
2213  write(luq_prt,'(a,1x,a)') &
2214 & 'Q_CTRGRID: Header in binary quad file :',trim(r_header)
2215  write(luq_prt,'(a,1x,a)') &
2216 & 'Q_CTRGRID: Expected header of binary quad file:',trim(q_header)
2217  write(luq_prt,'(a)') 'Q_CTRGRID: The file headers disagree'
2218  write(luq_prt,'(a)') 'Q_CTRGRID: A new grid will be generated'
2219  end if
2220  end if
2221 !------------------------------------------------------------------------------
2222 ! check other parts of binary grid file
2223 !
2224  if(.not.lq_grid) then
2225  read(luq_bqf) naz,nkz
2226  allocate (z_sig(nkz),z_ad(naz))
2227  read(luq_bqf) z_sig
2228  read(luq_bqf) z_ad
2229  read(luq_bqf) iz_geom,iz_disp,iz_cple
2230  read(luq_bqf) z_depth
2231 !
2232  if(iq_prt >=2) then
2233  write(luq_prt,'(a)') 'Q_CTRGRID: Contents of BQF file'
2234  write(luq_prt,'(2a)') 'Q_CTRGRID: Header:',trim(r_header)
2235  write(luq_prt,'(a,i4)') 'Q_CTRGRID: NK:',nkz
2236  write(luq_prt,'(a,i4)') 'Q_CTRGRID: NA:',naz
2237  end if
2238  end if
2239 !---------------------------------------------------------------------------------------
2240 ! check spectral interaction grid and depth for consistency
2241 !---------------------------------------------------------------------------------------
2242  if(.not. lq_grid) then
2243 az: do iaz = 1,naz
2244  if(abs(q_ad(iaz)-z_ad(iaz)) > 0.01) then
2245  write(luq_prt,'(a)') 'Q_CTRGRID: Directions do not agree'
2246  do jaz=1,naz
2247  write(luq_prt,'(1x,a,i4,2f10.3)') 'iaz q_ad z_ad:',jaz,q_ad(jaz),z_ad(jaz)
2248  end do
2249  lq_grid = .true.
2250  igrid = 2
2251  exit az
2252  end if
2253  end do az
2254  end if
2255 !
2256  if(.not. lq_grid) then
2257 ak: do ikz = 1,nkz
2258  if(abs(q_sig(ikz)-z_sig(ikz)) > 0.01) then
2259  write(luq_prt,'(a)') 'Q_CTRGRID: Wave numbers do not agree'
2260  do jkz=1,nkz
2261  write(luq_prt,'(1x,a,i4,2f10.3)') 'ikz q_k z_sig:',jkz,q_sig(jkz),z_sig(jkz)
2262  end do
2263  lq_grid = .true.
2264  igrid = 2
2265  exit ak
2266  end if
2267  end do ak
2268  end if
2269 !
2270 ! compare water depths
2271 !
2272  if(abs(z_depth-s_depth) > 0.09 .and. iq_disp > 1 .and. .not. lq_grid) then
2273  write(luq_prt,'(a)') 'Q_CTRGRID: Water depths do not agree'
2274  write(luq_prt,'(a,2f16.2)') 'Q_CTRGRID: q_depth z_depth:',q_depth,z_depth
2275  lq_grid = .true.
2276  igrid = 2
2277  end if
2278 !
2279  if(lq_grid) then
2280  close(luq_bqf)
2281  if(iq_log >= 1) write(luq_log,'(a)') 'Q_CTRGRID: Existing BQF-file invalid, it will be closed'
2282  end if
2283 !
2284 else
2285  lq_grid = .true.
2286  igrid = 1
2287 end if
2288 !------------------------------------------------------------------------------
2289 if(itask==1) then
2290  if(luq_bqf>0) call z_fclose(luq_bqf)
2291  goto 9999
2292 end if
2293 !-----------------------------------------------------------------------------
2294 ! if lq_grid==true a new grid has to be generated
2295 ! if not, read the grid information into memory
2296 ! or iq_make==2 always make an interaction grid
2297 ! or iq_make==3 as 2, plus stop after making grid
2298 !
2299 if(lq_grid .or. iq_make==2 .or. iq_make==3) then
2300 !
2301  if(luq_bqf>0) call z_fclose(luq_bqf)
2302  call z_fileio(bqname,'UU',iufind,luq_bqf,iuerr) ! binary quadruplet file
2303 !
2304  if(iq_log >= 1) then
2305  write(luq_log,*)
2306  write(luq_log,'(a)') 'Q_CTRGRID: New grid will be generated'
2307  write(luq_log,'(a,a)') 'Q_CTRGRID: Name of BQF file:',trim(bqname)
2308  write(luq_log,'(a,i4)') 'Q_CTRGRID: '//trim(bqname)//' connected to :',luq_bqf
2309  end if
2310 !
2311  if(iq_screen >= 1) write(iscreen,'(2a)') &
2312 & 'Q_CTRGRID: Generating wave number grid for quadruplet interactions: ',trim(bqname)
2313 !
2314  q_depth = s_depth
2315  call q_makegrid
2316  q_depth = q_depth_saved
2317 !
2318  if(iq_err /=0) then
2319  lastquadfile = 'quad_err_.bqf'
2320  goto 9999
2321  end if
2322 !
2323  igrid = 0
2324 !
2325  close(luq_bqf)
2326 !
2327  if(iq_log >=1) then
2328  write(luq_log,'(a,i4)') 'Q_CTRGRID: '//trim(bqname)//' disconnected from:',luq_bqf
2329  end if
2330 !
2331  if(iq_screen >=1) write(iscreen,'(a)') 'Q_CTRGRID: Grid generation completed succesfully'
2332 !----------------------------------------------------------------------------------------
2333 !
2334 ! check of header and spectral grid succesfull
2335 ! such that data can be read from BQF file
2336 !----------------------------------------------------------------------------------------
2337 !
2338 else
2339  if(iq_screen >= 1) write(iscreen,'(2a)') 'Q_CTRGRID: Reading existing grid: ',trim(bqname)
2340  if(iq_prt >= 1) write(luq_prt,'(2a)') 'Q_CTRGRID: Existing grid will be read:',trim(bqname)
2341  if(iq_log >= 1) write(luq_log,'(2a)') 'Q_CTRGRID: Existing grid will be read:',trim(bqname)
2342 !
2343  read(luq_bqf) quad_nloc
2344  read(luq_bqf) quad_ik2
2345  read(luq_bqf) quad_ia2
2346  read(luq_bqf) quad_ik4
2347  read(luq_bqf) quad_ia4
2348  read(luq_bqf) quad_w1k2
2349  read(luq_bqf) quad_w2k2
2350  read(luq_bqf) quad_w3k2
2351  read(luq_bqf) quad_w4k2
2352  read(luq_bqf) quad_w1k4
2353  read(luq_bqf) quad_w2k4
2354  read(luq_bqf) quad_w3k4
2355  read(luq_bqf) quad_w4k4
2356  read(luq_bqf) quad_zz
2357 !
2359 !
2360  close(luq_bqf)
2361 !
2362 
2363 end if
2364 !
2365 9999 continue
2366 !
2367 if (allocated(z_ad)) deallocate(z_ad,z_sig)
2368 !
2369 !
2370 call q_stack('-q_ctrgrid')
2371 !
2372 return
2373 end subroutine
2374 !------------------------------------------------------------------------------
2395 
2396 subroutine q_dscale(n,sigma,angle,nsig,nang,depth,grav,q_dfac)
2397 !------------------------------------------------------------------------------
2398 !
2399 ! +-------+ ALKYON Hydraulic Consultancy & Research
2400 ! | | Gerbrant van Vledder
2401 ! | +---+
2402 ! | | +---+ Last update: 23 Aug. 2002
2403 ! +---+ | | Release: 5.0
2404 ! +---+
2405 !
2406 use serv_xnl4v5
2407 implicit none
2408 !
2409 ! 0. Update history
2410 !
2411 ! Date Modification
2412 !
2413 ! 25/02/1999 Initial version
2414 ! 2/12/1999 Result modified if total energy <= 0
2415 ! Cosmetic changes
2416 ! 13/08/2002 Upgrade to release 4.0
2417 ! 23/09/2002 Mean wave number multiplied by 0.75
2418 !
2419 ! 1. Purpose:
2420 !
2421 ! Compute scaling factor for nonlinear transfer in finite depth
2422 !
2423 ! 2. Method
2424 !
2425 ! Compute mean wave number km
2426 !
2427 ! Compute scale factor based on parameterized function of (km*d)
2428 ! according to Herterich and Hasselmann
2429 ! and parameterisation from WAM model
2430 !
2431 !
2432 ! 3. Interface parameter list:
2433 !
2434 ! Type I/O Name Description
2435 !-------------------------------------------------------------------------
2436 integer, intent (in) :: nsig ! Number of sigma-values
2437 integer, intent (in) :: nang ! Number of directions
2438 real, intent(in) :: n(nsig,nang) ! N(nsig,nang) Action density
2439 real, intent(in) :: sigma(nsig) ! sigma values
2440 real, intent(in) :: angle(nang) ! directions in (radians)
2441 real, intent(in) :: depth ! Depth (m)
2442 real, intent(in) :: grav ! Gravitational acceleration
2443 real, intent(out) :: q_dfac ! scale factor
2444 !
2445 ! 4. Error messages
2446 !
2447 ! 5. Called by:
2448 !
2449 ! XNL_MAIN
2450 !
2451 ! 6. Subroutines used
2452 !
2453 ! x_wnumb
2454 ! z_steps
2455 ! q_stack
2456 !
2457 ! 7. Remarks
2458 !
2459 ! 8. Structure
2460 !
2461 ! 9. Switches
2462 !
2463 ! 10. Source code
2464 !------------------------------------------------------------------------------
2465 ! local variables
2466 !
2467 real w ! radian frequency
2468 real kk ! local wave number
2469 real sqkk ! square root of local wave number
2470 real dnn ! summation quantity
2471 real kms ! mean wave number
2472 real kd ! depth*mean wave number product
2473 real sum0 ! summation variable for total energy
2474 real sumk ! summation variable for wave number
2475 real delta ! directional step, in radians
2476 !
2477 integer isig ! counter over sigma loop
2478 integer iang ! counter over direction loop
2479 !
2480 ! functions
2481 !!!real z_wnumb ! function to compute wave number
2482 !
2483 ! temporary data
2484 !
2485 real dsigma(nsig) ! step size of sigma array, used for integration
2486 !------------------------------------------------------------------------------
2487 !
2488 call q_stack('+q_dscale')
2489 !
2490 call z_steps(sigma,dsigma,nsig) ! compute step size of sigma's
2491 delta = angle(2)-angle(1) ! compute directional step (radians)
2492 !
2493 sum0 = 0.
2494 sumk = 0.
2495 !
2496 ! compute sums for total energy andwave number
2497 !
2498 do isig = 1,nsig
2499  w = sigma(isig)
2500  kk = z_wnumb(w,depth,grav) ! compute wave number for given sigma,depth
2501  sqkk = sqrt(kk)
2502  do iang=1,nang
2503  dnn = n(isig,iang)*dsigma(isig)*delta
2504  sum0 = sum0 + dnn
2505  sumk = sumk + 1./sqkk*dnn
2506  end do
2507 end do
2508 !
2509 ! compute mean wave number and scale factor based
2510 ! on the WAM approximation
2511 !
2512 if(sum0 > 0) then
2513  kms = (sum0/sumk)**2
2514  kd = max(0.5,0.75*kms*depth)
2515  q_dfac = 1+5.5/kd*(1.-5./6.*kd)*exp(-5./4.*kd)
2516 ! pause
2517 else
2518  kms = 0.
2519  kd = 0.
2520  q_dfac = 1.
2521 end if
2522 !
2523 call q_stack('-q_dscale')
2524 !
2525 return
2526 end subroutine
2527 !------------------------------------------------------------------------------
2528 
2542 
2543 subroutine q_error(err_type,err_name,err_msg)
2544 !------------------------------------------------------------------------------
2545 !
2546 ! +-------+ ALKYON Hydraulic Consultancy & Research
2547 ! | | Gerbrant van Vledder
2548 ! | +---+
2549 ! | | +---+ Last update 8 Aug. 2002
2550 ! +---+ | | Release: 4.0
2551 ! +---+
2552 !
2553 ! do not use m_xnldata
2554 use m_fileio
2555 implicit none
2556 !
2557 ! 0. Update history
2558 !
2559 ! 0.01 22/06/1999 Initial version
2560 ! 0.02 20/07/1999 Error message included
2561 ! 0.03 24/09/1999 Full message read from file Q_ERROR.TXT
2562 ! input argument ERR_NAME added
2563 ! 0.04 13/10/1999 Reading of multiple lines in Q_ERROR.TXT file
2564 ! 0.05 26/11/1999 Layout modified
2565 ! 0.06 30/11/1999 Extra output added, also to screen
2566 ! 4.01 08/08/2002 Upgrade to release 4
2567 !
2568 ! 1. Purpose:
2569 !
2570 ! Error handling routine, produces a warning to an error
2571 ! that has occured prints the error message and print
2572 ! module stack to trace the origin of the error/
2573 !
2574 ! 3. Parameter list:
2575 !
2576 !Type I/O Name Description
2577 !------------------------------------------------------------------------------
2578 character(len=1), intent(in) :: err_type ! type of error
2579 ! w or W: Warning or non-terminating error
2580 ! e or E: terminating error
2581 character(len=*), intent(in) :: err_name ! reference to error message
2582 character(len=*), intent(in) :: err_msg ! Optional additional error message
2583 !
2584 ! 4. Error messages
2585 !
2586 ! 5. Called by:
2587 !
2588 ! All q_** subroutines
2589 !
2590 ! 6. Subroutines used
2591 !
2592 ! 7. Remarks
2593 !
2594 ! The reference to an error message is stored in the
2595 ! string ERR_NAME. For each error number an associated
2596 ! error is given.
2597 !
2598 ! No call is made to subroutine q_trace to avoid
2599 ! infinite recursion
2600 !
2601 character(len=80) qline ! Input line from file with error messges
2602 integer ntext ! number of text line
2603 integer iend ! indicator for end of line
2604 integer iutxt ! unit number for text file
2605 integer iuerr ! indicator for error
2606 integer j_stack ! counter in printing stack
2607 integer ispace ! indicates that first character of line is space
2608 !
2609 call z_fileio(trim(qbase)//'.err','UF',iufind,luq_err,iuerr) ! error messages
2610 !
2611 ! logging of unit number
2612 !
2613 if(iq_log >= 1) write(luq_log,'(a,i4)') &
2614 & 'Q_ERROR: '//trim(qbase)//'.ERR connected to unit:',luq_err
2615 !
2616 ! write general information, when the first error or
2617 !
2618 if(iq_warn ==0 .and. iq_err==0) then
2619  write(luq_err,'(a)') q_version
2620  write(luq_err,'(a)')'--------------------------------------------------'
2621 end if
2622 !
2623 ! check type of error
2624 !
2625 if(index('wW',err_type) > 0) then
2626  iq_warn = iq_warn + 1
2627  write(luq_err,'(a,i4)') 'Warning or non-terminating error:',iq_warn
2628  write(luq_err,'(a,a)') 'Name of error:',trim(err_name)
2629 !
2630 elseif(index('eE',err_type) > 0) then
2631  iq_err = iq_err + 1
2632  write(luq_err,'(a,i4)') 'Terminating error:',iq_err
2633  write(luq_err,'(a,a)') 'Name of error:',trim(err_name)
2634  write(*,'(1x,a,i4)') 'Terminating error:',iq_err
2635  write(*,'(1x,a,a)') 'Name of error:',trim(err_name)
2636 end if
2637 !
2638 ! search explanation of error message in the file
2639 ! QF_ERROR, set in XNL_INIT
2640 !
2641 ntext = len_trim(err_name)
2642 !
2643 if(ntext > 0) then
2644  call z_fileio(qf_error,'OF',iufind,luq_txt,iutxt)
2645 !
2646  if(iutxt < 0) then
2647  if(iq_log > 0) write(luq_log,'(3a)') &
2648 & 'Q_ERROR: File ',trim(qf_error),' does not exist in current directory'
2649 !
2650  else
2651  if(iq_log >= 1) write(luq_log,'(a,i4)') &
2652 & 'Q_ERROR: File Q_ERROR.TXT connected to unit:',luq_txt
2653  iend=0
2654 !
2655 ! scan all lines in the text file with error messages
2656 !
2657  do while (iend==0)
2658  read(luq_txt,'(a)',iostat=iend) qline
2659  if(iend==0) then
2660 !
2661 ! check code word exists in text file
2662 !
2663  if(qline(1:ntext) == err_name(1:ntext)) then
2664  write(luq_err,*)
2665  write(luq_err,'(a)') 'Explanation of error, and recommended action'
2666  write(luq_err,'(a)') '--------------------------------------------'
2667  write(luq_err,'(a)') trim(qline)
2668 !
2669 ! read following lines until end of file or a non-space in column 1
2670 !
2671  ispace = 1
2672  do while (ispace ==1)
2673  read(luq_txt,'(a)',iostat=iend) qline
2674 !
2675 ! check conditions
2676 !
2677  if(iend==0) then
2678  if(qline(1:1) == ' ') then
2679  write(luq_err,'(a)') trim(qline)
2680  else
2681  ispace = 0
2682  end if
2683  else
2684  ispace = 0
2685  end if
2686  end do
2687  end if
2688  end if
2689  end do
2690 !
2691 ! close text file with error messages
2692 !
2693  close(luq_txt)
2694  if(iq_log >= 1) write(luq_log,'(3a,i4)') &
2695 & 'Q_ERROR: File ',trim(qf_error),' disconnected from unit:',luq_txt
2696  end if
2697 end if
2698 !
2699 if(len_trim(err_msg) > 0) then
2700  write(luq_err,*)
2701  write(luq_err,'(a)') 'Additional message from point of occurrence:'
2702  write(luq_err,'(a)') trim(err_msg)
2703  write(luq_err,*)
2704 end if
2705 !
2706 ! print stack of subroutines to trace the location where the
2707 ! error occurred
2708 !
2709 write(luq_err,'(a)') 'Trace of error'
2710 write(luq_err,'(a)') '--------------'
2711 do j_stack=1,iq_stack
2712  write(luq_err,'(1x,i4,2x,a)') j_stack,trim(cstack(j_stack))
2713 end do
2714 !
2715 write(luq_err,*)
2716 !
2717 if(iq_warn > 10) stop 'Too many warnings'
2718 !
2719 return
2720 end subroutine
2721 !------------------------------------------------------------------------------
2722 
2740 
2741 subroutine q_getlocus(ik1,ia1,ik3,ia3,ifnd)
2742 !------------------------------------------------------------------------------
2743 !
2744 ! +-------+ ALKYON Hydraulic Consultancy & Research
2745 ! | | Gerbrant van Vledder
2746 ! | +---+
2747 ! | | +---+ Last update: 27 August 2003
2748 ! +---+ | | Release: 5.0
2749 ! +---+
2750 !
2751 ! do not use m_xnldata
2752 use m_constants
2753 use serv_xnl4v5
2754 !----------------------------------------------------------------------------------
2755 implicit none
2756 !
2757 ! 0. Update history
2758 !
2759 ! 25/02/1999 Initial version
2760 ! 15/04/1999 Extra parameter IFND to indicate if a
2761 ! reference locus exists in the data base
2762 ! 19/07/1999 Restructured and some bugs removed
2763 ! 20/07/1999 Option added to compute locus directly, no database
2764 ! or scaling involved. IFND < 0
2765 ! 15/10/1999 Information to transformation file updated
2766 ! 16/10/1999 Equation for computing address for storage updated
2767 ! 25/10/1999 Transformations updated
2768 ! 28/10/1999 Local variables ia1 and ia3 may not be changed, temp. variables
2769 ! it1 and it3 included
2770 ! 29/10/1999 Use of IQ_TRF modified
2771 ! EPSK introduced to check equality of loci
2772 ! 28/12/1999 A_CMPLOC renamed to Q_CMPLOC
2773 ! 03/01/2000 IQ_START replaced by IQ_LOCUS
2774 ! 05/01/2000 Interface with Q_CMPLOC modified
2775 ! 08/08/2002 Upgrade to release 4.0
2776 ! 13/08/2002 Indexing in terms of integers and real weights
2777 ! upgrade to release 4.0
2778 ! 19/08/2002 Bug fixed in transforming CASE 6
2779 ! Interpolation option added
2780 ! 12/06/2003 Parameter t_ws set equal to r_ws
2781 ! 13/06/2003 Parameter t_cple, t_jac and t_sym assigned
2782 ! Bug fixed in nearest bin approach, symmetry regained
2783 ! 27/08/2003 Short-cut when number of points on locus is ZERO
2784 !
2785 ! 1. Purpose:
2786 !
2787 ! Retrieve locus from basic locus as stored in the database
2788 !
2789 ! 2. Method
2790 !
2791 ! In the case of geometric scaling, k-scaling is used using scale laws
2792 ! described by Tracy
2793 !
2794 ! Directional transformation using linear transformations, shifting and mirror
2795 ! imaging.
2796 !
2797 !
2798 ! 3. Parameter list:
2799 !
2800 !Type I/O name Description
2801 !------------------------------------------------------------------------------
2802 integer, intent(in) :: ik1 ! k-index of wave number k1
2803 integer, intent(in) :: ia1 ! theta-index of wave number k1
2804 integer, intent(in) :: ik3 ! k-index of wave number k3
2805 integer, intent(in) :: ia3 ! theta-index of wave number k3
2806 integer, intent(out) :: ifnd ! indicator if reference locus exists in database
2807 !
2808 ! 4. Error messages
2809 !
2810 ! 5. Called by
2811 !
2812 ! Q_T13V4
2813 !
2814 ! 6. Subroutines used
2815 !
2816 ! 7. Remarks
2817 !
2818 ! 8. Structure
2819 !
2820 ! 9. Switches
2821 !
2822 ! 10. Source code
2823 !------------------------------------------------------------------------------
2824 ! Local variables
2825 !
2826 integer it1,it3 ! work indices for directions, copy of ia1 and ia3
2827 integer idir ! switch to indicate if locus should be inverted
2828 integer itrans ! type of transformation
2829 integer iloc,jloc ! counters along locus
2830 integer iadif,ikdif ! difference in angular and k-index
2831 integer ja1r,ja3r
2832 integer imirror ! extra step when locus is mirrorred
2833 !
2834 integer ibeta,kdif
2835 integer nloc ! number of points on locus
2836 !
2837 integer ierr
2838 integer kmem ! index for storing 2-d matrix in 1-d array
2839 integer amem ! index for storing direction of reference wave number k3
2840 !
2841 real lambda ! geometric scale factor
2842 real j_lambda ! scale factor for Jacobian term
2843 real c_lambda ! scale factor for coupling coefficient
2844 real zz_lambda ! combined scale factor
2845 !
2846 real xt2(nlocus),yt2(nlocus) ! xy-components of test k2-locus
2847 real xt4(nlocus),yt4(nlocus) ! xy-components of test k4-locus
2848 real wk,wa,vk,va
2849 !! \A
2850 !! real x_kfunc ! real function to compute wave number
2851 !! \Z
2852 !
2853 integer ikmin,ja1,ja3,jk1,jk3,itmin
2854 integer ibdif,nhalf
2855 integer iaq,ikq ! counters for loop over direction and wave numbers
2856 !------------------------------------------------------------------------------
2857 !
2858 !! data i_getloc /0/ ! Initialise counter
2859 !-------------------------------------------------------------------------------------
2860 call q_stack('+q_getlocus')
2861 !
2862 !------------------------------------------------------------------------------
2863 ! initialisations
2864 !------------------------------------------------------------------------------
2865 !
2866 it1 = ia1
2867 it3 = ia3
2868 !
2869 imirror = 1
2870 !
2871 ikmin = min(ik1,ik3) ! compute minimum of wave number index
2872 ikdif = abs(ik1-ik3) ! compute difference between wave number indices
2873 !
2874 if (iq_geom ==0) then
2875  jk1 = min(ik1,ik3)
2876  jk3 = max(ik1,ik3)
2877 else
2878  jk1 = 1
2879  jk3 = ikdif + 1 ! compute k-index of wave number k3 relative to reference wave number
2880 end if
2881 !
2882 itmin = min(it1,it3) ! compute minimum angle of k1 and k3
2883 iadif = abs(it1-it3) ! difference index
2884 ja1 = 1 ! index of direction of reference wave number k1
2885 ja3 = iadif+iaref ! compute theta-index of direction of wave number k3
2886 !
2887 !------------------------------------------------------------------------------
2888 ! circle grid, modify ranges and transformation variables
2889 !------------------------------------------------------------------------------
2890 !
2891 if (iq_grid==3) then
2892  nhalf = naq/2
2893  if (iadif > nhalf) then
2894  if(it1 > nhalf) it1 = it1 - naq
2895  if(it3 > nhalf) it3 = it3 - naq
2896  end if
2897  itmin = min(it1,it3)
2898  ibdif = (naq - abs(naq-2*abs(it1-it3)))/2 ! compute shortest difference in indices
2899  ! while taking care of periodicity
2900  ja3 = ibdif + 1
2901  iadif = ibdif
2902 end if
2903 !
2904 ja1r = 1
2905 ja3r = iadif + 1
2906 amem = iadif + 1 ! compute index of reference wave number k3 in interaction grid
2907 !
2908 !------------------------------------------------------------------------------
2909 ! obtain k-index of reference wave number
2910 !------------------------------------------------------------------------------
2911 !
2912 if(iq_geom==0) then
2913  kmem = (jk3-jk1+1) - (jk1-2*nkq-2)*(jk1-1)/2
2914 else
2915  kmem = ikdif+1
2916 end if
2917 !
2918 !
2919 !------------------------------------------------------------------------------
2920 ! check memory indexing
2921 !------------------------------------------------------------------------------
2922 !
2923 if (amem > iamax) then
2924  ifnd = 0
2925  call q_error('e','MEMORY','Incorrect addres')
2926  goto 9999
2927 end if
2928 !
2929 !-----------------------------------------------------------------------------
2930 ! retrieve info from reference locus in
2931 ! get actual number of valid points along locus (NLOCUSZ)
2932 ! depending on value of switch IQ_COMPACT
2933 !------------------------------------------------------------------------------
2934 !
2935 nloc = quad_nloc(kmem,amem)
2936 nlocusx = nloc
2937 !
2938 ! short-cut when number of NON-ZERO points on locus is ZERO [27/8/2003]
2939 !
2940 if(nlocusx==0) goto 9999
2941 !
2942 r_ik2(1:nloc) = quad_ik2(kmem,amem,1:nloc)
2943 r_ia2(1:nloc) = quad_ia2(kmem,amem,1:nloc)
2944 r_ik4(1:nloc) = quad_ik4(kmem,amem,1:nloc)
2945 r_ia4(1:nloc) = quad_ia4(kmem,amem,1:nloc)
2946 !
2947 r_w1k2(1:nloc) = quad_w1k2(kmem,amem,1:nloc)
2948 r_w2k2(1:nloc) = quad_w2k2(kmem,amem,1:nloc)
2949 r_w3k2(1:nloc) = quad_w3k2(kmem,amem,1:nloc)
2950 r_w4k2(1:nloc) = quad_w4k2(kmem,amem,1:nloc)
2951 !
2952 r_w1k4(1:nloc) = quad_w1k4(kmem,amem,1:nloc)
2953 r_w2k4(1:nloc) = quad_w2k4(kmem,amem,1:nloc)
2954 r_w3k4(1:nloc) = quad_w3k4(kmem,amem,1:nloc)
2955 r_w4k4(1:nloc) = quad_w4k4(kmem,amem,1:nloc)
2956 !
2957 r_zz(1:nloc) = quad_zz(kmem,amem,1:nloc)
2958 !
2959 !------------------------------------------------------------------------------
2960 kdif = ikmin - 1
2961 if(iq_geom==0) then
2962  lambda = 1.
2963  kdif = 0.
2964 else
2965  lambda = q_kfac**(ikmin-1.)
2966 end if
2967 !
2968 j_lambda = 1./sqrt(lambda)
2969 c_lambda = lambda**6
2970 !
2971 ! compute combined scale factor
2972 !
2973 zz_lambda = lambda*c_lambda/j_lambda
2974 !
2975 !------------------------------------------------------------------------------
2976 ! select case to transform reference locus
2977 !
2978 ! Transform of weigths reduces to an addition or subtraction
2979 ! because of log-spacing of wave numbers in the case of deep water
2980 !
2981 if(ik3 > ik1 .and. it3 >= it1) then ! Case 1
2982  itrans = 1
2983  t_ik2(1:nloc) = kdif + r_ik2(1:nloc)
2984  t_ik4(1:nloc) = kdif + r_ik4(1:nloc)
2985  ibeta = itmin-iaref
2986  t_ia2(1:nloc) = r_ia2(1:nloc) + ibeta
2987  t_ia4(1:nloc) = r_ia4(1:nloc) + ibeta
2988  idir = 1
2989  t_w1k2(1:nloc) = r_w1k2(1:nloc)
2990  t_w2k2(1:nloc) = r_w2k2(1:nloc)
2991  t_w3k2(1:nloc) = r_w3k2(1:nloc)
2992  t_w4k2(1:nloc) = r_w4k2(1:nloc)
2993  t_w1k4(1:nloc) = r_w1k4(1:nloc)
2994  t_w2k4(1:nloc) = r_w2k4(1:nloc)
2995  t_w3k4(1:nloc) = r_w3k4(1:nloc)
2996  t_w4k4(1:nloc) = r_w4k4(1:nloc)
2997 !
2998 elseif(ik3 > ik1 .and. it3 < it1) then ! Case 2
2999  itrans = 2
3000  t_ik2(1:nloc) = kdif + r_ik2(1:nloc)
3001  t_ik4(1:nloc) = kdif + r_ik4(1:nloc)
3002  ibeta = int(q_ad(ia1)/q_deltad+0.01)
3003  t_ia2(1:nloc) = ibeta + 2.*iaref - r_ia2(1:nloc) -imirror
3004  t_ia4(1:nloc) = ibeta + 2.*iaref - r_ia4(1:nloc) -imirror
3005  t_w1k2(1:nloc) = r_w3k2(1:nloc)
3006  t_w2k2(1:nloc) = r_w4k2(1:nloc)
3007  t_w3k2(1:nloc) = r_w1k2(1:nloc)
3008  t_w4k2(1:nloc) = r_w2k2(1:nloc)
3009  t_w1k4(1:nloc) = r_w3k4(1:nloc)
3010  t_w2k4(1:nloc) = r_w4k4(1:nloc)
3011  t_w3k4(1:nloc) = r_w1k4(1:nloc)
3012  t_w4k4(1:nloc) = r_w2k4(1:nloc)
3013  idir = -1 ! according to theory
3014 ! idir = 1 ! as it should be to get symmetry
3015 !
3016 elseif(ik1 > ik3 .and. it3 >= it1) then ! Case 3
3017  itrans = 3
3018  t_ik2(1:nloc) = kdif + r_ik4(1:nloc)
3019  t_ik4(1:nloc) = kdif + r_ik2(1:nloc)
3020  ibeta = int(q_ad(ia3)/q_deltad+0.01)
3021  t_ia2(1:nloc) = ibeta + 2.*iaref - r_ia4(1:nloc) -imirror
3022  t_ia4(1:nloc) = ibeta + 2.*iaref - r_ia2(1:nloc) -imirror
3023  t_w1k2(1:nloc) = r_w3k2(1:nloc)
3024  t_w2k2(1:nloc) = r_w4k2(1:nloc)
3025  t_w3k2(1:nloc) = r_w1k2(1:nloc)
3026  t_w4k2(1:nloc) = r_w2k2(1:nloc)
3027  t_w1k4(1:nloc) = r_w3k4(1:nloc)
3028  t_w2k4(1:nloc) = r_w4k4(1:nloc)
3029  t_w3k4(1:nloc) = r_w1k4(1:nloc)
3030  t_w4k4(1:nloc) = r_w2k4(1:nloc)
3031  idir = 1
3032 !
3033 elseif(ik1 > ik3 .and. it1 > it3) then ! Case 4
3034  itrans = 4
3035  t_ik2(1:nloc) = kdif + r_ik4(1:nloc)
3036  t_ik4(1:nloc) = kdif + r_ik2(1:nloc)
3037  ibeta = itmin-iaref
3038  t_ia2(1:nloc) = ibeta + r_ia4(1:nloc)
3039  t_ia4(1:nloc) = ibeta + r_ia2(1:nloc)
3040  idir = -1
3041  t_w1k2(1:nloc) = r_w1k2(1:nloc)
3042  t_w2k2(1:nloc) = r_w2k2(1:nloc)
3043  t_w3k2(1:nloc) = r_w3k2(1:nloc)
3044  t_w4k2(1:nloc) = r_w4k2(1:nloc)
3045  t_w1k4(1:nloc) = r_w1k4(1:nloc)
3046  t_w2k4(1:nloc) = r_w2k4(1:nloc)
3047  t_w3k4(1:nloc) = r_w3k4(1:nloc)
3048  t_w4k4(1:nloc) = r_w4k4(1:nloc)
3049 !
3050 elseif(ik1==ik3 .and. it3 > it1) then ! Case 5
3051  itrans = 5
3052  t_ik2(1:nloc) = kdif + r_ik2(1:nloc)
3053  t_ik4(1:nloc) = kdif + r_ik4(1:nloc)
3054  ibeta = itmin-iaref
3055  t_ia2(1:nloc) = r_ia2(1:nloc) + ibeta
3056  t_ia4(1:nloc) = r_ia4(1:nloc) + ibeta
3057  idir = 1
3058  t_w1k2(1:nloc) = r_w1k2(1:nloc)
3059  t_w2k2(1:nloc) = r_w2k2(1:nloc)
3060  t_w3k2(1:nloc) = r_w3k2(1:nloc)
3061  t_w4k2(1:nloc) = r_w4k2(1:nloc)
3062  t_w1k4(1:nloc) = r_w1k4(1:nloc)
3063  t_w2k4(1:nloc) = r_w2k4(1:nloc)
3064  t_w3k4(1:nloc) = r_w3k4(1:nloc)
3065  t_w4k4(1:nloc) = r_w4k4(1:nloc)
3066 !
3067 elseif(ik1==ik3 .and. it1 > it3) then ! Case 6
3068  itrans = 6
3069  t_ik2(1:nloc) = kdif + r_ik4(1:nloc)
3070  t_ik4(1:nloc) = kdif + r_ik2(1:nloc)
3071  ibeta = int(q_ad(ia1)/q_deltad+0.01)
3072  t_ia2(1:nloc) = ibeta + 2.*iaref - r_ia2(1:nloc) -imirror
3073  t_ia4(1:nloc) = ibeta + 2.*iaref - r_ia4(1:nloc) -imirror
3074 !! ibeta = itmin-iaref
3075 !! t_ia2(1:nloc) = r_ia4(1:nloc) + ibeta
3076 !! t_ia4(1:nloc) = r_ia2(1:nloc) + ibeta
3077  idir = -1
3078  t_w1k2(1:nloc) = r_w3k2(1:nloc)
3079  t_w2k2(1:nloc) = r_w4k2(1:nloc)
3080  t_w3k2(1:nloc) = r_w1k2(1:nloc)
3081  t_w4k2(1:nloc) = r_w2k2(1:nloc)
3082  t_w1k4(1:nloc) = r_w3k4(1:nloc)
3083  t_w2k4(1:nloc) = r_w4k4(1:nloc)
3084  t_w3k4(1:nloc) = r_w1k4(1:nloc)
3085  t_w4k4(1:nloc) = r_w2k4(1:nloc)
3086 end if
3087 !
3088 t_zz(1:nloc) = lambda*c_lambda/j_lambda * r_zz(1:nloc)
3089 !
3090 ifnd = 1
3091 !
3092 !------------------------------------------------------------------------------
3093 !
3094 9999 continue
3095 !
3096 call q_stack('-q_getlocus')
3097 !
3098 return
3099 end subroutine
3100 !------------------------------------------------------------------------------
3119 
3120 subroutine q_init
3121 !------------------------------------------------------------------------------
3122 !
3123 ! +-------+ ALKYON Hydraulic Consultancy & Research
3124 ! | | Gerbrant van Vledder
3125 ! | +---+
3126 ! | | +---+ Last update: 25 Sep. 2002
3127 ! +---+ | | Release: 5.0
3128 ! +---+
3129 !
3130 ! do not use m_xnldata
3131 use m_fileio
3132 use m_constants
3133 use serv_xnl4v5
3134 implicit none
3135 !--------------------------------------------------------------------------------
3136 ! 0. Update history
3137 !
3138 ! 25/02/1999 Initial version
3139 ! 13/10/1999 Error handling improved
3140 ! 18/10/1999 Test output to MATCHK.GRD added
3141 ! 21/10/1999 Extra output to MATCHK.GRD, iaref=1 for circle grids
3142 ! 01/11/1999 Allocatable arrays Q_XK and Q_SK added
3143 ! 14/02/2001 Version ready for WAVEWATCH III
3144 ! 8/08/2002 Release 4.
3145 ! 16/08/2002 Group velocity computed
3146 ! 22/08/2002 First and last used defined direction accounted for
3147 ! 11/09/2002 Call of Q_ALOC moved to higher level, viz. XNL_INIT
3148 ! q_kpow initialized
3149 ! 25/09/2002 User defined directions used in the case of a sector grid
3150 !
3151 ! 1. Purpose:
3152 !
3153 ! Initializing module for quadruplets
3154 ! and setting default settings
3155 !
3156 ! 2. Method
3157 !
3158 ! Conversion of power of spectral tail from E(f) to N(k) using the following
3159 ! relations:
3160 !
3161 ! E(f) ~ f^qf_tail
3162 !
3163 ! N(k) ~ k^qk_tail
3164 !
3165 ! qk_tail = qf_tail/2 -1
3166 !
3167 ! See also Note 13 of G.Ph. van Vledder
3168 !
3169 ! 3. Parameter list:
3170 !
3171 ! Name I/O Type Description
3172 !
3173 !
3174 ! 4. error meassage
3175 !
3176 ! 5. Called by
3177 !
3178 ! XNL_INIT
3179 !
3180 ! 6. Subroutines used
3181 !
3182 ! Q_STACK
3183 ! Z_CMPCG
3184 ! Z_STEPS
3185 ! Z_WNUMB
3186 !
3187 ! 7. Remarks
3188 !
3189 ! 8. Structure
3190 !
3191 ! 9. Switches
3192 !
3193 ! /S Enable subroutine tracing
3194 !
3195 ! 10. Source code
3196 !------------------------------------------------------------------------------------------
3197 ! Local variables
3198 !
3199 integer iaq,ikq ! counters for loops over directions and wave numbers
3200 real ff ! frequency
3201 !!!real z_wnumb ! service function to compute wave number
3202 !
3203 !------------------------------------------------------------------------------
3204 !
3205 call q_stack('+q_init')
3206 !
3207 ! set general settings
3208 !
3209 ! convert power of E(f) f^qf_tail to power of N(k) k^qk_tail
3210 ! See Note 13 of G.Ph. van Vledder
3211 !
3212 qk_tail = (qf_tail-2.)/2. ! power of spectral tail, of N(k)
3213 !
3214 if(iq_prt >=2) then
3215  write(luq_prt,*)
3216  write(luq_prt,'(a,f6.1)') 'Q_INIT: E(f)_tail: ',qf_tail
3217  write(luq_prt,'(a,f6.1)') 'Q_INIT: N(k)_tail: ',qk_tail
3218 end if
3219 !
3220 ! set absolute and relative accuracies
3221 !
3222 eps_q = 0.001 ! absolute accuracy for check of q==0
3223 eps_k = 1.e-5 ! absolute accuracy for equality check of k
3224 rel_k = 0.001 ! relative accuracy for equality check of k
3225 !
3226 sk_max = 50. ! set maximum waver number
3227 wk_max = real(nkq+0.9999) ! set maximum wave number index
3228 !
3229 ! compute frequency and wave number grid
3230 ! assume that frequencies are always geometrically spaced,
3231 ! in the case of deep water this also holds for the wave numbers
3232 !
3233 q_ffac = (fqmax/fqmin)**real(1./(nkq-1.)) ! geometric spacing factor of frequencies
3234 !
3235 ff = fqmin ! set minimum frequency
3236 !
3237 if(iq_prt>=2) then
3238  write(luq_prt,*)
3239  write(luq_prt,'(a)') 'Basic wave numbers, frequencies'
3240 end if
3241 !
3242 do ikq=1,nkq ! Generate wave number dependent variables
3243  q_f(ikq) = ff ! Frequency
3244  q_sig(ikq) = ff*2.*pi ! Radian frequency
3245  q_k(ikq) = z_wnumb(q_sig(ikq),q_depth,q_grav) ! compute wave number
3246  q_kpow(ikq) = (q_k(1)/q_k(ikq))**7.5 ! used in filtering
3247  ff = ff*q_ffac ! Increase frequency
3248 !
3249  call z_cmpcg(q_sig(ikq),q_depth,q_grav,q_cg(ikq))
3250  if(iq_prt >= 2) then
3251  write(luq_prt,'(a,i4,3f10.5,e12.4)') 'Q_INIT: ikq f sigma k k^p:', &
3252 & ikq,q_f(ikq),q_sig(ikq),q_k(ikq),q_kpow(ikq)
3253  end if
3254 end do
3255 !
3256 ! compute characteristics of extended k-array
3257 !
3258 if(iq_prt>=2) then
3259  write(luq_prt,*)
3260  write(luq_prt,'(a)') 'Extended wave numbers and spacing'
3261 end if
3262 !
3263 do ikq=0,nkq
3264  if(ikq==0) then
3265  q_xk(ikq) = 0.
3266  q_sk(ikq) = q_k(1)
3267  elseif(ikq==nkq) then
3268  q_xk(ikq) = q_k(ikq)
3269  q_sk(ikq) = sk_max
3270  else
3271  q_xk(ikq) = q_k(ikq)
3272  q_sk(ikq) = q_k(ikq+1) - q_k(ikq)
3273  end if
3274 !
3275 end do
3276 !
3277 !
3278 kqmin = q_k(1)
3279 kqmax = q_k(nkq)
3280 q_kfac = (kqmax/kqmin)**real(1./(nkq-1)) ! this value makes only sense in the
3281  ! case of deep water, IQ_DISP==1
3282 !
3283 ! compute step size of frequency grids and wave number grid
3284 !
3285 call z_steps(q_f, q_df, nkq) ! step size of frequencies
3286 call z_steps(q_sig,q_dsig,nkq) ! step size of radian frequencies
3287 call z_steps(q_k, q_dk, nkq) ! step size of wave numbers
3288 !
3289 if(iq_prt >= 2) then
3290  write(luq_prt,*)
3291  write(luq_prt,'(a)') 'Q_INIT: Additional information'
3292  write(luq_prt,'(a,f8.1)') 'Q_depth (m):',q_depth
3293  write(luq_prt,'(a,i3)') 'Number of frequencies:',nkq
3294  write(luq_prt,'(a,f8.4)') 'Geometric f-spacing factor:',q_ffac
3295  write(luq_prt,'(a,f8.4)') 'Geometric k-spacing factor:',q_kfac
3296  write(luq_prt,'(a,2f8.3)') 'fmin fmax (Hz):',fqmin,fqmax
3297  write(luq_prt,'(a,2f8.3)') 'kmin kmax (Hz):',kqmin,kqmax
3298  write(luq_prt,*)
3299 !
3300  write(luq_prt,*) ' i f df sig dsig k dk cg'
3301 !
3302  do ikq=1,nkq
3303  write(luq_prt,'(1x,i4,7f10.4)') &
3304  & ikq,q_f(ikq),q_df(ikq),q_sig(ikq),q_dsig(ikq),q_k(ikq),q_dk(ikq),q_cg(ikq)
3305  end do
3306 end if
3307 !
3308 ! =============== D I R E C T I O N S ===============================================
3309 !
3310 ! the directions in the array ANGLE are running from 1 to NAQ
3311 ! for a sector definition the middle direction has index IAREF
3312 !
3313 ! compute index IAREF of middle wave direction for sector grids
3314 !
3315 if(iq_grid ==1 .or. iq_grid==2) then
3316  iaref = (naq/2)+1
3317 elseif(iq_grid==3) then
3318  iaref = 1
3319 end if
3320 !
3321 if(iq_prt >= 2) write(luq_prt,'(a,i4)') &
3322 & 'Q_INIT: Index of first direction for reference:',iaref
3323 !
3324 ! set loops indices
3325 !
3326 if(iq_grid==1) then ! symmetric sector
3327  iaq1 = iaref
3328  iaq2 = naq
3329 !
3330 ! non-symmetric sector and full circle
3331 !
3332 elseif(iq_grid==2 .or. iq_grid==3) then
3333  iaq1 = 1
3334  iaq2 = naq
3335 end if
3336 !
3337 if(iq_prt >= 2) write(luq_prt,'(a,2i4)') &
3338 & 'Q_INIT: Range of indices for loop over directions:',iaq1,iaq2
3339 !
3340 ! generate directions, given in degrees
3341 !
3342 q_sector = 0.5*(abs(q_dird1) + abs(q_dird2))
3343 !
3344 if(iq_grid==1 .or. iq_grid==2) then ! define symmetric sector
3345  q_deltad = 2.*q_sector/real(naq-1.) ! delta in degrees
3346  q_ang1 = -q_sector ! degrees
3347  q_ang2 = q_sector ! degrees
3348  if(iq_prt>0) write(luq_prt,'(a)') 'Q_INIT: take care of q_dird1 and check if sector is OK'
3349 !
3350 elseif(iq_grid==3) then ! full sector
3351  q_deltad = 360./real(naq) ! degrees
3352  q_ang1 = 0 ! degrees
3353  q_ang2 = 360.-q_delta ! degrees
3354 end if
3355 !
3356 q_delta = q_deltad*dera ! directional step in radians
3357 ncirc = 2.00001*pi/q_delta ! number of directions on circle
3358 !
3359 if(iq_prt >= 2) then
3360  write(luq_prt,'(a,3f10.3)') 'Q_INIT: d(1),d(n),dsector:',q_dird1,q_dird2,q_sector
3361  write(luq_prt,'(a,f6.2,a)') 'Q_INIT: Angular step :',q_deltad,' degrees'
3362  write(luq_prt,'(a,2f8.2,i4,a)') 'Q_INIT: ang1 ang2 nang :',q_ang1,q_ang2,naq,' degrees'
3363  write(luq_prt,'(a,i4)') 'Q_INIT: #Angles on circle:',ncirc
3364  write(luq_prt,*)
3365 end if
3366 !
3367 ! generate directions arrays, given in degrees and radians
3368 !
3369 do iaq=1,naq
3370  q_ad(iaq) = q_ang1 + q_deltad*(iaq-1.)
3371  q_a(iaq) = q_ad(iaq)*dera
3372  if(iq_prt >= 2) then
3373  write(luq_prt,'(a,i4,f10.4,f10.2)') 'Q_INIT: iaq q_a q_ad:',iaq,q_a(iaq),q_ad(iaq)
3374  if(iaq==naq) write(luq_prt,*)
3375  end if
3376 end do
3377 !
3378 ! set loop indices for generation of grid
3379 ! for sector grids and circle grids
3380 !
3381 if(iq_grid==1 .or. iq_grid==2) then
3382  iag1 = iaref
3383  iag2 = naq
3384 !
3385 ! circle grid
3386 !
3387 elseif(iq_grid==3) then
3388  iag1 = 1
3389  iag2 = naq/2+1
3390 end if
3391 !
3392 iamax = iag2-iag1+1
3393 !-------------------------------------------------------------------------
3394 !
3395 !
3396 call q_stack('-q_init')
3397 !
3398 return
3399 end subroutine
3400 !------------------------------------------------------------------------------
3412 
3413 subroutine q_locpos(ka,kb,km,kw,loclen)
3414 !------------------------------------------------------------------------------
3415 !
3416 ! +-------+ ALKYON Hydraulic Consultancy & Research
3417 ! | | Gerbrant van Vledder
3418 ! | +---+
3419 ! | | +---+ Last update: 14 Oct. 2002
3420 ! +---+ | | Release: 5.0
3421 ! +---+
3422 !
3423 ! do not use m_xnldata
3424 use m_constants
3425 use serv_xnl4v5, only: z_root2
3426 !
3427 implicit none
3428 !
3429 ! 0. Update history
3430 !
3431 ! Version Date Description
3432 !
3433 ! 03/12/1999 Initial version
3434 ! 09/08/2002 Upgrade to release 4.0
3435 ! 29/08/2002 Error handling z_root2 relaxed and some write statements modified
3436 ! 07/10/2002 Initialisation of QSQ replaced
3437 !
3438 ! 1. Purpose:
3439 !
3440 ! Compute characteristics of locus used to optimize its acutal computation
3441 !
3442 ! 2. Method
3443 !
3444 ! 3. Parameter list:
3445 !
3446 !Type I/O Name Description
3447 !-----------------------------------------------------------------
3448 real, intent (out) :: ka ! minimum k along symmetry axis
3449 real, intent (out) :: kb ! maximum k along symmetry axis
3450 real, intent (out) :: km ! wave number at midpoint
3451 real, intent (out) :: kw ! half width of locus at midpoint
3452 real, intent (out) :: loclen ! estimated length of locus
3453 !
3454 ! 4. Error messages
3455 !
3456 ! 5. Called by:
3457 !
3458 ! Q_CMPLOCUS
3459 !
3460 ! 6. Subroutines used
3461 !
3462 ! z_zero2 Root finding method
3463 ! x_locus1 Function of locus geometry, along symmetry axis
3464 ! x_locus2 Function of locus geometry, perpendicular to symmetry axis
3465 ! x_flocus Locus function
3466 !
3467 ! 7. Remarks
3468 !
3469 ! 8. Structure
3470 !
3471 ! 9. Switches
3472 !
3473 ! /S enable subroutine tracing
3474 ! /T enable test output
3475 !
3476 ! 10. Source code
3477 !------------------------------------------------------------------------------
3478 ! Local variables
3479 !
3480 real kp ! wave number at peak
3481 real kpx,kpy ! wave number at peak maximum
3482 real zp ! value of locus function at maximum
3483 real za,zb ! (test) value of locus function at kmin & kmax
3484 real zz1,zz2 ! intermediate function values in interation process
3485 real kk1,kk2 ! start values for finding root of locus equation
3486 real kk1x,kk1y ! wave number components at one side of root
3487 real kk2x,kk2y ! wave number components at other side of root
3488 real beta1,beta2 ! parameters specifying cross component
3489 real betaw ! parameter specifying iterated cross component
3490 real kwx,kwy ! wave number at side of locus
3491 real zw ! function value at (kwx,kwy)
3492 real a1,a2,b1,b2 ! constants in polynomial approximation of elliptic function
3493 real aa,bb,mm,mm1 ! semi-major exis of ellips and derived parameters
3494 !
3495 real eps ! local machine accuracy for determination of roots
3496 real bacc ! accuracy for determination of beta
3497 real kacc ! accuracy for determination of wave number roots
3498 real qs ! (w1-w3)/sqrt(g)
3499 real qsq ! gs^2
3500 !
3501 ! Function declaration
3502 !
3503 !real z_root2 ! root finding using Ridders method
3504 !
3505 integer ierr ! local error indicator, used in function Z-ZERO1
3506 integer itest ! local test level for test output
3507 integer lutest ! unit for test output in service routines
3508 integer iter ! local iteration number
3509 integer maxiter ! maximum number of iteration for determining starting points
3510 !
3511 ! function declarations
3512 !!real, external :: x_locus2 ! locus function perpendicular to symmetry axis
3513 !!real x_flocus ! 2-d locus function
3514 !---------------------------------------------------------------------------------
3515 ! assign test options
3516 !
3517 itest = iq_test ! assign test level
3518 lutest = 0 ! assign default, no test output in service routines
3519 !
3520 itest = 0 ! reset local test level
3521 if(itest > 0) lutest=luq_tst ! assign unit for test output
3522 !
3523 call q_stack('+q_locpos')
3524 !
3525 ! set initial values
3526 !
3527 eps = epsilon(1.) ! determine machine accurcy
3528 maxiter = 20 ! maximum number of iterations
3529 !
3530 ! compute location of maximum, located at k_2 = P
3531 !
3532 kpx = -px
3533 kpy = -py
3534 kp = sqrt(kpx**2 + kpy**2)
3535 zp = x_locus1(kp)
3536 !
3537 ! find location of points A and B on locus
3538 ! for deep water, explicit relations are available
3539 !
3540 if(iq_disp==1) then
3541  qs = q/sqrtg
3542  qsq = qs*qs
3543  if(qs < 0) then
3544  ka = 0.5*(-qs+sqrt(2.0*pmag-qsq))
3545  ka = ka**2
3546  kb = (pmag+qsq)/(2.*qs)
3547  kb = kb**2
3548  za = x_locus1(ka)
3549  zb = x_locus1(kb)
3550  else
3551  ka = 0.5*(-qs+sqrt(2.0*pmag-qsq))
3552  ka = -ka**2
3553  kb = (pmag-qsq)/(2.*qs)
3554  kb = kb**2
3555  za = x_locus1(ka)
3556  zb = x_locus1(kb)
3557  end if
3558 !
3559 !
3560 ! find location of points A and B on locus
3561 ! for water of finite depth, an iteration process is applied to
3562 ! determine the zero-crossings of the locus function
3563 !
3564 else
3565 !
3566  if(q<0) then
3567 !
3568 ! set two start points to locate position of wave number ka
3569 !
3570  kk1 = 0.
3571  kk2 = kp
3572 !
3573 ! search root by Ridder's method
3574 !
3575  kacc = 10.*max(kk1,kk2)*eps
3576  ka = z_root2(x_locus1,kk1,kk2,kacc,lutest,ierr)
3577 !
3578 !
3579 !
3580 ! determine start points to locate position of wave number kb
3581 !
3582  kk1 = kp
3583  kk2 = kp
3584  zz1 = zp
3585  zz2 = zp
3586  iter = 0
3587 !
3588 ! ensure that two points are found on either side of zero-crossing
3589 !
3590  do while (zz1*zz2 >= 0 .and. iter < maxiter)
3591  iter = iter + 1
3592  kk2 = kk2*2
3593  zz2 = x_locus1(kk2)
3594  end do
3595 !
3596  if(iter>=maxiter) then
3597  call q_error('e','Start kb','Too many iterations needed')
3598  goto 9999
3599  end if
3600 !
3601 ! search root by Ridders method
3602 !
3603  kacc = 10.*max(kk1,kk2)*eps
3604  kb = z_root2(x_locus1,kk1,kk2,kacc,lutest,ierr)
3605 !
3606 !==================================================================
3607 ! find positions for ka and kb for the case q > 0
3608 !
3609  else
3610 !
3611 ! set two start points to locate position of wave number ka
3612 !
3613  kk1 = 0.
3614  kk2 = -kp
3615  zz1 = x_locus1(kk1)
3616  zz2 = x_locus1(kk2)
3617  iter = 0
3618 !
3619 ! ensure that two points are found on either side of zero-crossing
3620 !
3621  do while (zz1*zz2 >= 0 .and. iter < maxiter)
3622  iter = iter + 1
3623  kk2 = kk2*2
3624  zz2 = x_locus1(kk2)
3625  end do
3626 !
3627  if(iter>=maxiter) then
3628  call q_error('e','Start ka','Too many iterations needed')
3629  goto 9999
3630  end if
3631 !
3632 ! search root by Ridder's method
3633 !
3634  kacc = 10.*max(abs(kk1),abs(kk2))*eps
3635  ka = z_root2(x_locus1,kk1,kk2,kacc,lutest,ierr)
3636 !
3637 ! determine start points to locate position of wave number kb
3638 !
3639  kk1 = 0
3640  kk2 = kp
3641  zz1 = x_locus1(kk1)
3642  zz2 = x_locus1(kk2)
3643  iter = 0
3644 !
3645 ! ensure that two points are found on either side of zero-crossing
3646 !
3647  do while (zz1*zz2 >= 0 .and. iter < maxiter)
3648  iter = iter + 1
3649  kk2 = kk2*2
3650  zz2 = x_locus1(kk2)
3651  end do
3652 !
3653  if(iter>=maxiter) then
3654  call q_error('e','Start kb','Too many iterations needed')
3655  goto 9999
3656  end if
3657 !
3658 ! search root by Ridders method
3659 !
3660  kacc = 10.*max(kk1,kk2)*eps
3661  kb = z_root2(x_locus1,kk1,kk2,kacc,luq_tst,ierr)
3662 !
3663 ! find positions for ka and kb for the case q > 0
3664 !
3665  end if
3666 !
3667  za = x_locus1(ka)
3668  zb = x_locus1(kb)
3669 !
3670 end if
3671 !
3672 ! compute position of mid point
3673 !
3674 kmid = 0.5*(ka+kb)
3675 km = kmid
3676 !
3677 if(q < 0) then
3678  kmidx = kmid*cos(pang+pi)
3679  kmidy = kmid*sin(pang+pi)
3680 else
3681  kmidx = kmid*cos(pang)
3682  kmidy = kmid*sin(pang)
3683 end if
3684 !
3685 !
3686 ! compute width of locus near mid point of locus
3687 !
3688 ! set starting values for determination of crossing point
3689 !
3690 beta1 = 0.
3691 kk1x = kmidx
3692 kk1y = kmidy
3693 beta2 = 0.5
3694 kk2x = kmidx - beta2*py
3695 kk2y = kmidy + beta2*px
3696 zz1 = x_flocus(kk1x,kk1y)
3697 zz2 = x_flocus(kk2x,kk2y)
3698 !
3699 !
3700 iter = 0
3701 do while (zz1*zz2 > 0 .and. iter < maxiter)
3702  iter = iter + 1
3703  kk2x = kmidx - beta2*py
3704  kk2y = kmidy + beta2*px
3705  zz1 = x_flocus(kk1x,kk1y)
3706  zz2 = x_flocus(kk2x,kk2y)
3707  beta2 = beta2*2
3708 end do
3709 !
3710 ! call Ridders method to locate position of zero-crossing
3711 !
3712 !
3713 bacc = 10.*max(beta1,beta2)*eps
3714 betaw = z_root2(x_locus2,beta1,beta2,bacc,lutest,ierr)
3715 !
3716 !
3717 kwx = kmidx - betaw*py
3718 kwy = kmidy + betaw*px
3719 zw = x_flocus(kwx,kwy)
3720 kw = betaw*pmag
3721 !
3722 !
3723 ! estimate circumference of locus, assuming it to be an ellips
3724 ! estimate axis, this seems to be a rather good estimate
3725 !
3726 aa = 0.5*abs(ka-kb)
3727 bb = kw
3728 !
3729 if (aa > bb) then
3730  mm = 1-(bb/aa)**2
3731 else
3732  mm = 1-(aa/bb)**2
3733 end if
3734 !
3735 mm1 = 1.-mm
3736 a1 = 0.4630151; a2 = 0.1077812;
3737 b1 = 0.2452727; b2 = 0.0412496;
3738 !
3739 if (mm1==0) then
3740  loclen = 4.*max(aa,bb)
3741 else
3742  loclen = 4.*max(aa,bb)*((1. + a1*mm1 + a2*mm1**2) + (b1*mm1 + b2*mm1**2)*log(1/mm1))
3743 end if
3744 !
3745 !
3746 9999 continue
3747 !
3748 call q_stack('-q_locpos')
3749 !
3750 return
3751 end subroutine
3752 !
3753 !------------------------------------------------------------------------------
3762 
3763 subroutine q_makegrid
3764 !------------------------------------------------------------------------------
3765 !
3766 ! +-------+ ALKYON Hydraulic Consultancy & Research
3767 ! | | Gerbrant van Vledder
3768 ! | +---+
3769 ! | | +---+ Last update: 10 June 2003
3770 ! +---+ | | Release: 5.0
3771 ! +---+
3772 !
3773 ! do not use m_xnldata
3774 use m_constants
3775 use serv_xnl4v5
3776 !
3777 ! 0. Update history
3778 !
3779 ! 25/02/1999 Initial version
3780 ! 11/10/1999 Error handling improved; Bugs fixed when w1=w3
3781 ! 12/10/1999 Storage modified and non-geometric option included
3782 ! 16/10/1999 Equation for computing address of 2d array simplified
3783 ! 21/10/1999 Range of precomputed grid added to data file
3784 ! 22/10/1999 Renaming of some indices
3785 ! 25/10/1999 Header with grid info extended
3786 ! 12/11/1999 Output format modified of data to GRD file, adapted
3787 ! for use on UNIX systems at WES
3788 ! 08/12/1999 Interface with A_CMPLOC extended
3789 ! 28/12/1999 Routine A_CMPLOC renamed to Q_CMPLOC
3790 ! 03/01/2000 IQ_START replaced by IQ_LOCUS
3791 ! 05/01/2000 Interface with Q_CMPLOC modified
3792 ! 08/02/2000 Output to LUQLOC made conditional
3793 ! 09/08/2002 Name changed from Q_GRIDV1 to Q_MAKEGRID
3794 ! Upgrade to release 4.0
3795 ! 15/08/2002 Bug fixed in indexing bins below lowest wave number
3796 ! 20/08/2002 Sigma written to QUAD file, instead of wave numbers
3797 ! 22/08/2002 Data along locus compacted, elimate zero's
3798 ! 10/09/2002 Upgrade to release 5
3799 ! Value of LASTQUADFILE set
3800 ! 10/06/2003 Output to GRD file always without compacting
3801 !
3802 ! 1. Purpose:
3803 !
3804 ! Set-up grid for computation of loci
3805 !
3806 ! Generate data file with basic loci for computation of
3807 ! nonlinear quadruplet interactions
3808 !
3809 ! 2. Method
3810 !
3811 !
3812 ! 3. Parameter list:
3813 !
3814 ! Name I/O Type Description
3815 !
3816 ! 4. Error messages
3817 !
3818 ! 5. Called by:
3819 !
3820 ! Q_CTRGRID
3821 !
3822 ! 6. Subroutines used
3823 !
3824 ! Q_STACK
3825 ! Q_CPMLOCUS
3826 ! Q_MODIFY
3827 ! Q_WEIGHT
3828 ! Q_CHKRES
3829 ! Q_NEAREST
3830 !
3831 ! 7. Remarks
3832 !
3833 ! 8. Structure
3834 !
3835 ! 9. Switches
3836 !
3837 ! 10. Source code
3838 !------------------------------------------------------------------------------
3839 ! Local variables
3840 !
3841 integer iloc,jloc ! counters
3842 integer iaq,ikq ! counters
3843 integer iaq3,ikq1,ikq3,nkq1 ! counters
3844 integer jaq1,jaq3 ! counters
3845 integer amem,kmem ! index of angle and wave number in grid
3846 real aa1,aa3,kk1,kk3 ! temporary wave number variables
3847 !
3848 integer nzloc ! counter for non-zero contributions along locus
3849 integer nztot1,nztot2 ! total number of zero and non-zero points on locus
3850 integer ik2,ia2 ! index of wave number k2
3851 integer ik4,ia4 ! index of wave number k4
3852 !
3853 real wk,wa ! weights
3854 real w1k2,w2k2,w3k2,w4k2 ! interpolation weights
3855 real w1k4,w2k4,w3k4,w4k4 ! interpolation weights
3856 !
3857 real ka,kb ! lower and higher wave number magnitude
3858 real km ! wave number at mid point
3859 real kw ! half width of locus
3860 !
3861 real tfac ! combined tail factor
3862 !
3863 logical lwrite ! indicator if binary interaction grid has been written successfully
3864 real smax ! maximum s-value
3865 !
3866 real, allocatable :: xloc(:),yloc(:)
3867 real qq
3868 !-------------------------------------------------------------------------------
3869 call q_stack('+q_makegrid')
3870 !
3871 ! initializations
3872 !
3873 lwrite = .false.
3874 nztot1 = 0
3875 nztot2 = 0
3876 !%
3877 quad_nloc = -1 ! number of points on all loci
3878 !%
3879 if(allocated(xloc)) deallocate(xloc) ; allocate (xloc(mlocus))
3880 if(allocated(yloc)) deallocate(yloc) ; allocate (yloc(mlocus))
3881 !
3882 ! write header to grid file
3883 !
3884 !
3885 ! set range of do loops for computing interaction grid
3886 !
3887 if(iq_geom==0 .or. iq_disp/=1) then
3888  nkq1 = nkq ! loop over all k1 wave numbers, since no geometric scaling can be used
3889 else
3890  nkq1 = 1 ! use only first wave number for k1, since geometric scaling can be used
3891 end if
3892 !
3893 jaq1 = 1 ! index of direction of k1 in grid matrix
3894 !-------------------------------------------------------------------------------------
3895 ! compute components of reference wave number,
3896 ! for setting up interaction grid
3897 !-------------------------------------------------------------------------------------
3898 k1: do ikq1=1,nkq1
3899 !
3900  if(iq_screen==2) write(iscreen,*) 'k1-ring:',ikq1
3901 !
3902  aa1 = q_ad(iaref)
3903  kk1 = q_k(ikq1)
3904  krefx = kk1*cos(q_ad(iaref)*dera)
3905  krefy = kk1*sin(q_ad(iaref)*dera)
3906 !
3907  k1x = krefx
3908  k1y = krefy
3909 !
3910 
3911 k3: do ikq3 = ikq1,nkq !
3912  if(iq_screen==2) write(iscreen,*) 'k1-k3 indices:',ikq1,ikq3
3913 !
3914  kk3 = q_k(ikq3)
3915 !
3916 !
3917 a3: do iaq3 = iag1,iag2
3918 !
3919  if(iaq3 == iag1 .and. ikq3 == ikq1) cycle
3920 !
3921  aa3 = q_ad(iaq3)
3922  k3x = kk3*cos(aa3*dera)
3923  k3y = kk3*sin(aa3*dera)
3924 !------------------------------------------------------------------------------
3925 ! compute locus for a specified combination of k1 and k3
3926 !
3927 !-----------------------------------------------------------------------------
3928  ia_k1 = iaq1; ik_k1 = ikq1
3929  ia_k3 = iaq3; ik_k3 = ikq3
3930  call q_cmplocus(ka,kb,km,kw,crf1)
3931 !
3932  if(iq_err/=0) goto 9999
3933 !------------------------------------------------------------------------------
3934 ! redistibute or filter data points along locus
3935 !
3936  call q_modify
3937  if(iq_err > 0) goto 9999
3938 !------------------------------------------------------------------------------
3939 ! compute weights for interpolation in computational grid
3940 !
3941  call q_weight
3942  if(iq_err > 0) goto 9999
3943 !------------------------------------------------------------------------------
3944 ! special storing mechanism for interactions per combination of k1 and k3
3945 !
3946  kmem = (ikq3-ikq1+1) - (ikq1-2*nkq-2)*(ikq1-1)/2;
3947  jaq3 = iaq3-iaref+1 ! ensure that data stored in matrix start at index (1,1)
3948  amem = jaq3 ! index of direction
3949 !
3950 !
3951 !-------------------------------------------------------------------------------
3952 ! Convert real indices to integer indexing and real weights
3953 !
3954 ! 3-----------4 ja2p w1 = (1-wk)*(1-wa)
3955 ! | . | w2 = wk*(1-wa)
3956 ! |. . + . . .| wa2 A w3 = (1-wk)*wa
3957 ! | . | | w4 = wk*wa
3958 ! | . | wa
3959 ! | . | |
3960 ! 1-----------2 ja2 V
3961 ! jk2 wk2 jk2p
3962 !
3963 ! <-wk->
3964 !
3965 !-------------------------------------------------------------------------------
3966  nzloc = 0
3967 !
3968 loc: do iloc = 1,nlocus
3969 !
3970  ik2 = floor(wk_k2(iloc))
3971  ia2 = floor(wa_k2(iloc))
3972  wk = wk_k2(iloc)-real(ik2)
3973  wa = wa_k2(iloc)-real(ia2)
3974  w1k2 = (1.-wk)*(1.-wa)
3975  w2k2 = wk*(1.-wa)
3976  w3k2 = (1.-wk)*wa
3977  w4k2 = wk*wa
3978 !
3979  ik4 = floor(wk_k4(iloc))
3980  ia4 = floor(wa_k4(iloc))
3981  wk = wk_k4(iloc)-real(ik4)
3982  wa = wa_k4(iloc)-real(ia4)
3983  w1k4 = (1.-wk)*(1.-wa)
3984  w2k4 = wk*(1.-wa)
3985  w3k4 = (1.-wk)*wa
3986  w4k4 = wk*wa
3987 !
3988 ! Take care of points that lie below lowest wave number
3989 ! when no geometric scaling is applied, then modify weights
3990 ! such that directional position is retained
3991 !
3992  if(iq_geom==0) then
3993  if(ik2 ==0) then
3994  ik2 = 1
3995  w1k2 = w1k2 + w2k2
3996  w2k2 = 0.
3997  w3k2 = w3k2 + w4k2
3998  w4k2 = 0.
3999  end if
4000  if(ik4 ==0) then
4001  ik4 = 1
4002  w1k4 = w1k4 + w2k4
4003  w2k4 = 0.
4004  w3k4 = w3k4 + w4k4
4005  w4k4 = 0.
4006  end if
4007  end if
4008 !
4009 ! compute combined tail factor and product of coupling coefficient, step size,
4010 ! symmetry factor, and tail factor divided by jacobian
4011 !
4012  tfac = wt_k2(iloc)*wt_k4(iloc)
4013  quad_zz(kmem,amem,iloc) = cple_mod(iloc)*ds_mod(iloc)*sym_mod(iloc)/jac_mod(iloc)*tfac
4014 !
4015 !----------------------------------------------------------------------------------------
4016 ! compact data by elimating zero-contribution on locus
4017 !----------------------------------------------------------------------------------------
4018 !
4019  if(iq_compact==1 .and. abs(quad_zz(kmem,amem,iloc)) > 1.e-15) then
4020  nzloc = nzloc + 1
4021  jloc = nzloc
4022  nztot1 = nztot1 + 1
4023  else
4024  jloc = iloc
4025  end if
4026  nztot2 = nztot2 + 1
4027 !
4028 ! shift data
4029 !
4030  quad_zz(kmem,amem,jloc) = quad_zz(kmem,amem,iloc)
4031 !
4032  quad_ik2(kmem,amem,jloc) = ik2 ! lower wave number index of k2
4033  quad_ia2(kmem,amem,jloc) = ia2 ! lower direction index of k2
4034  quad_ik4(kmem,amem,jloc) = ik4 ! lower wave number index of k4
4035  quad_ia4(kmem,amem,jloc) = ia4 ! lower direction index of k4
4036 !
4037  quad_w1k2(kmem,amem,jloc) = w1k2 ! weight 1 of k2
4038  quad_w2k2(kmem,amem,jloc) = w2k2 ! weight 2 of k2
4039  quad_w3k2(kmem,amem,jloc) = w3k2 ! weight 3 of k2
4040  quad_w4k2(kmem,amem,jloc) = w4k2 ! weight 4 of k2
4041 !
4042  quad_w1k4(kmem,amem,jloc) = w1k4 ! weight 1 of k4
4043  quad_w2k4(kmem,amem,jloc) = w2k4 ! weight 2 of k4
4044  quad_w3k4(kmem,amem,jloc) = w3k4 ! weight 3 of k4
4045  quad_w4k4(kmem,amem,jloc) = w4k4 ! weight 4 of k4
4046 !
4047 !
4048  end do loc
4049 !
4050  if(iq_compact==1) then
4051  quad_nloc(kmem,amem) = nzloc ! store compacted number of points on locus
4052  else
4053  quad_nloc(kmem,amem) = nlocus ! store number of points on locus
4054  nzloc = nlocus
4055  end if
4056 !
4057 ! write(luq_prt,'(a,4i5)') 'Q_MAKEGRID kmem amem nlocus:',kmem,amem,nlocus,nzloc
4058 !
4059  end do a3
4060  end do k3
4061 end do k1
4062 !------------------------------------------------------------------------------
4063 ! Write locus information to binary file
4064 !------------------------------------------------------------------------------
4065 !
4066 write(luq_bqf) q_header
4067 !
4068 !------------------------------------------------------------------------------
4069 ! spectral interaction grid
4070 !------------------------------------------------------------------------------
4071 !
4072 write(luq_bqf) naq,nkq
4073 write(luq_bqf) q_sig
4074 write(luq_bqf) q_ad
4076 write(luq_bqf) q_depth
4077 !
4078 !------------------------------------------------------------------------------
4079 ! interaction grid
4080 !------------------------------------------------------------------------------
4081 !
4082 write(luq_bqf) quad_nloc
4083 write(luq_bqf) quad_ik2
4084 write(luq_bqf) quad_ia2
4085 write(luq_bqf) quad_ik4
4086 write(luq_bqf) quad_ia4
4087 write(luq_bqf) quad_w1k2
4088 write(luq_bqf) quad_w2k2
4089 write(luq_bqf) quad_w3k2
4090 write(luq_bqf) quad_w4k2
4091 write(luq_bqf) quad_w1k4
4092 write(luq_bqf) quad_w2k4
4093 write(luq_bqf) quad_w3k4
4094 write(luq_bqf) quad_w4k4
4095 write(luq_bqf) quad_zz
4096 !
4097 !
4098 lwrite = .true.
4100 !
4101 if(iq_screen >= 1 .and. iq_test>=1) write(iscreen,'(2a)') 'q_makegrid: LASTQUADFILE: ',lastquadfile
4102 !
4103 9999 continue
4104 !
4105 if(allocated(xloc)) deallocate(xloc,yloc)
4106 !
4107 ! check if BQF file has been written succesfully
4108 ! if not, deleted both the AQFILE and BQFILE
4109 !
4110 if(.not. lwrite) then
4111  close(luq_bqf,status='delete')
4112  if(iq_log > 0) then
4113  write(luq_log,*)
4114  write(luq_log,*) 'Q_MAKEGRID: Grid files ',trim(aqname),' and ',trim(bqname),' deleted'
4115  write(luq_log,*) 'Q_MAKEGRID: Since an error occurred during the generation'
4116  write(luq_log,*) 'Q_MAKEGRID: of the interaction grid'
4117  end if
4118 end if
4119 !-------------------------------------------------------------------------------
4120 ! write statistics of compacting to print file
4121 !
4122 if(iq_prt >=1) then
4123  if(iq_compact==0) nztot1 = nztot2
4124  write(luq_prt,'(a,i10)') 'Total number of points on loci :',nztot2
4125  write(luq_prt,'(a,i10)') 'Total number of stored points on locus:',nztot1
4126  write(luq_prt,'(a,i10)') 'Total number of zero points on locus :',nztot2-nztot1
4127  write(luq_prt,'(a,f8.2)') 'Reduction factor (%):',real(nztot2-nztot1)/real(nztot2)*100.
4128 end if
4129 !
4130 call q_stack('-q_makegrid')
4131 !
4132 return
4133 end subroutine
4134 !------------------------------------------------------------------------------
4147 
4148 subroutine q_modify
4149 !------------------------------------------------------------------------------
4150 !
4151 ! +-------+ ALKYON Hydraulic Consultancy & Research
4152 ! | | Gerbrant van Vledder
4153 ! | +---+
4154 ! | | +---+ Last update: 11 June 2003
4155 ! +---+ | | Release: 5.0
4156 ! +---+
4157 !
4158 ! do not use m_xnldata
4159 use m_constants
4160 use serv_xnl4v5
4161 implicit none
4162 !--------------------------------------------------------------------------------
4163 ! 0. Update history
4164 !
4165 ! 9/04/1999 Initial version
4166 ! 13/04/1999 New intermediate variables *_mod introduced
4167 ! 11/10/1999 Check on error messages in interpolation added
4168 ! 18/10/1999 Bug fixed in assigning new ds values to array DS_MOD
4169 ! 27/10/1999 Checked added on allocated of SOLD
4170 ! 8/12/1999 Test output added
4171 ! 29/12/1999 Bug fixed in assigning DS_MOD for first and last point on locus
4172 ! 1/10/2001 Components of k4-locus added
4173 ! No interpolation and modification if q==0
4174 ! 9/08/2002 Upgrade to version 4.0
4175 ! 15/08/2002 Step sizing improved
4176 ! 4/06/2003 Bug fixed in computing slen (length of locus)
4177 ! Locus closed to enable interpolation to finer resolution
4178 ! 6/06/2003 Activate output to XDIA configuration file
4179 ! 10/06/2003 Conversion to new indexing and lumping debugged
4180 ! 11/06/2003 Call to subroutine Q_SYMMETRY added
4181 !
4182 ! 1. Purpose:
4183 !
4184 ! Modify points along the locus, such that they are evenly distributed
4185 ! Only when intented, i.e. when IQ_LOCUS==2
4186 !
4187 ! 2. Method
4188 !
4189 ! Compute new spacing along locus
4190 ! Redistribute points and coefficient at new spacing using linear interpolation
4191 ! Output DIA configuration when also lumping active
4192 !
4193 ! If no redistribution is needed, then copy relevant data
4194 !
4195 ! 3. Parameter list:
4196 !
4197 ! Name I/O Type Description
4198 !
4199 ! 4. Error messages
4200 !
4201 ! 5. Called by:
4202 !
4203 ! Q_CMPLOCUS
4204 !
4205 ! 6. Subroutines used
4206 !
4207 ! Q_STACK
4208 ! Q_SYMMETRY
4209 ! Z_INTP1
4210 !
4211 ! 7. Remarks
4212 !
4213 ! 8. structure
4214 !
4215 ! 9. Switches
4216 !
4217 ! 10. Source code
4218 !------------------------------------------------------------------------------
4219 ! Local parameters
4220 !
4221 integer ierr,jerr ! error indicators
4222 integer nold,nnew ! old and new number of points on locus
4223 integer iold,inew ! counter for loop along points
4224 integer iloc ! counter for loop along locus
4225 integer jloc ! counter for loop over lumped locus
4226 integer itest ! local test level, by default equal to IQ_TEST
4227 !
4228 real k2a,k2m ! angle (deg) and wave number magnitude of wave number k2
4229 real k4a,k4m ! angle (deg) and wave number magnitude of wave number k4
4230 real w2,w4 ! radian frequencies of wave numbers
4231 !
4232 !
4233 real dk13,dk14 ! difference wave number
4234 real dsnew,slen ! new step size and length of locus
4235 real zero ! 0
4236 real q_eps ! accuracy to distinguish special case, with q=0
4237 real diold ! 'real' old number of indices between succeeding lumped bins
4238 real dinew ! 'real' new number of indices between succeeding lumped bins
4239 !
4240 !!real x_disper ! evaluate dispersion relation
4241 real, allocatable :: sold(:) ! old coordinate along locus
4242 real, allocatable :: snew(:) ! new coordinate along locus
4243 !--------------------------------------------------------------------------
4244 call q_stack('+q_modify')
4245 !
4246 ! initialisations
4247 !
4248 zero = 0.
4249 q_eps = 1.e-5
4250 itest = iq_test
4251 !
4252 ! itest = 1 ! set local test level for test purposes
4253 !
4254 if(itest>=1) then
4255  write(luq_tst,'(a,i4)') 'Q_MODIFY: iq_mod :',iq_mod
4256  write(luq_tst,'(a,i4)') 'Q_MODIFY: iq_xdia :',iq_xdia
4257  write(luq_tst,'(a,i4)') 'Q_MODIFY: iq_lump :',iq_lump
4258  write(luq_tst,'(a,i4)') 'Q_MODIFY: iq_gauleg:',iq_gauleg
4259 end if
4260 !------------------------------------------------------------------------------
4261 ! do not modify data when IQ_MOD==0
4262 !------------------------------------------------------------------------------
4263 !
4264 if(iq_mod==0) then
4265  nlocus = nlocus1
4266  x2_mod = x2_loc
4267  y2_mod = y2_loc
4268  x4_mod = x4_loc
4269  y4_mod = y4_loc
4270  s_mod = s_loc
4271  ds_mod = ds_loc
4272  jac_mod = jac_loc
4273  cple_mod = cple_loc
4275 else
4276 !------------------------------------------------------------------------------
4277 ! Modify spacing along locus
4278 !------------------------------------------------------------------------------
4279  nold = nlocus1
4280 !
4281 ! close locus by adding one point, equal to first point
4282 ! only for normal locus
4283 !
4284  if(abs(q)>q_eps) nold = nold+1
4285 !
4286 !------------------------------------------------------------------------------
4287 ! Determine new number of points along locus
4288 !------------------------------------------------------------------------------
4289 !
4290  if(iq_gauleg > 0) then
4291  nnew = iq_gauleg
4292  elseif(iq_lump > 0) then
4293  nnew = iq_lump
4294  else
4295  nnew = nlocus0
4296  end if
4297 !
4298 !
4299  allocate (sold(nold),snew(nnew))
4300 !------------------------------------------------------------------------------
4301 ! Compute circumference of locus, distinguish 2 case, open or closed
4302 !------------------------------------------------------------------------------
4303 !
4304  if(abs(q)<q_eps) then
4305  slen = s_loc(nold)
4306  sold = s_loc
4307  else
4308  slen = 0
4309  do iold=1,nold-1 ! loop length minus one, since locus is closed
4310  sold(iold) = s_loc(iold)
4311  slen = slen + ds_loc(iold)
4312  end do
4313 !
4314 !------------------------------------------------------------------------------
4315 ! close locus by copying first value in last value
4316 !------------------------------------------------------------------------------
4317 !
4318  sold(nold) = slen
4319  x2_loc(nold) = x2_loc(1)
4320  y2_loc(nold) = y2_loc(1)
4321  x4_loc(nold) = x4_loc(1)
4322  y4_loc(nold) = y4_loc(1)
4323  jac_loc(nold) = jac_loc(1)
4324  cple_loc(nold) = cple_loc(1)
4325  end if
4326 !
4327 !------------------------------------------------------------------------------
4328 ! compute new spacing along loci and coordinates along locus
4329 ! Gauss-Legendre integration
4330 !------------------------------------------------------------------------------
4331 !
4332  if(iq_gauleg > 0) then
4333  if(iq_gauleg > nnew) stop 'Q_MODIFY: iq_gauleg > nlocus0'
4334  nnew = iq_gauleg
4335  call y_gauleg(zero,slen,snew,ds_mod,nnew)
4336 !
4337  else
4338  if(abs(q)>q_eps) then
4339  dsnew = slen/real(nnew)
4340  do inew=1,nnew
4341  snew(inew) = (inew-1.)*dsnew
4342  end do
4343  else
4344  dsnew = slen/real(nnew-1.)
4345  do inew=1,nnew
4346  snew(inew) = (inew-1)*dsnew
4347  end do
4348  end if
4349  ds_mod = dsnew
4350  end if
4351 !
4352 !
4353  jerr = 0
4354 !------------------------------------------------------------------------------
4355 ! Compute characteristics of locus for special case q=0
4356 !------------------------------------------------------------------------------
4357 !
4358  if(abs(q)<1.e-5) then
4359  call z_intp1(sold,x2_loc,snew,x2_mod,nold,nnew,ierr)
4360  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4361  jerr = jerr + ierr
4362 !
4363  call z_intp1(sold,y2_loc,snew,y2_mod,nold,nnew,ierr)
4364  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4365  jerr = jerr + ierr
4366  !
4367  call z_intp1(sold,x4_loc,snew,x4_mod,nold,nnew,ierr)
4368  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4369  jerr = jerr + ierr
4370 !
4371  call z_intp1(sold,y4_loc,snew,y4_mod,nold,nnew,ierr)
4372  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4373  jerr = jerr + ierr
4374 !
4375  call z_intp1(sold,s_loc,snew,s_mod,nold,nnew,ierr)
4376  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4377  jerr = jerr + ierr
4378 !
4380 !
4381 ! --- lumping along locus --------------------------------------------
4382 !
4383  if(iq_lump>0) then
4384  diold = slen/real(nold)
4385  dinew = slen/real(nnew)
4386  ds_mod = 0.
4388 !
4389  do iloc=1,nlocus1
4390  jloc = floor((iloc-1.)*diold/dinew)+1
4391  ds_mod(jloc) = ds_mod(jloc) + cple_loc(iloc)*ds_loc(iloc)/jac_loc(iloc)*sym_loc(iloc)
4392  jac_mod(jloc) = 1.
4393  cple_mod(jloc) = 1.
4394  end do
4395 !
4396  sym_mod = 1 ! symmetry already taken account in lumping proces
4397 !
4398 ! --- No lumping -------------------------------------------------------------
4399 !
4400  else
4401  call z_intp1(sold,jac_loc,snew,jac_mod,nold,nnew,ierr)
4402  if(ierr > 0) write(luq_err,*) 'Z_INTP1 jac_loc, ierr=',ierr
4403  jerr = jerr + ierr
4404 !
4405  call z_intp1(sold,cple_loc,snew,cple_mod,nold,nnew,ierr)
4406  if(ierr > 0) write(luq_err,*) 'Z_INTP1 cp_loc, ierr=',ierr
4407  jerr = jerr + ierr
4408  end if
4409 !------------------------------------------------------------------------------------------------
4410 ! compute characteristics for closed locus
4411 !------------------------------------------------------------------------------------------------
4412  else
4413  call z_intp1(sold,x2_loc,snew,x2_mod,nold,nnew,ierr)
4414  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4415  jerr = jerr + ierr
4416 !
4417  call z_intp1(sold,y2_loc,snew,y2_mod,nold,nnew,ierr)
4418  if(ierr > 0) write(luq_err,*) 'Z_INTP1 y_loc, ierr=',ierr
4419  jerr = jerr + ierr
4420 !
4421  call z_intp1(sold,x4_loc,snew,x4_mod,nold,nnew,ierr)
4422  if(ierr > 0) write(luq_err,*) 'Z_INTP1 x_loc, ierr=',ierr
4423  jerr = jerr + ierr
4424 !
4425  call z_intp1(sold,y4_loc,snew,y4_mod,nold,nnew,ierr)
4426  if(ierr > 0) write(luq_err,*) 'Z_INTP1 y_loc, ierr=',ierr
4427  jerr = jerr + ierr
4428 !
4429  call z_intp1(sold,s_loc,snew,s_mod,nold,nnew,ierr)
4430  if(ierr > 0) write(luq_err,*) 'Z_INTP1 s_loc, ierr=',ierr
4431  jerr = jerr + ierr
4432 !
4433 !
4435 !
4436 ! ----- Lumping along locus -----------------------------------
4437 !
4438  if(iq_lump>0) then
4439  diold = slen/real(nold-1)
4440  dinew = slen/real(nnew)
4441  ds_mod = 0.
4443 !
4444  do iloc=1,nold-1
4445  jloc = floor((iloc-1.)*diold/dinew + 1.49999)
4446  jloc = mod(jloc-1+nnew,nnew)+1
4447  ds_mod(jloc) = ds_mod(jloc) + cple_loc(iloc)*ds_loc(iloc)/jac_loc(iloc)*sym_loc(iloc)
4448  jac_mod(jloc) = 1.
4449  cple_mod(jloc) = 1.
4450  end do
4451 !
4452  sym_mod = 1 ! symmetry already taken account in lumping proces
4453 !
4454 !------------ No lumping along locus --------------------------------
4455 !
4456  else
4457  call z_intp1(sold,jac_loc,snew,jac_mod,nold,nnew,ierr)
4458  if(ierr > 0) write(luq_err,*) 'Z_INTP1 jac_loc, ierr=',ierr
4459  jerr = jerr + ierr
4460 !
4461  call z_intp1(sold,cple_loc,snew,cple_mod,nold,nnew,ierr)
4462  if(ierr > 0) write(luq_err,*) 'Z_INTP1 cp_loc, ierr=',ierr
4463  jerr = jerr + ierr
4464  end if
4465 !
4466  if(jerr > 0) then
4467  iq_err = iq_err + 1
4468  call q_error('e','INTER','Problem in interpolation process')
4469  goto 9999
4470  end if
4471  end if
4472 !
4473  nlocus = nnew
4474 !
4475 end if
4476 !
4477 !------------------------------------------------------------------------------
4478 !
4479 !
4480 !------------------------------------------------------------------------------
4481 !
4482 !! compute symmetry factor for reducing computational load
4483 !!
4484 !!call q_symmetry(k1x,k1y,k3x,k3y,x4_mod,y4_mod,sym,nnew)
4485 !!
4486 do iloc=1,nlocus
4487  k2x = x2_mod(iloc)
4488  k2y = y2_mod(iloc)
4489  k4x = x4_mod(iloc)
4490  k4y = y4_mod(iloc)
4491 !
4492  k2m = sqrt(k2x**2 + k2y**2)
4493  k4m = sqrt(k4x**2 + k4y**2)
4494  k2a = atan2(k2y,k2x)*rade
4495  k4a = atan2(k4y,k4x)*rade
4496 !
4497  k2m_mod(iloc) = k2m
4498  k4m_mod(iloc) = k4m
4499  k2a_mod(iloc) = k2a
4500  k4a_mod(iloc) = k4a
4501 !
4502 !
4503 !
4504 end do
4505 !
4506 !
4507 9999 continue
4508 !
4509 if(allocated(sold)) deallocate(sold,snew)
4510 !
4511 call q_stack('-q_modify')
4512 !
4513 return
4514 end subroutine
4515 !------------------------------------------------------------------------------
4533 
4534 subroutine q_polar2(kmin,kmax,kx_beg,ky_beg,kx_end,ky_end,loclen,ierr)
4535 !------------------------------------------------------------------------------
4536 !
4537 ! +-------+ ALKYON Hydraulic Consultancy & Research
4538 ! | | Gerbrant van Vledder
4539 ! | +---+
4540 ! | | +---+ Last update: 8 Aug. 2003
4541 ! +---+ | | Release: 5.0
4542 ! +---+
4543 !
4544 ! do not use m_xnldata
4545 use m_constants
4546 use serv_xnl4v5, only: z_wnumb
4547 !
4548 implicit none
4549 !
4550 ! 0. Update history
4551 !
4552 ! Date Description
4553 !
4554 ! 03/12/1999 Initial version
4555 ! 09/08/2002 Geometric spacing of k added
4556 ! Upgrade to release 4.0
4557 ! 13/08/2002 reorganisation of loops generating points on locus
4558 ! 08/08/2003 Check included for maximum number of IPOL by using MPOL
4559 ! MPOL=MLOCUS/2+1-1 (-1 added regarding IPOL=IPOL+1 in Q_MODIFY)
4560 ! Check included on ARG=0 for IQ_LOCUS=2 and parameter dke added
4561 !
4562 ! 1. Purpose:
4563 !
4564 ! Compute position of locus for given k1-k3 vector
4565 !
4566 ! 2. Method
4567 !
4568 ! Explicit polar method, see Van Vledder 2000, Monterey paper
4569 ! Optionally using a fixed k-step, geometric k-step or adaptive stepping
4570 !
4571 ! 3. Parameters used:
4572 !
4573 !Type I/O Name Description
4574 !------------------------------------------------------------------------------
4575 real, intent(in) :: kmin ! minimum wave number on locus
4576 real, intent(in) :: kmax ! maximum wave number on locus
4577 real, intent(in) :: kx_beg ! x-coordinate of begin point
4578 real, intent(in) :: ky_beg ! y-coordinate of begin point
4579 real, intent(in) :: kx_end ! x-coordinate of end point
4580 real, intent(in) :: ky_end ! y-coordinate of end point
4581 real, intent(in) :: loclen ! estimated length of locus
4582 integer, intent (out) :: ierr ! error condition
4583 !
4584 ! Parameters with module
4585 !
4586 ! nlocus0 Preferred number of points on locus
4587 ! q w1-w3, difference of radian frequencies
4588 ! pmag |k1-k3| (vector form)
4589 ! pdir direction of difference vector k1-k3
4590 !
4591 ! 4. Error messages
4592 !
4593 ! 5. Called by:
4594 !
4595 ! Q_CPMLOCUS
4596 !
4597 ! 6. Subroutines used:
4598 !
4599 ! X_COSK
4600 !
4601 ! 7. Remarks
4602 !
4603 ! The type of locus computation is controlled by the parameter IQ_LOCUS
4604 ! Set in Q_SETCFG
4605 !
4606 ! 8. Structure
4607 !
4608 ! 9. Switches
4609 !
4610 ! /S enable subroutine tracing
4611 ! /T enable test output
4612 !
4613 ! 10. Source code
4614 !------------------------------------------------------------------------------
4615 ! Local variabels
4616 !
4617 integer ipol ! counter
4618 integer jpol ! counter
4619 integer iend ! indicates end of locus computation
4620 integer ipass ! counter for passes
4621 integer npol ! number of points on locus
4622 integer npass ! number of passes in iteration process
4623 integer mpol ! maximum number of points on locus, related to MLOCUS
4624 !
4625 real kold ! temporary wave number
4626 real knew ! temporary wave number
4627 real cosold ! 'old' cosine of angle
4628 real cosnew ! 'new' cosine of angle
4629 real dkpol ! step in wave number
4630 real dkold ! 'old' step in wave number
4631 real ang1 ! 'old' angle
4632 real ang2 ! 'new' angle
4633 real kk1 ! 'old' wave number
4634 real kk2 ! 'new' wave number
4635 real kratio ! ratio between succesive k-values when IQ_LOCUS=3
4636 real arg ! argument
4637 real dk ! step in wave number
4638 real dke ! estimate of new dk
4639 real dsnew ! new step size along locus
4640 real dsz ! estimated step size along locus
4641 !
4642 integer itest ! local test level
4643 integer lutest ! unit number for test output in service routine
4644 !
4645 ! function declarations
4646 !!!real z_wnumb ! compute wave number, via module SERV_XNL4V4
4647 !!real x_disper ! dispersion relation
4648 !
4649 !------------------------------------------------------------------------------
4650 ! initialisations
4651 !------------------------------------------------------------------------------
4652 call q_stack('+q_polar2')
4653 !
4654 ierr = 0 ! set error code to zero
4655 npol = (nlocus0+1)/2+1 ! first estimate of number k-values along symmetry axis
4656 mpol = mlocus/2 ! set maximum number of points along locus axis
4657 !
4658 !-------------------------------------------------------------------------------
4659 !
4660 select case(iq_locus)
4661 !------------------------------------------------------------------------------
4662 ! CASE = 1: Linear spacing of wave numbers along symmetry axis
4663 !------------------------------------------------------------------------------
4664  case(1)
4665 !
4666  dk = (kmax-kmin)/real(npol-1)
4667  do ipol=1,npol
4668  k_pol(ipol) = kmin + (ipol-1)*dk
4669  c_pol(ipol) = x_cosk(k_pol(ipol))
4670  end do
4671 !------------------------------------------------------------------------------
4672 ! Case = 2: Variable k-stepping along symmetry axis,
4673 ! such that step along locus is more or less constant
4674 !------------------------------------------------------------------------------
4675  case(2)
4676 !
4677 ! set first point on locus
4678 !
4679  ipol = 1
4680  k_pol(ipol) = kmin
4681  c_pol(ipol) = -1.
4682  kold = kmin
4683  cosold = -1.
4684 !
4685 ! compute initial step size of polar wave number
4686 !
4687  dk0 = (kmax - kmin)/real(npol) ! estimate of step size of equidistant radii
4688  dsz = loclen/real(nlocus0) ! estimate of step size along locus
4689  npass = 3 ! set number of passes in iteration
4690  dk0 = dk0/2 ! reduce initial step
4691  dk = dk0
4692  iend = 0
4693 !
4694 !
4695  do while (k_pol(ipol) < kmax .and. iend==0 .and. ipol < mpol)
4696  do ipass=1,npass
4697  knew = min(kmax,k_pol(ipol)+dk)
4698  dkold = knew - k_pol(ipol)
4699  cosnew = x_cosk(knew)
4700  ang1 = pang + acos(cosold)
4701  ang2 = pang + acos(cosnew)
4702  kk1 = kold
4703  kk2 = knew
4704  arg = kk1**2 + kk2**2 -2.*kk1*kk2*cos(ang1-ang2)
4705  dsnew = sqrt(abs(arg))
4706  if(dsnew>0) dke = dk*dsz/dsnew
4707  dk = dke
4708  end do
4709 !----------------------------------------------------------------------------------------------
4710 ! assign new estimate and check value of IPOL
4711 !----------------------------------------------------------------------------------------------
4712  ipol = ipol + 1
4713  k_pol(ipol) = k_pol(ipol-1) + dkold
4714  c_pol(ipol) = cosnew
4715  kold = knew
4716  cosold = cosnew
4717  if (abs(dkold) < 0.0005*(kmax-kmin)) iend=1
4718  end do
4719 !
4720 ! fill last bin with coordinates of end point
4721 !
4722  if(k_pol(ipol) < kmax .and. ipol < mpol) then
4723  ipol = ipol + 1
4724  c_pol(ipol) = -1.
4725  k_pol(ipol) = kmax
4726  end if
4727 !
4728 ! update the number of k-points on symmetry axis
4729 !
4730  npol = ipol
4731 !
4732 !-------------------------------------------------------------------------------
4733 ! Case 3: Geometric spacing of wave numbers along symmetry axis
4734 !-------------------------------------------------------------------------------
4735  case(3)
4736  kratio = (kmax/kmin)**(1./(npol-1.))
4737  do ipol=1,npol
4738  k_pol(ipol) = kmin*kratio**(ipol-1.)
4739  c_pol(ipol) = x_cosk(k_pol(ipol))
4740  end do
4741 !
4742 end select
4743 !
4744 !------------------------------------------------------------------------------
4745 !
4746 ! compute actual number of points on locus
4747 ! this will always be an even number
4748 ! mirror image the second half of the locus
4749 !
4750 nlocus1 = 2*npol-2
4751 !
4752 a_pol(1) = pang + acos(c_pol(1))
4753 c_pol(1) = cos(a_pol(1))
4754 !
4755 do ipol=2,npol
4756  jpol = 2*npol-ipol
4757  a_pol(ipol) = pang + acos(c_pol(ipol))
4758  a_pol(jpol) = pang - acos(c_pol(ipol))
4759  c_pol(jpol) = cos(a_pol(jpol))
4760  k_pol(jpol) = k_pol(ipol)
4761 end do
4762 !
4763 ! compute x- and y-position along locus
4764 !
4765 do ipol=1,nlocus1
4766  x2_loc(ipol) = k_pol(ipol)*cos(a_pol(ipol))
4767  y2_loc(ipol) = k_pol(ipol)*sin(a_pol(ipol))
4768 end do
4769 !
4770 !
4771 9999 continue
4772 !
4773 call q_stack('-q_polar2')
4774 !
4775 return
4776 end subroutine
4777 !-----------------------------------------------------------------------------------
4793 
4794 subroutine q_setconfig(iquad)
4795 !------------------------------------------------------------------------------
4796 !
4797 ! +-------+ ALKYON Hydraulic Consultancy & Research
4798 ! | | Gerbrant van Vledder
4799 ! | +---+
4800 ! | | +---+ Last update: 16 June 2003
4801 ! +---+ | | Release: 5.0
4802 ! +---+
4803 !
4804 ! do not use m_xnldata
4805 use m_fileio
4806 use serv_xnl4v5
4807 !--------------------------------------------------------------------------------
4808 !
4809 implicit none
4810 
4811 !
4812 ! 0. Update history
4813 !
4814 ! 20/07/1999 Initial version
4815 ! 11/10/1999 Option iq_geom added, consistency checks added
4816 ! 15/10/1999 Option iq_trf added, keyword TRANSF
4817 ! 02/11/1999 Close(LUQCFG) added, implicit none added
4818 ! 08/12/1999 Option IQ_MOD added
4819 ! 24/12/1999 Extra output when *.cfg does not exist, and IQ_PRT=1
4820 ! 08/02/2000 Error message included for IQUAD
4821 ! 12/05/2002 Triplet settings added
4822 ! 08/08/2002 Upgrade to release 4
4823 ! 19/08/2002 Inclusion of various test option and interpolation
4824 ! 22/08/2002 Switch to compact data included
4825 ! 09/09/2002 Parameter q_dstep added
4826 ! 11/09/2002 Parameter qf_frac added
4827 ! 26/05/2003 Parameter iq_lump added
4828 ! 04/06/2003 Parameter IQ_INT renamed IQ_INTEG
4829 ! Switch IQ_GAULEG added
4830 ! 11/06/2003 name changed from Q_SETCFG to Q_SETCONFIG
4831 ! Parameter IQ_SPACE removed
4832 ! 13/06/2003 Set test output, from XNL_INIT
4833 ! 16/06/2003 Switch IQ_SYM added
4834 ! 09/09/2003 Variable ID_FACMAX added
4835 !
4836 ! 1. Purpose:
4837 !
4838 ! Set settings for computing the nonlinear interactions
4839 ! set optimal basic settings
4840 ! Set some settings based on the value of IQUAD
4841 !
4842 ! 2. Method
4843 !
4844 ! Based on the value of IQUAD a number of settings are preset
4845 ! In the case the file [qbase].CFG exists, this file
4846 ! is analyzed and possibly some settings are reset
4847 !
4848 ! 3. Parameter list:
4849 !
4850 !Type, I/O Name Description
4851 !--------------------------------------------------------------------------
4852 integer, intent(in) :: iquad ! Indicator for a specific choice of
4853 ! settings for computing the nonlinear
4854 ! interactions
4855 ! 4. Error messages
4856 !
4857 ! 5. Called by:
4858 !
4859 ! XNL_INIT
4860 !
4861 ! 6. Subroutines used
4862 !
4863 ! 7. Remarks
4864 !
4865 ! IF no valid value for iquad is given, a default choice is
4866 ! specified
4867 !
4868 ! The various options of the setting are specified in the general quads module
4869 !
4870 ! 8. Structure
4871 !
4872 ! 9. Switches
4873 !
4874 ! /S Enable subroutine tracing
4875 !
4876 ! 10. Source code
4877 !--------------------------------------------------------------------------------
4878 ! Local variables
4879 !
4880 integer iend ! indicator for end of file
4881 integer iuerr ! error status of file io
4882 character(len=10) cpar ! character parameter
4883 real rpar ! real parameter
4884 !--------------------------------------------------------------------------------
4885 !
4886 call q_stack('+q_setconfig')
4887 !--------------------------------------------------------------------------------
4888 ! default settings, which always work
4889 !--------------------------------------------------------------------------------
4890 nlocus0 = 30 ! Preferred number of points along locus
4891 id_facmax = 2 ! Factor for depth search in Q_SEARCHGRID
4892 iq_filt = 1 ! switch filtering on
4893 iq_gauleg = 0 ! No Gauss-Legendre interpolation
4894 iq_locus = 2 ! polar method, constant step with adaptive stepping
4895 iq_lump = 0 ! lumping disabled
4896 iq_make = 1 ! make grid at each new run
4897 iq_mod = 1 ! Modify spacing to equidistant spacing of points along locus
4898 iq_compact = 1 ! Do not (yet) compact data along locus
4899 iq_interp = 1 ! bi-linear interpolation
4900 iq_lump = 0 ! no lumping of coefficient along locus
4901 iq_search = 0 ! No search is carried out for nearest quad grid
4902 iq_sym = 1 ! Activate symmetry reduction
4903 !--------------------------------------------------------------------------------
4904 ! set settings for special or test purposes
4905 !--------------------------------------------------------------------------------
4906 iq_trf = 0 ! No output of transformed loci
4907 iq_t13 = 0 ! No test output of T13 integration
4908 !-------------------------------------------------------------------------------
4909 ! set filtering values for retricting integration space
4910 !-------------------------------------------------------------------------------
4911 qf_krat = 2.5 ! maximum ratio between wave numbers k1 and k3
4912 qf_dmax = 75.0 ! difference in degrees between k1 and k3
4913 qf_frac = 0.1 ! fraction of maximum energy density
4914 !
4915 q_sector = 120. ! set size of half-plane direction sector (120)
4916 !------------------------------------------------------------------------------
4917 !
4918 ! Set specific parameter depending on IQUAD
4919 !
4920 !------------------------------------------------------------------------------
4921 ! deep water test version
4922 !
4923 if(iquad==1) then
4924  iq_geom = 0 ! apply geometric scaling (Geometric scaling is disabled)
4925  iq_dscale = 0 ! no depth scaling
4926  iq_disp = 1 ! deep water
4927  iq_cple = 1 ! Webb's coupling coefficient
4928 !
4929 ! 'deep' water computation and HH/WAM depth scaling
4930 !
4931 elseif(iquad==2) then
4932  iq_geom = 0 ! apply geometric scaling
4933  iq_dscale = 1 ! put depth scaling on
4934  iq_disp = 1 ! deep water
4935  iq_cple = 1 ! Webb's coupling coefficient
4936 !
4937 ! full finite depth computation of interactions
4938 !
4939 elseif(iquad==3) then
4940  iq_dscale = 0 ! no depth scaling
4941  iq_disp = 2 ! finite depth dispersion relation
4942  iq_geom = 0 ! no geometric scaling
4943  iq_cple = 2 ! finite depth coupling coefficient of H&H
4944 else
4945  if(iq_screen>0) write(iscreen,'(a,i4)') 'Q_SETCONFIG: iquad=',iquad
4946  call q_error('e','IQUAD','No valid value of iquad has been given, default settings')
4947  write(luq_err,'(a,i4)') 'Q_SETCONFIG: Value of IQUAD:',iquad
4948  goto 9999
4949 end if
4950 !-------------------------------------------------------------------------------------------------
4951 !
4952 !----------------------------------------------------------------------------------
4953 ! check if the configuration exists,
4954 ! and if so, override the settings
4955 !----------------------------------------------------------------------------------
4956 !
4957 call z_fileio(trim(qbase)//'.cfg','OF',iufind,luq_cfg,iuerr)
4958 if(luq_cfg > 0) then
4959  if(iq_log >= 1) then
4960  write(luq_log,*)
4961  write(luq_log,'(a)') 'Q_SETCONFIG: Configuration file '//trim(qbase)//'.cfg has been found'
4962  write(luq_log,'(a,i4)') 'Q_SETCONFIG: '//trim(qbase)//'.cfg connected to :',luq_cfg
4963  end if
4964 !
4965  iend = 0
4966 !
4967  do while (iend==0)
4968  read(luq_cfg,*,iostat=iend) cpar,rpar
4969 !
4970  call z_upper(cpar) ! Convert string to upper case
4971 !
4972  if(iend==0) then ! process the command
4973 !
4974  if(trim(cpar)=='DEPTH') q_depth = rpar
4975  if(trim(cpar)=='DSTEP') q_dstep = rpar
4976  if(trim(cpar)=='F_DMAX') qf_dmax = rpar
4977  if(trim(cpar)=='F_KRAT') qf_krat = rpar
4978  if(trim(cpar)=='F_FRAC') qf_frac = rpar
4979  if(trim(cpar)=='FMIN') fqmin = rpar
4980  if(trim(cpar)=='FMAX') fqmax = rpar
4981  if(trim(cpar)=='NLOCUS') nlocus0 = int(rpar)
4982  if(trim(cpar)=='SECTOR') q_sector = rpar
4983 !
4984  if(trim(cpar)=='GEOM') then
4985  iq_geom = int(rpar)
4986  if(iq_geom==1) then
4987  iq_geom=0
4988  if(iq_screen>0) write(iscreen,'(a)') 'Q_SETCONFIG: geometric scaling disabled'
4989  if(iq_prt>=1) write(luq_prt,'(a)') 'Q_SETCONFIG: geometric scaling disabled'
4990  end if
4991  end if
4992  if(trim(cpar)=='COMPACT') iq_compact = int(rpar)
4993  if(trim(cpar)=='COUPLING') iq_cple = int(rpar)
4994  if(trim(cpar)=='DISPER') iq_disp = int(rpar)
4995  if(trim(cpar)=='FILT') iq_filt = int(rpar)
4996  if(trim(cpar)=='GAULEG') iq_gauleg = int(rpar)
4997  if(trim(cpar)=='GRID') iq_grid = int(rpar)
4998  if(trim(cpar)=='INTEG') iq_integ = int(rpar)
4999  if(trim(cpar)=='INTERP') iq_interp = int(rpar)
5000  if(trim(cpar)=='LOCUS') iq_locus = int(rpar)
5001  if(trim(cpar)=='LOGGING') iq_log = int(rpar)
5002  if(trim(cpar)=='LUMPING') iq_lump = int(rpar)
5003  if(trim(cpar)=='MAKE') iq_make = int(rpar)
5004  if(trim(cpar)=='MODIFY') iq_mod = int(rpar)
5005  if(trim(cpar)=='PRINT') iq_prt = int(rpar)
5006  if(trim(cpar)=='PRINT') iq_prt = int(rpar)
5007  if(trim(cpar)=='SCREEN') iq_screen = int(rpar)
5008  if(trim(cpar)=='SEARCH') iq_search = int(rpar)
5009  if(trim(cpar)=='SYM') iq_sym = int(rpar)
5010  if(trim(cpar)=='T13') iq_t13 = int(rpar)
5011  if(trim(cpar)=='TEST') iq_test = int(rpar)
5012  if(trim(cpar)=='TRACE') iq_trace = int(rpar)
5013  if(trim(cpar)=='TRANSF') iq_trf = int(rpar)
5014  if(trim(cpar)=='XDIA') iq_xdia = int(rpar)
5015  end if
5016  end do
5017 !
5018  close(luq_cfg)
5019 !
5020  if(iq_log >= 1) write(luq_log,'(a,i4)') &
5021 & 'Q_SETCONFIG: '//trim(qbase)//'.cfg disconnected from :',luq_cfg
5022 !
5023 else
5024 ! iq_prt = 1
5025  if(iq_log >= 1) then
5026  write(luq_log,*)
5027  write(luq_log,'(a)') 'Q_SETCONFIG: Configuration file '//trim(qbase)//'.CFG has not been found'
5028  end if
5029 end if
5030 !
5031 9999 continue
5032 !
5033 call q_stack('-q_setconfig')
5034 !
5035 return
5036 end subroutine
5037 !------------------------------------------------------------------------------
5049 
5050 subroutine q_searchgrid(depth,igrid)
5051 !------------------------------------------------------------------------------
5052 !
5053 ! +-------+ ALKYON Hydraulic Consultancy & Research
5054 ! | | Gerbrant van Vledder
5055 ! | +---+
5056 ! | | +---+ Last update: 9 September 2003
5057 ! +---+ | | Release: 5.03
5058 ! +---+
5059 !
5060 ! do not use m_xnldata
5061 implicit none
5062 !------------------------------------------------------------------------------
5063 ! 0. Update history
5064 !
5065 ! Version Date Modification
5066 !
5067 ! 20/08/2002 Initial version
5068 ! 29/08/2002 Write statements made conditionsl
5069 ! 5/09/2003 Search algorithm improved
5070 ! 09/09/2003 factor ID_FACMAX introduced and extra test output created
5071 ! Input water depth saved for output
5072 !
5073 ! 1. Purpose:
5074 !
5075 ! Search nearest valid grid, read grid file and scale factor
5076 !
5077 ! 2. Method
5078 !
5079 ! Using the actual water depth
5080 ! all possible interaction grids are checked
5081 ! in upward and downward direction
5082 !
5083 ! 3. Parameters used
5084 !
5085 real, intent(in) :: depth ! depth for which grid file must be found
5086 integer, intent(out) :: igrid ! status of grid checking
5087 ! ==0: a proper grid exists
5088 ! ==1: grid file does not exist
5089 ! ==2: grid file exists, but it is incorrect
5090 ! ==3: read error in accessing grid information
5091 !
5092 ! 4. Error messages
5093 !
5094 ! 5. Called by:
5095 !
5096 ! Q_XNL4V4
5097 !
5098 ! 6. Subroutines used
5099 !
5100 ! Q_CTRGRID
5101 ! Q_STACK
5102 !
5103 ! 7. Remarks
5104 !
5105 !
5106 ! 8. Structure
5107 !
5108 !
5109 ! 9. Switches
5110 !
5111 ! 10. Source code
5112 !---------------------------------------------------------------------------
5113 ! Local variables
5114 !
5115 integer id ! counter
5116 integer idepth ! integer depth
5117 integer id_upper ! upper limit of search
5118 integer id_lower ! lower limit of depth search
5119 !
5120 real d_lower ! lower valid depth
5121 real d_upper ! upper valid depth
5122 real r_lower ! ratio with lower valid depth
5123 real r_upper ! ratio with upper valid depth
5124 real s_depth ! target depth in m, saved in this variable
5125 real dfac1,dfac2 ! depth scale factors
5126 real eps ! accuracy
5127 !------------------------------------------------------------------------------
5128 !
5129 call q_stack('+q_searchgrid')
5130 !
5131 eps = 0.0001
5132 !
5133 !------------------------------------------------------------------------------
5134 ! check if a depth exists for current grid
5135 !------------------------------------------------------------------------------
5136 !
5137 !
5138 q_depth = depth + eps
5139 
5140 call q_ctrgrid(1,igrid)
5141 !
5142 !
5143 if(igrid==0) then
5144  if(iq_screen>=1) write(iscreen,'(a)') 'Q_SEARCHGRID: grid accepted, read whole database'
5145 !
5146  call q_ctrgrid(2,igrid)
5147  goto 9999
5148 end if
5149 !
5150 ! save depth for which nearest grid file is to be found
5151 !
5152 s_depth = depth
5153 idepth = int(s_depth*10+eps)
5154 id_lower = int(q_mindepth*10+eps)
5155 id_upper = int(q_maxdepth*10+eps)
5156 !
5157 id_upper = min(id_facmax*idepth,id_upper)
5158 !
5159 ! set 'not found' condition
5160 !
5161 d_lower = -1.
5162 d_upper = -1.
5163 !
5164 !------------------------------------------------------------------------------
5165 ! search downwards until a valid grid is found
5166 !------------------------------------------------------------------------------
5167 !
5168 do id = idepth-1,id_lower,-1
5169  q_depth = real(id)/10.+eps
5170 
5171  call q_ctrgrid(1,igrid)
5172 
5173 
5174  if(igrid==0) then
5175  d_lower = q_depth
5176  exit
5177  end if
5178 end do
5179 !
5180 !------------------------------------------------------------------------------
5181 ! seach upwards until a valid grid is found
5182 !------------------------------------------------------------------------------
5183 !
5184 do id = idepth+1,id_upper
5185  q_depth = real(id)/10.+eps
5186 
5187 
5188  call q_ctrgrid(1,igrid)
5189 
5190 
5191  if(igrid==0) then
5192  d_upper = q_depth
5193  exit
5194  end if
5195 end do
5196 if(iq_prt>=1) write(luq_prt,*)
5197 !------------------------------------------------------------------------------
5198 !
5199 ! determine nearest grid
5200 !------------------------------------------------------------------------------
5201 !
5202 if(d_lower > 0) then
5203  r_lower = s_depth/d_lower
5204 else
5205  r_lower = -1.
5206 end if
5207 !
5208 if(d_upper > 0) then
5209  r_upper = d_upper/s_depth
5210 else
5211  r_upper = -1.
5212 end if
5213 !
5214 if(iq_prt>=1) then
5215  write(luq_prt,'(a,3f8.2)') 'Q_SEARCHGRID: d_lower d_target d_upper :',d_lower,s_depth,d_upper
5216  write(luq_prt,'(a,2f8.2)') 'Q_SEARCHGRID: r_lower r_upper :',r_lower,r_upper
5217 end if
5218 !------------------------------------------------------------------------------
5219 ! select nearest valid grid
5220 !------------------------------------------------------------------------------
5221 if(r_lower>0 .and. r_upper>0) then
5222  if(r_lower < r_upper) then
5223  q_depth = d_lower
5224  else
5225  q_depth = d_upper
5226  end if
5227 !
5228 elseif(r_lower > 0 .and. r_upper <0 ) then
5229  q_depth = d_lower
5230 elseif(r_lower < 0 .and. r_upper > 0) then
5231  q_depth = d_upper
5232 else
5233  call q_error('e','SEARCHGRID','No valid nearest grid could be found')
5234  goto 9999
5235 end if
5236 !
5237 !-----------------------------------------------------------------------------------------------
5238 ! compute depth scaling factors
5239 !------------------------------------------------------------------------------
5240 !
5241 call q_dscale(a,q_sig,q_a,nkq,naq,s_depth,q_grav,dfac1)
5242 call q_dscale(a,q_sig,q_a,nkq,naq,q_depth,q_grav,dfac2)
5243 !
5244 q_scale = dfac1/dfac2
5245 !
5246 if(iq_prt>=1) then
5247  write(luq_prt,'(a,2f8.4)') 'Q_SEARCHGRID: target and nearest scale factors:',dfac1,dfac2
5248  write(luq_prt,'(a,f8.4)') 'Q_SEARCHGRID: compound scale factor :',q_scale
5249 end if
5250 !
5251 ! Read BQF for nearest valid water depth
5252 !
5253 call q_ctrgrid(2,igrid)
5254 if(iq_prt>=2) then
5255  write(luq_prt,'(a,f12.2)') 'Q_SEARCHGRID: Q_CTRGRID called with depth:',q_depth
5256  write(luq_prt,'(a,i4)') 'Q_SEARCHGRID: igrid of nearest grid operation:',igrid
5257 end if
5258 !
5259 9999 continue
5260 !
5261 ! restore water depth
5262 !
5263 q_depth = s_depth
5264 !
5265 call q_stack('-q_searchgrid')
5266 !
5267 return
5268 end subroutine
5269 !-----------------------------------------------------------------
5277 
5278 subroutine q_setversion
5279 !-----------------------------------------------------------------
5280 ! do not use m_xnldata
5281 !-----------------------------------------------------------------
5282 ! This subroutine has automatically been written by MODULE5
5283 ! Author: Gerbrant van Vledder
5284 !
5285 q_version ='GurboQuad Version: 5.03 Build: 59 Date: 2003/09/15 [S]'
5286 !
5287 ! Source code options:S
5288 !
5289 return
5290 end subroutine
5291 !------------------------------------------------------------------------------
5308 
5309 subroutine q_stack(mod_name)
5310 !------------------------------------------------------------------------------
5311 !
5312 ! +-------+ ALKYON Hydraulic Consultancy & Research
5313 ! | | Gerbrant van Vledder
5314 ! | +---+
5315 ! | | +---+ Last update: 11 June 2003
5316 ! +---+ | | Release: 5
5317 ! +---+
5318 !
5319 ! do not use m_xnldata
5320 use m_fileio
5321 implicit none
5322 !
5323 !
5324 ! 0. Update history
5325 !
5326 ! 20/07/1999 Initial version
5327 ! 13/10/1999 Error handling improved
5328 ! 08/08/2002 Upgrade to release 4
5329 ! 11/06/2003 Extra check on output to print or test file
5330 !
5331 ! 1. Purpose:
5332 !
5333 ! Add or remove mod_name name from module stack
5334 !
5335 ! 2. Method
5336 !
5337 ! mod_name must be preceeded by a '+' , '-'
5338 ! The module name is pushed to the stack when preceeded by '+'
5339 ! and removed if mname starts with '-'.
5340 ! In case an error is active,the module name is not removed
5341 ! from the stack if mname starts with a '-'.The module is
5342 ! always removed from the stack if mname starts with '!'.
5343 !
5344 !
5345 ! 3. Parameter list:
5346 !
5347 !Type I/O name description
5348 !-------------------------------------------------------
5349 character(len=*), intent(in) :: mod_name ! module name
5350 !
5351 ! 4. Error messages
5352 !
5353 ! 5. Called by
5354 !
5355 ! All q_** routines
5356 !
5357 ! 6. Subroutines used
5358 !
5359 ! q_error
5360 !
5361 ! 7. Remarks
5362 !
5363 ! 8. Structure
5364 !
5365 ! 9. Switches
5366 !
5367 ! 10. Source code
5368 !-------------------------------------------------------------------------------------
5369 character(len=1) mod_task ! task to do
5370 integer mod_len ! length of mod_name
5371 !
5372 !!\A
5373 if(iq_trace > 0) then
5374  if(iq_prt>0) write(luq_prt,'(2a)') 'TRACE -> ',trim(mod_name)
5375  if(iq_test>0) write(luq_tst,'(2a)') 'TRACE -> ',trim(mod_name)
5376  if(iq_screen >= 2) write(iscreen,'(2a)') 'TRACE -> ',trim(mod_name)
5377 end if
5378 !
5379 ! split MOD_NAME in two parts
5380 !
5381 ! MOD_TASK '+','-'
5382 !
5383 mod_len = len_trim(mod_name)
5384 mod_task = mod_name(1:1)
5385 sub_name = mod_name(2:mod_len)
5386 !
5387 if(mod_task(1:1) == '+') then
5388  iq_stack = iq_stack + 1
5389 !
5390  if(iq_stack > mq_stack) then
5391  call q_error('e','STACKMAX',' ')
5392  goto 9999
5393  else
5394  cstack(iq_stack) = mod_name(2:mod_len)
5395  end if
5396 !------------------------------------------------------------------------
5397 ! remove name from stack
5398 !------------------------------------------------------------------------
5399 elseif(mod_task(1:1) == '-') then
5400 !
5401  if(mod_name(2:mod_len) == cstack(iq_stack)) then
5402  iq_stack = iq_stack - 1
5403  else
5404  write(luq_err,'(a)') 'Module name:',mod_name
5405  call q_error('e','STACKNAME',' ')
5406  goto 9999
5407  end if
5408 else
5409  call q_error('e','STACKCALL',' ')
5410  goto 9999
5411 end if
5412 !
5413 !!\Z
5414 !
5415 9999 continue
5416 !
5417 return
5418 end subroutine
5419 !------------------------------------------------------------------------------
5429 
5430 subroutine q_summary
5431 !------------------------------------------------------------------------------
5432 !
5433 ! +-------+ ALKYON Hydraulic Consultancy & Research
5434 ! | | Gerbrant van Vledder
5435 ! | +---+
5436 ! | | +---+ Last update: 16 June 2003
5437 ! +---+ | | Release: 5.0
5438 ! +---+
5439 !
5440 ! do not use m_xnldata
5441 use m_fileio
5442 use serv_xnl4v5
5443 !--------------------------------------------------------------------------------
5444 !
5445 implicit none
5446 
5447 !
5448 ! 0. Update history
5449 !
5450 ! 11/06/2003 Initial version
5451 ! Parameter iq_space removed
5452 ! 16/06/2003 Switch IQ_SYM added
5453 !
5454 ! 1. Purpose:
5455 !
5456 ! Write summary of GurboQuad settings to print file
5457 !
5458 ! 2. Method
5459 !
5460 ! Based on the value of IQUAD a number of settings are preset
5461 ! In the case the file [qbase].CFG exists, this file
5462 ! is analyzed and possibly some settings are reset
5463 !
5464 ! 3. Parameter list:
5465 !
5466 !Type, I/O Name Description
5467 !--------------------------------------------------------------------------
5468 !
5469 ! 4. Error messages
5470 !
5471 ! 5. Called by:
5472 !
5473 ! XNL_INIT
5474 !
5475 ! 6. Subroutines used
5476 !
5477 ! 7. Remarks
5478 !
5479 ! 8. Structure
5480 !
5481 ! 9. Switches
5482 !
5483 ! /S Enable subroutine tracing
5484 !
5485 ! 10. Source code
5486 !--------------------------------------------------------------------------------
5487 ! Local variables
5488 !
5489 !--------------------------------------------------------------------------------
5490 !
5491 call q_stack('+q_summary')
5492 !--------------------------------------------------------------------------------
5493 !-----------------------------------------------------------------------------------------------------
5494 ! write summary of settings for computation of quadruplets
5495 ! to print file
5496 !
5497 if (iq_prt > 0) then
5498  write(luq_prt,*)
5499  write(luq_prt,'(a)') 'Summary of settings for QUAD computation'
5500  write(luq_prt,'(a)') '------------------------------------------------'
5501  write(luq_prt,'(a,i4)') 'Number of wave numbers :',nkq
5502  write(luq_prt,'(a,i4)') 'Number of directions :',naq
5503  write(luq_prt,'(a,f10.5)') 'Minimum frequency (Hz) :',fqmin
5504  write(luq_prt,'(a,f10.5)') 'Maximum frequency (Hz) :',fqmax
5505  write(luq_prt,'(a,f10.2)') 'Water depth (m) :',q_depth
5506  write(luq_prt,'(a,i4)') 'Preferred number of locus points:',nlocus0
5507 !
5508  write(luq_prt,*)
5509  write(luq_prt,'(a,f10.3)') 'Gravitational acceleration:',q_grav
5510 ! write(luq_prt,'(a,f10.3)') 'Density of water :',q_rhow
5511 ! write(luq_prt,'(a,f10.2)') 'Power spectral tail E(f) :',qf_tail
5512 ! write(luq_prt,'(a,f10.2)') 'Power spectral tail N(k) :',qk_tail
5513 !
5514  write(luq_prt,*)
5515  if(iq_type==1) write(luq_prt,'(a)') 'IQUAD = 1: Deep water'
5516  if(iq_type==2) write(luq_prt,'(a)') 'IQUAD = 2: Deep water & WAM depth scaling'
5517  if(iq_type==3) write(luq_prt,'(a)') 'IQUAD = 3: Direct finite depth calculation'
5518  write(luq_prt,*)
5519 !
5520  write(luq_prt,'(a,f5.2)') 'Step size in m of BQF coding:',q_dstep
5521  write(luq_prt,*)
5522 !
5523  if(iq_grid==1) write(luq_prt,'(a)') 'Symmetric sector grid'
5524  if(iq_grid==2) write(luq_prt,'(a)') 'Non-symmetric sector grid'
5525  if(iq_grid==3) write(luq_prt,'(a)') 'Non-symmetric full circle grid'
5526 !
5527  write(luq_prt,*)
5528  if(iq_compact==0) write(luq_prt,'(a)') 'No compacting of data along locus'
5529  if(iq_compact==1) write(luq_prt,'(a)') 'Compact data along locus by eliminating zero contributions'
5530 !
5531  write(luq_prt,*)
5532  if(iq_dscale==0) write(luq_prt,'(a)') 'No WAM depth scaling'
5533  if(iq_dscale==1) write(luq_prt,'(a)') 'WAM depth scaling of transfer'
5534 !
5535  write(luq_prt,*)
5536  if(iq_screen==0) write(luq_prt,'(a)') 'No output to screen'
5537  if(iq_screen>=1) write(luq_prt,'(a)') 'Intermediate output to screen'
5538  if(iq_screen>=2) write(luq_prt,'(a)') 'Intermediate output to screen + subroutine tracing'
5539  write(luq_prt,*)
5540 !
5541  write(luq_prt,*)
5542  if(iq_search==0) write(luq_prt,'(a)') 'No search is carried out for nearest QUAD grid'
5543  if(iq_search==1) write(luq_prt,'(a)') 'A search is carried out for nearest QUAD grid'
5544 !
5545  write(luq_prt,*)
5546  if(iq_gauleg==0) write(luq_prt,'(a)') 'Rectangular integration'
5547  if(iq_gauleg>0) write(luq_prt,'(a,i4)') 'Gauss-Legendre integration with N=',iq_gauleg
5548 !
5549  write(luq_prt,*)
5550  if(iq_cple==1) write(luq_prt,'(a)') 'Deep water coupling coefficient of Webb'
5551  if(iq_cple==2) write(luq_prt,'(a)') 'Finite depth coupling coefficient of H&H'
5552  if(iq_cple==3) write(luq_prt,'(a)') 'Finite depth coupling coefficient of Gorman'
5553  if(iq_cple==4) write(luq_prt,'(a)') 'Deep water coefficient of Zakharov'
5554  if(iq_cple==5) write(luq_prt,'(a)') 'Finite depth coefficient of Zakharov'
5555 !
5556  write(luq_prt,*)
5557  if(iq_disp==1) write(luq_prt,'(a)') 'Deep water dispersion relation'
5558  if(iq_disp==2) write(luq_prt,'(a)') 'Finite depth linear dispersion relation'
5559  if(iq_disp==3) write(luq_prt,'(a)') 'Non linear finite depth dispersion'
5560 !
5561  write(luq_prt,*)
5562  if(iq_filt==0) write(luq_prt,'(a)') 'Filtering of quadruplets off'
5563  if(iq_filt==1) then
5564  write(luq_prt,'(a)') 'Filtering of quadruplets on'
5565  write(luq_prt,*)
5566  write(luq_prt,'(a,f8.2)') 'Maximum ratio of k1 and k3 :',qf_krat
5567  write(luq_prt,'(a,f8.2)') 'Maximum directional difference :',qf_dmax
5568  write(luq_prt,'(a,e12.3)') 'Fraction of maximum energy density:',qf_frac
5569  end if
5570 !
5571 ! write(luq_prt,*)
5572 ! if(iq_geom==0) write(luq_prt,'(a)') 'Only directional scaling of loci'
5573 ! if(iq_geom==1) write(luq_prt,'(a)') 'Geometric scaling of loci using R-T method'
5574 !
5575  write(luq_prt,*)
5576  if(iq_locus==1) write(luq_prt,'(a)') 'Compute locus with polar method with fixed k-step'
5577  if(iq_locus==2) write(luq_prt,'(a)') 'Compute locus with polar method using adaptive k-step'
5578  if(iq_locus==3) write(luq_prt,'(a)') 'Compute locus with polar method using geometric k-step'
5579 !
5580  write(luq_prt,*)
5581  if(iq_sym==0) write(luq_prt,'(a)') 'Handling of symmetries disabled'
5582  if(iq_sym==1) write(luq_prt,'(a)') 'Handling of symmetries enabled'
5583 !
5584  write(luq_prt,*)
5585  if(iq_make==1) write(luq_prt,'(a)') 'Make quadruplet grid when necessary'
5586  if(iq_make==2) write(luq_prt,'(a)') 'Always make quadruplet grid'
5587  if(iq_make==3) write(luq_prt,'(a)') 'Stop after generation of quadruplet grid'
5588 !
5589  write(luq_prt,*)
5590  if(iq_interp==1) write(luq_prt,'(a)') 'Apply bi-linear interpotion to retrieve action density'
5591  if(iq_interp==2) write(luq_prt,'(a)') 'Take nearest bin to retrieve action density'
5592 !
5593  write(luq_prt,*)
5594  if(iq_lump==0) write(luq_prt,'(a)') 'Lumping of coefficients along locus disabled'
5595  if(iq_lump>0) write(luq_prt,'(a)') 'Lumping of coefficients along locus enabled'
5596 !
5597  write(luq_prt,*)
5598  if(iq_mod==0) write(luq_prt,'(a)') '?X? Spacing of point along locus as initially computed'
5599  if(iq_mod==1) write(luq_prt,'(a)') 'Equidistant spacing of points along locus'
5600 !
5601  write(luq_prt,*)
5602  if(iq_trace==0) write(luq_prt,'(a)') 'Subroutine tracing disabled'
5603  if(iq_trace>0) write(luq_prt,'(a)') 'Subroutine tracing enabled'
5604 !
5605 !
5606 !
5607 !
5608  write(luq_prt,*)
5609 !
5610 ! if(iq_disp==1 .and. iq_start==2) then
5611 ! write(luqprt,'(a)') 'Start point for locus according to Resio&Tracy'
5612 ! else
5613 ! write(luqprt,'(a)') 'Start point for locus equal to k3'
5614 ! end if
5615  write(luq_prt,*)
5616  write(luq_prt,'(a,i4)') 'Level of printed output :',iq_prt
5617  write(luq_prt,'(a,i4)') 'Level of logging output :',iq_log
5618  write(luq_prt,'(a,i4)') 'Level of test output :',iq_test
5619  write(luq_prt,'(a,i4)') 'Level of trace output :',iq_trace
5620  write(luq_prt,'(a,i4)') 'Level of transformation output :',iq_trf
5621  write(luq_prt,'(a)') '----------------------------------------------'
5622 end if
5623 !
5624 9999 continue
5625 !
5626 call q_stack('-q_summary')
5627 !
5628 return
5629 end subroutine
5630 !------------------------------------------------------------------------------
5647 
5648 subroutine q_symmetry(k1x,k1y,k3x,k3y,k4x,k4y,symfac,nloc)
5649 !------------------------------------------------------------------------------
5650 !
5651 ! +-------+ ALKYON Hydraulic Consultancy & Research
5652 ! | | Gerbrant van Vledder
5653 ! | +---+
5654 ! | | +---+ Last update: 16 June 2003
5655 ! +---+ | | Release: 5.0
5656 ! +---+
5657 !
5658 implicit none
5659 !--------------------------------------------------------------------------------
5660 ! 0. Update history
5661 !
5662 ! 10/06/2003 Initial version
5663 ! 16/06/2003 Switch iq_sym added
5664 !
5665 ! 1. Purpose:
5666 !
5667 ! Compute symmetry factor to reduce integration
5668 !
5669 ! 2. Method
5670 !
5671 ! Compute distance between k1 and k3, and between k4 and k1
5672 !
5673 ! 3. Parameter list:
5674 !
5675 ! Type i/o Name Description
5676 !----------------------------------------------------------------------------------
5677 integer, intent(in) :: nloc ! number of points in array with wave number
5678 real, intent(in) :: k1x ! x-component of wave number k1
5679 real, intent(in) :: k1y ! y-component of wave number k1
5680 real, intent(in) :: k3x ! x-component of wave number k3
5681 real, intent(in) :: k3y ! y-component of wave number k3
5682 real, intent(in) :: k4x(nloc) ! x-components of wave number k4
5683 real, intent(in) :: k4y(nloc) ! y-components of wave number k4
5684 real, intent(out) :: symfac(nloc) ! symmetry factor
5685 !----------------------------------------------------------------------------------
5686 ! 4. Error messages
5687 !
5688 ! 5. Called by:
5689 !
5690 ! Q_MODIFY
5691 !
5692 ! 6. Subroutines used
5693 !
5694 ! Q_STACK
5695 !
5696 ! 7. Remarks
5697 !
5698 ! 8. structure
5699 !
5700 ! 9. Switches
5701 !
5702 ! 10. Source code
5703 !------------------------------------------------------------------------------
5704 integer iloc ! counter
5705 real dk13 ! distance between k1 and k3
5706 real dk14 ! distance between k1 and k4
5707 !------------------------------------------------------------------------------
5708 !
5709 call q_stack('+q_symmetry')
5710 !
5711 !
5712 ! evaluate criterion |k3-k1| < |k4-k1|
5713 ! if true then symfac=1
5714 !
5715 symfac = 1.
5716 if(iq_sym==1) then
5717  dk13 = (k1x-k3x)**2 + (k1y-k3y)**2
5718  do iloc=1,nloc
5719  dk14 = (k1x-k4x(iloc))**2 + (k1y-k4y(iloc))**2
5720  if (dk13 >= dk14) symfac(iloc) = 0.
5721  end do
5722 end if
5723 !
5724 call q_stack('-q_symmetry')
5725 !
5726 return
5727 end subroutine
5728 !------------------------------------------------------------------------------
5744 
5745 subroutine q_t13v4(ik1,ia1,ik3,ia3,t13,diagk1,diagk3)
5746 !------------------------------------------------------------------------------
5747 !
5748 ! +-------+ ALKYON Hydraulic Consultancy & Research
5749 ! | | Gerbrant van Vledder
5750 ! | +---+
5751 ! | | +---+ Last update: 5 September 2003
5752 ! +---+ | | Release: 5.0
5753 ! +---+
5754 !
5755 ! do not use m_xnldata
5756 use m_constants
5757 implicit none
5758 !
5759 ! 0. Update history
5760 !
5761 ! 25/02/1999 Initial version
5762 ! 14/04/1999 Extra check in GET_LOC if locus exists in internal database
5763 ! 12/10/1999 Error handling improved
5764 ! 15/01/2001 Interface extended with diagonal term
5765 ! 06/05/2002 Criterion f34_mod added to computational procedure
5766 ! 14/08/2002 Integration simplified
5767 ! 22/08/2002 Integration modified depending on actual number of non-zero points
5768 ! 26/09/2002 Boundary check for sector grid activated
5769 ! 15/04/2003 Bug fixed in handling of periodicity
5770 ! Nearest bin integration enabled, including diagonal term
5771 ! 25/04/2003 Output to triplet arrays for nearest bin
5772 ! 03/05/2003 Output of triplets for bi-linear interpolation enabled
5773 ! 04/06/2003 Parameter IQ_INT renamed IQ_INTEG
5774 ! 13/06/2003 Test of integration for case of nearest bin interpolation
5775 ! 25/06/2003 Bug fixed in computation of partial derivatives for contribution to
5776 ! diagonal term
5777 ! 27/08/2003 Short-cut when number of non-zero points on locus is ZERO
5778 ! 05/09/2003 Switches for test output in nearest bin approach modified
5779 !
5780 ! 1. Purpose:
5781 !
5782 ! Compute the function T13, defined as a line integral around a locus
5783 !
5784 ! 2. Method
5785 !
5786 ! See Tracy and Resio (1982) and Van Vledder (1999)
5787 !
5788 ! 3. Parameter list:
5789 !
5790 ! Type I/O Name Description
5791 !------------------------------------------------------------------------------
5792 integer, intent(in) :: ik1 ! Index of k-component of wave number k1
5793 integer, intent(in) :: ia1 ! Index of a-component of wave number k1
5794 integer, intent(in) :: ik3 ! Index of k-component of wave number k3
5795 integer, intent(in) :: ia3 ! Index of a-component of wave number k3
5796 real, intent(out) :: t13 ! Value of line integral over a specific locus
5797 real, intent(out) :: diagk1 ! Contribution to diagonal term of k1
5798 real, intent(out) :: diagk3 ! Contribution to diagonal term of k3
5799 !
5800 ! 4. Error messages
5801 !
5802 ! 5. Called by:
5803 !
5804 ! Q_XNL4V4
5805 !
5806 ! 6. Subroutines used
5807 !
5808 ! Q_GETLOCUS
5809 ! Q_PUT_BTRIPLETS
5810 ! Q_PUT_NTRIPLETS
5811 !
5812 ! 7. Remarks
5813 !
5814 ! The action density product term is given by:
5815 ! P = n1.n2.(n3+n4)-(n1+n2).n3.n4
5816 !
5817 ! This term is rewritten as:
5818 !
5819 ! P = n1.n2.n3 + n1.n2.n4 - n1.n3.n4 - n2.n3.n4
5820 ! = n1.n3.(n2-n4) + n2.n4.(n1-n3)
5821 
5822 !
5823 ! 8. Structure
5824 !
5825 ! 9. Switches
5826 !
5827 ! /S enable subroutine tracing
5828 ! /T enable test output
5829 ! /N enable interpolation using nearest point
5830 !
5831 ! 10. Source code:
5832 !------------------------------------------------------------------------------
5833 ! Local variables
5834 !
5835 integer iloc ! counter along locus
5836 integer ifnd ! indicator if correct locus is found
5837 integer ja2,ja2p ! direction indices for interpolation of k2
5838 integer jk2,jk2p ! wave number indices for interpolation of k2
5839 integer ja4,ja4p ! direction indices for interpolation of k4
5840 integer jk4,jk4p ! wave number indices for interpolation of k4
5841 integer ikq,iaq ! counters
5842 !
5843 real sumt13 ! sum along locus
5844 real qn1,qn2,qn3,qn4 ! action densities at wave numbers k1, k2, k3 and k4
5845 real nprod ! wave number product
5846 real t2,t4 ! tail factors for k2 and k4
5847 real qd1,qd3 ! contribution to diagonal term
5848 real rterm ! product term along locus
5849 !
5850 real qn13p ! product of N1 and N3
5851 real qn13d ! difference of N1 and N3
5852 !
5853 !
5854 !------------------------------------------------------------------------------
5855 call q_stack('+q_t13v4')
5856 !
5857 t13 = 0.
5858 diagk1 = 0.
5859 diagk3 = 0.
5860 !
5861 !
5862 if(ik1==ik3 .and. ia1==ia3) goto 9999 ! skip routine if k1=k3
5863 !
5864 ! obtain information requested locus based on a information
5865 ! about a precomputed locus, as stored in the database file
5866 !
5867 call q_getlocus(ik1,ia1,ik3,ia3,ifnd)
5868 !
5869 if(ifnd==0 .or. nlocusx==0) then
5870  t13 = 0.
5871  goto 9999
5872 end if
5873 !---------------------------------------------------------------------------------------
5874 qn1 = nspec(ik1,ia1)
5875 qn3 = nspec(ik3,ia3)
5876 !
5877 qn13p = qn1*qn3 ! compute product
5878 qn13d = qn3-qn1 ! compute difference
5879 !
5880 sumt13 = 0
5881 !
5882 ! 3-----------4 ja2p w1 = (1-wk)*(1-wa)
5883 ! | . | w2 = wk*(1-wa)
5884 ! |. . + . . .| wa2 A w3 = (1-wk)*wa
5885 ! | . | | w4 = wk*wa
5886 ! | . | wa
5887 ! | . | |
5888 ! 1-----------2 ja2 V
5889 ! jk2 wk2 jk2p
5890 !
5891 ! <-wk->
5892 !
5893 !
5894 t2 = 1.
5895 t4 = 1.
5896 !
5897 !-----------------------------------------------------------------------------------
5898 !---------------------------------------------------------------------------------------
5899 ! Main loop over the locus
5900 !
5901 do iloc=1,nlocusx
5902 !
5903  jk2 = t_ik2(iloc)
5904  jk2p = min(jk2+1,nkq)
5905  ja2 = mod(t_ia2(iloc)-1+naq,naq)+1
5906  ja2p = mod(t_ia2(iloc)+naq,naq)+1
5907 !
5908 ! compute tail parameters
5909 !
5910 !! if(iq_geom==1) then
5911 !! jk2 = max(1,jk2)
5912 !! jk4 = max(1,jk4)
5913 !! t2 = max(1.,q_kfac**real(t_ik2(iloc)-nkq))
5914 !! t2 = t2**qk_tail
5915 !! t4 = max(1.,q_kfac**real(t_ik4(iloc)-nkq))
5916 !! t4 = t4**qk_tail
5917 !! end if
5918 !---------------------------------------------------------------------------------------
5919 ! check boundaries of sector grid
5920 !
5921  if(iq_grid < 3) then
5922  ja2 = max(ja2,1)
5923  ja2 = min(ja2,naq)
5924  ja2p = max(ja2p,1)
5925  ja2p = min(ja2p,naq)
5926  end if
5927 !
5928  qn2 = (t_w1k2(iloc)*nspec(jk2,ja2) + t_w2k2(iloc)*nspec(jk2p,ja2) + &
5929 & t_w3k2(iloc)*nspec(jk2,ja2p) + t_w4k2(iloc)*nspec(jk2p,ja2p))*t2
5930 !
5931  jk4 = t_ik4(iloc)
5932  jk4p = min(jk4+1,nkq)
5933  ja4 = mod(t_ia4(iloc)-1+naq,naq)+1
5934  ja4p = mod(t_ia4(iloc)+naq,naq)+1
5935 !
5936 ! special treatment for sector grids
5937 ! limit range of indices
5938 ! QQQ: in fact energy density should be set to ZERO
5939 !
5940  if(iq_grid < 3) then
5941  ja4 = max(ja4,1)
5942  ja4 = min(ja4,naq)
5943  ja4p = max(ja4p,1)
5944  ja4p = min(ja4p,naq)
5945  end if
5946 !
5947  qn4 = (t_w1k4(iloc)*nspec(jk4,ja4) + t_w2k4(iloc)*nspec(jk4p,ja4) + &
5948 & t_w3k4(iloc)*nspec(jk4,ja4p) + t_w4k4(iloc)*nspec(jk4p,ja4p))*t4
5949 !
5950 !-------------------------------------------------------------------------------
5951 !
5952  nprod = qn13p*(qn4-qn2) + qn2*qn4*qn13d
5953  rterm = t_zz(iloc)
5954  t13 = t13 + rterm*nprod
5955 !
5956 ! output to triplets
5957 !
5958 !
5959 !
5960 ! add diagonal terms
5961 !
5962 !! qd1 = qn3*(qn4-qn2) + qn2*qn4*qn3
5963 !! qd3 = qn1*(qn4-qn2) - qn2*qn4*qn1
5964 !
5965  qd1 = qn3*(qn4-qn2) - qn2*qn4
5966  qd3 = qn1*(qn4-qn2) + qn2*qn4
5967  diagk1 = diagk1 + qd1*rterm
5968  diagk3 = diagk3 + qd3*rterm
5969 !-----------------------------------------------------------------------------------
5970 end do
5971 !
5972 !!/T if(iq_test>=4) then
5973 !!/T write(luq_tst,'(a)') 'Q_T13V4: NSPEC'
5974 !!/T do ikq=1,nkq
5975 !!/T write(luq_tst,'(100e12.4)') (nspec(ikq,iaq),iaq=1,naq)
5976 !!T end do
5977 !!T end if
5978 !!if(iq_integ==3) write(luq_int,'(4i3,i5,1000e13.5)') ik1,ia1,ik3,ia3,nloc, &
5979 !!& t_s(nloc),t13,(dt13(iloc),iloc=1,nloc)
5980 !
5981 9999 continue
5982 !
5983 call q_stack('-q_t13v4')
5984 !
5985 return
5986 end subroutine
5987 !------------------------------------------------------------------------------
5996 
5997 subroutine q_weight
5998 !------------------------------------------------------------------------------
5999 !
6000 ! +-------+ ALKYON Hydraulic Consultancy & Research
6001 ! | | Gerbrant van Vledder
6002 ! | +---+
6003 ! | | +---+ Last update: 20 Aug. 2002
6004 ! +---+ | | Release: 4.0
6005 ! +---+
6006 !
6007 ! do not use m_xnldata
6008 implicit none
6009 !
6010 ! 0. Update history
6011 !
6012 ! 13/04/1999 Initial version
6013 ! 27/10/1999 Weight computed in the case that k2m < k(1)
6014 ! 01/11/1999 Use of Q_XK and Q_SK added to compute weights if k > kmax
6015 ! 26/11/1999 Bug fixed when checking conversion
6016 ! 8/12/1999 Use of SK_MAX introduced to handle very large loci
6017 ! 09/08/2002 Modification of weights
6018 ! 13/08/2002 storage of log-spacing replace by linear spacing
6019 ! 20/08/2002 Bug fixed when geometric scaling is assumed
6020 !
6021 ! 1. Purpose:
6022 !
6023 ! Compute interpolation weights of locus
6024 !
6025 ! 2. Method
6026 !
6027 ! Compute position of wave number in wave number grid
6028 ! Usable for linear interpolation
6029 !
6030 ! 3. Parameter list:
6031 !
6032 ! Name I/O Type Description
6033 !
6034 ! 4. Error messages
6035 !
6036 ! 5. Called by:
6037 !
6038 ! Q_MAKEGRID
6039 !
6040 ! 6. Subroutines used
6041 !
6042 ! 7. Remarks
6043 !
6044 ! The tail factors wt_k2 and wt_k4 are valid for the decay of the action density spectrum
6045 ! N(kx,ky). With p (qk_tail) the power p of the tail of the N(k) spectrum, and q the power
6046 ! of the tail of the N(kx,ky) spectrum, we have q=p-1
6047 !
6048 ! Since N(k) = k N(kx,ky) with k the Jacobian
6049 ! it follows that the tail functions are given by
6050 !
6051 ! k^p = k k^q => k^p = k^(q+1) => p=q+1 => q=p-1
6052 !
6053 ! 8. Structure
6054 !
6055 ! Initialisations
6056 ! do for all points on locus
6057 ! compute directional index for k2 and k4
6058 ! if geometric scaling then
6059 ! compute wave number index directly
6060 ! convert log-scaling to linear scaling
6061 ! else
6062 ! search position of wave number in k-array
6063 ! if k < kmin then
6064 ! k-index = 1 and factor is 0
6065 ! elsif k < kmax then
6066 ! compute k-index for k2 and k4
6067 ! else
6068 ! compute tail factor
6069 ! end if
6070 ! end if
6071 ! end do
6072 !
6073 !
6074 ! 9. Switches
6075 !
6076 ! /T enable test output
6077 !
6078 ! 10. Source code:
6079 !------------------------------------------------------------------------------
6080 ! Local variables
6081 !
6082 integer iloc ! counter along locus loop
6083 integer jpos ! index for interpolation and tracking of position in wave numebr array
6084 integer itest ! local test level
6085 real k2a,k2m ! angle (radians) and magnitude of wave number k2
6086 real k4a,k4m ! angle (radians) and magnitude of wave number k2
6087 real dk ! difference between two wave numbers
6088 real xtest ! test value for checking computation of weights, by inversion test
6089 real ff,gg ! variables in transformation of log-spacing to linear spacing
6090 !
6091 ! functions used
6092 !
6093 !!real x_kfunc ! function to invert computation of wieghts
6094 !------------------------------------------------------------------------------
6095 call q_stack('+q_weight')
6096 !
6097 ! initialisations
6098 !
6099 itest = iq_test ! set local test level
6100 itest = itest
6101 !------------------------------------------------------------------------------
6102 do iloc=1,nlocus
6103  k2m = k2m_mod(iloc)
6104  k2a = k2a_mod(iloc)
6105  k4m = k4m_mod(iloc)
6106  k4a = k4a_mod(iloc)
6107 !
6108  wt_k2(iloc) = 0.
6109  wt_k4(iloc) = 0.
6110 !
6111 ! compute directional weights
6112 !
6113  wa_k2(iloc) = (k2a-q_ang1)/q_deltad+1
6114  wa_k4(iloc) = (k4a-q_ang1)/q_deltad+1
6115 !------------------------------------------------------------------------------
6116 ! compute position of k2 in wave number grid
6117 ! and compute weight function
6118 !-----------------------------------------------------------------------------
6119  if(iq_disp==1.and. iq_geom==1) then ! deep water is assumed and loci have geometric scaling
6120 !
6121  wk_k2(iloc) = 1.+alog(k2m/kqmin)/alog(q_kfac)
6122  wt_k2(iloc) = 1.
6123  wk_k4(iloc) = 1.+alog(k4m/kqmin)/alog(q_kfac)
6124  wt_k4(iloc) = 1.
6125 !
6126 ! Replace log-spacing by linear spacing
6127 !
6128  ff = wk_k2(iloc)
6129  gg = floor(ff)
6130  wk_k2(iloc) = gg+(q_kfac**(ff-gg)-1.)/(q_kfac-1.)
6131 !
6132 !!/T if(iq_test>=3) write(luq_tst,'(a,4f10.5)') 'Q_WEIGHT: wlog gg wlin2:', &
6133 !!/T & ff,gg,wk_k2(iloc),abs(wk_k2(iloc)-ff)/abs(ff)*100.
6134 !
6135  ff = wk_k4(iloc)
6136  gg = floor(ff)
6137  wk_k4(iloc) = gg+(q_kfac**(ff-gg)-1.)/(q_kfac-1.)
6138 !
6139 !!/T if(iq_test>=3) write(luq_tst,'(a,4f10.5)') 'Q_WEIGHT: wlog gg wlin4:', &
6140 !!/T ff,gg,wk_k4(iloc),abs(wk_k4(iloc)-ff)/abs(ff)*100.
6141 !
6142 ! for finite depth a search is carried out to compute
6143 ! the position of the interacting wave number in the
6144 ! non-geometric k-grid
6145 !
6146  else
6147  jpos = 1
6148  do while (k2m > q_k(jpos))
6149  jpos = jpos + 1
6150  if(jpos > nkq) exit
6151  end do
6152 !
6153  if(k2m <= q_k(1)) then
6154  wk_k2(iloc) = k2m/q_k(1)
6155  wt_k2(iloc) = 0.
6156  elseif(k2m < q_k(nkq) .and. k2m > q_k(1)) then
6157  dk = q_k(jpos)-q_k(jpos-1)
6158  wk_k2(iloc) = real(jpos-1) + (k2m-q_k(jpos-1))/dk
6159  wt_k2(iloc) = 1.
6160  elseif(k2m >= q_k(nkq)) then
6161  wk_k2(iloc) = min(wk_max,real(nkq) + (k2m-q_k(nkq))/q_sk(nkq))
6162  wt_k2(iloc) = (k2m/q_k(nkq))**(qk_tail-1.)
6163 !
6164 ! minus 1 to account for Jacobian from kx,ky to polar k-grid
6165 !
6166  end if
6167 !
6168 ! compute position of k4 in wave number grid
6169 ! and compute weight function
6170 !
6171  jpos = 1
6172  do while (k4m > q_k(jpos))
6173  jpos = jpos + 1
6174  if(jpos > nkq) exit
6175  end do
6176 !
6177  if(k4m <= q_k(1)) then
6178  wk_k4(iloc) = k4m/q_k(1)
6179  wt_k4(iloc) = 0.
6180  elseif(k4m < q_k(nkq) .and. k4m > q_k(1)) then
6181  dk = q_k(jpos)-q_k(jpos-1)
6182  wk_k4(iloc) = real(jpos-1) + (k4m-q_k(jpos-1))/dk
6183  wt_k4(iloc) = 1.
6184  elseif(k4m >= q_k(nkq)) then
6185  wk_k4(iloc) = min(wk_max,real(nkq) + (k4m-q_k(nkq))/q_sk(nkq))
6186  wt_k4(iloc) = (k4m/q_k(nkq))**(qk_tail-1.)
6187  end if
6188 !
6189  end if
6190 !
6191 !
6192 end do
6193 !
6194 9999 continue
6195 !
6196 call q_stack('-q_weight')
6197 !
6198 return
6199 end subroutine
6200 !-----------------------------------------------------------------
6219 
6220 subroutine q_loc_w1w3(k1x,k1y,k3x,k3y,npts,k2x,k2y,k4x,k4y,s)
6221 !-----------------------------------------------------------------
6222 !
6223 ! +-------+ ALKYON Hydraulic Consultancy & Research
6224 ! | | Gerbrant van Vledder
6225 ! | +---+
6226 ! | | +---+ Last update: 11 June 2003
6227 ! +---+ | | Release: 5.0
6228 ! +---+
6229 !
6230 !
6231 implicit none
6232 !
6233 ! 0. Update history
6234 !
6235 ! 15/04/2002 Initial version
6236 ! 20/08/2002 Direction of k1 may be non-zero
6237 ! 27/08/2002 Singular solution crosses origin
6238 ! 11/06/2003 Length of locus fixed to 3
6239 !
6240 ! 1. Purpose:
6241 !
6242 ! Compute locus for the special case w1=w3
6243 !
6244 ! 2. Method
6245 !
6246 ! For this case, the k2-locus consists of a straight line
6247 !
6248 ! 3. Parameter used:
6249 !
6250 integer, intent(in) :: npts ! Number of points
6251 real, intent(in) :: k1x ! x-component of wave number k1
6252 real, intent(in) :: k1y ! y-component of wave number k1
6253 real, intent(in) :: k3x ! x-component of wave number k3
6254 real, intent(in) :: k3y ! y-component of wave number k3
6255 !
6256 real, intent(out) :: k2x(npts) ! x-component of wave number k2
6257 real, intent(out) :: k2y(npts) ! y-component of wave number k2
6258 real, intent(out) :: k4x(npts) ! x-component of wave number k4
6259 real, intent(out) :: k4y(npts) ! y-component of wave number k4
6260 real, intent(out) :: s(npts) ! distance along locus
6261 !
6262 ! 4. Error messages
6263 !
6264 ! 5. Caled by:
6265 !
6266 ! Q_CMPLOCUS
6267 !
6268 ! 6. Subroutines used
6269 !
6270 ! 7. Remarks
6271 !
6272 ! Routine based on modified version of routine SHLOCX of Resio and Tracy
6273 ! On 15/4/2002 a bug fixed in computation of THR when angle of k3 is larger than 90°
6274 !
6275 ! In addition, the assumption that k1y=0 and thus dir1=0 is removed
6276 ! In bug fix of 20/8/2002 this restriction is removed.
6277 !
6278 ! 8. Structure
6279 !
6280 ! Compute angle of symmetry axis
6281 ! Compute distance between 2 lines of solution
6282 ! compute wave numbers along locus
6283 ! rotate angles
6284 !
6285 ! 9. Switches
6286 !
6287 ! 10. Source code
6288 !------------------------------------------------------------------------------
6289 ! Local variables
6290 !
6291 integer ipt ! counter of points along locus
6292 !
6293 real dirs ! angle of symmetry axis
6294 real dir1 ! direction of wave number k1
6295 real dir3 ! direction of wave number k3
6296 real dk0 ! step size along locus
6297 real xk0 ! x-component
6298 real yk0 ! y-component
6299 real w2 ! radian frequency
6300 real xx2,yy2 ! values along k2-locus
6301 real xx4,yy4 ! values along k4-locus
6302 real k1m ! magnitude of wave number k1
6303 !------------------------------------------------------------------------------
6304 !
6305 ! dirs is the angle of rotation from the x-axis to the "bisecting" angle
6306 !
6307 dir1 = atan2(k1y,k1x)
6308 dir3 = atan2(k3y,k3x)
6309 dirs = 0.5*(180-abs(180-abs(dir3-dir1)))
6310 k1m = sqrt(k1x**2 + k1y**2)
6311 !
6312 ! k1x is the total length of the wavenumber vector
6313 ! xk0 is the length of this vector in the rotated coordinate system
6314 !
6315 xk0 = k1m * cos(dirs)
6316 yk0 = k1m * sin(dirs)
6317 !
6318 ! Specify step size for solution of singular case
6319 !
6320 !! dk0 = 0.11 ! Removed on 11/6/2003, this value is used in original WRT code
6321 !! dk0 = kqmax/real(npts-1.) this value depends on actual grid
6322 dk0 = 3./real(npts-1.) ! this is test value
6323 !
6324 ! modify rotation angle
6325 !
6326 dirs = dirs + dir1
6327 !
6328 ! generate sequence of parallel lines
6329 ! rotate lines over modified angle DIRS
6330 !
6331 do ipt=1,npts
6332 ! w2 = real(ipt-1.)*dk0 ! removed on Aug. 27 2002
6333 !
6334  w2 = 2.*real(ipt-npts/2)*dk0 ! create line on both sides of origin
6335  xx2 = w2*xk0
6336  yy2 = yk0
6337  k2x(ipt) = xx2*cos(dirs) - yy2*sin(dirs)
6338  k2y(ipt) = yy2*cos(dirs) + xx2*sin(dirs)
6339  xx4 = xx2
6340  yy4 = -yy2
6341  k4x(ipt) = xx4*cos(dirs) - yy4*sin(dirs)
6342  k4y(ipt) = yy4*cos(dirs) + xx4*sin(dirs)
6343  s(ipt) = real(ipt-1)*dk0*xk0
6344 end do
6345 !
6346 return
6347 end subroutine
6348 !------------------------------------------------------------------------------
6371 
6372 subroutine q_xnl4v4(aspec,sigma,angle,nsig,nang,depth,xnl,diag,ierr)
6373 !------------------------------------------------------------------------------
6374 !
6375 ! +-------+ ALKYON Hydraulic Consultancy & Research
6376 ! | | Gerbrant van Vledder
6377 ! | +---+
6378 ! | | +---+ Last update: 25 June 2003
6379 ! +---+ | | Release: 5.0
6380 ! +---+
6381 !
6382 ! do not use m_xnldata
6383 use m_constants
6384 use serv_xnl4v5
6385 implicit none
6386 !------------------------------------------------------------------------------
6387 ! 0. Update history
6388 !
6389 ! 08/01/2000 Initial version
6390 ! 12/01/2001 Updated interface
6391 ! 13/01/2001 Inclusion of diagonal term
6392 ! 14/02/2002 Upgrade to release 4.0, depth added to input
6393 ! 20/08/2002 quad depth adapted in the case of WAM-depth scaling
6394 ! then deep water is assumed for conversion of A(sig,theta) -> N(kx,ky)
6395 ! Search option for nearest grid included
6396 ! 23/08/2002 Allocation of work arrays set to fixed size
6397 ! 11/09/2002 Filtering of energy densities introduced and restructure
6398 ! 14/04/2003 Format of test write statement corrected
6399 ! 03/05/2003 Computation and output of triplets enabled
6400 ! 12/06/2003 Export spectral grid in case of Q_INTEG>1
6401 ! 16/06/2003 Switch IQ_SYM included
6402 ! Allocation of dynamic data array's moved to Q_ALLOCATE
6403 ! 24/06/2003 Range of loop for IK3 made dependent on value of IQ_SYM
6404 ! 25/06/2003 Bug fixed in assigment of contribution of diagonal term
6405 !
6406 ! 1. Purpose:
6407 !
6408 ! Compute nonlinear transfer for a given action density spectrum
6409 ! on a given wave number and direction grid
6410 !
6411 ! 2. Method
6412 !
6413 ! Compute nonlinear transfer in a surface gravity wave spectrum
6414 ! due to resonant four wave-wave interactions
6415 !
6416 ! Methods: Webb/Resio/Tracy/VanVledder
6417 !
6418 !
6419 ! 3. Parameter list:
6420 !
6421 ! Type I/O Name Description
6422 !------------------------------------------------------------------------------
6423 integer,intent(in) :: nsig ! number of radian frequencies
6424 integer,intent(in) :: nang ! number of directions
6425 real, intent(in) :: aspec(nsig,nang) ! Action density spectrum as a function of (sigma,theta)
6426 real, intent(in) :: sigma(nsig) ! radian frequencies
6427 real, intent(in) :: angle(nang) ! directions in radians (sector or full circle)
6428 real, intent(in) :: depth ! water depth in m
6429 real, intent(out) :: xnl(nsig,nang) ! nonlinear quadruplet interaction computed with
6430 ! a certain exact method (k,theta)
6431 real, intent(out) :: diag(nsig,nang) ! Diagonal term for WAM based implicit integration scheme
6432 integer, intent(out) :: ierr ! error indicator
6433 !
6434 ! 4. Error messages
6435 !
6436 ! 5. Called by:
6437 !
6438 ! XNL_MAIN
6439 !
6440 ! 6. Subroutines used
6441 !
6442 ! Q_STACK
6443 ! Q_INIT
6444 ! Q_CTRGRID
6445 ! Q_T13V4
6446 ! Q_SEARCHGRID
6447 !
6448 ! 7. Remarks
6449 !
6450 ! The external action density spectrum is given as N(sigma,dir)
6451 ! The internal action density spectrum is given as N(kx,ky)
6452 !
6453 ! These 2 spectra are conected via the Jacobian transformation
6454 !
6455 ! cg
6456 ! N(kx,ky) = -- N(sig,theta)
6457 ! k
6458 ! 8. Structure
6459 !
6460 ! 9. Switches
6461 !
6462 ! 10. Source code
6463 !------------------------------------------------------------------------------
6464 ! local variables
6465 !---------------------------------------------------------------------------------------
6466 integer iaq ! counter for directions
6467 integer jaq ! counter for directions
6468 integer ikq ! counter for wave numbers
6469 integer iang ! counter for directions
6470 integer ia ! counter for directions
6471 integer ik ! counter for wave numbers
6472 integer idir1 ! direction in degrees of k1 (for integration test)
6473 integer idir3 ! direction in degrees of k3 (for integration test)
6474 real period ! periodicity for direction, used in conversion of 2-spectra
6475 real diagk1 ! diagonal term for k1
6476 real diagk3 ! diagonal term for k3
6477 !
6478 real qn_max ! maximum action density
6479 real qn_min ! minimum action density
6480 !
6481 real cg(nsig) ! group velocity for conversion of spectrum and transfer
6482 !
6483 integer ia1,ia3,ja3 ! limits for directional loops
6484 integer jk3 ! start of k3 loop
6485 integer ik1,ik3 ! counters for wave number loop
6486 integer nloc ! number of points on locus
6487 !
6488 integer igrid ! status of grid file
6489 real t13 ! value of sub-integral
6490 real k_rat ! local ratio of wave numbers
6491 real a_dif ! directional difference
6492 real jacobian ! Jacobian
6493 real qn1,qn3 ! action densities in k1 and k3
6494 !
6495 ! testing of diagonal term on a low level
6496 !
6497 real diagk1_0 ! saved value of diagk1
6498 real diagk3_0 ! saved value of diagk3
6499 real dq1 ! small change in action density of n1
6500 real dq3 ! small change in action density of n3
6501 real t13_0 ! Original estimated of diagonal term
6502 real t13_1,t13_3 ! perturbed estimated of diagonal term
6503 !
6504 integer ifil_dir ! indicator for filtering of directional criterion
6505 integer ifil_krat ! indicator for filtering of wave number ratio criterion
6506 integer ifil_dens ! indicator for filtering of action density criterion
6507 integer ifil_tot ! indicator for filtering due to any criterion
6508 integer nfil_dir ! counter to indicate filtering of directional criterion
6509 integer nfil_krat ! counter to indicate filtering of wave number criterion
6510 integer nfil_dens ! counter to indicate filtering of action density criterion
6511 !
6512 integer ntot_conf ! total number of configurations
6513 integer ntot_filt ! total number of filtered configurations
6514 !
6515 !
6516 !------------------------------------------------------------------------------
6517 call q_stack('+q_xnl4v4')
6518 !
6519 ! initialisations
6520 !------------------------------------------------------------------------------
6521 ierr = 0 ! error status
6522 diag = 0 ! initialize output diagonal term
6523 !
6524 !
6525 if(iq_type==3) then
6526  q_depth = depth ! water depth to be used in computation
6527 else
6529 end if
6530 !--------------------------------------------------------------------------
6531 ! generate basic grid of loci and store loci in memory and to datafile
6532 !--------------------------------------------------------------------------
6533 if(iq_screen >= 1) write(iscreen,'(a)') 'Q_XNL4V4: Checking interaction grid '
6534 !
6535 if(iq_search==0 .or. iq_type/=3) then
6536  call q_init
6537  call q_ctrgrid(2,igrid)
6538  if(iq_err /= 0) goto 9999
6539 !
6540  if(igrid/=0) then
6541  call q_error('e','NOGRID','No proper grid exists')
6542  goto 9999
6543  end if
6544 !
6545  if(iq_make ==3) then
6546  call q_error('e','MAKEGRID','Only computation of grid')
6547  goto 9999
6548  end if
6549 !------------------------------------------------------------------------------
6550 ! set overall scale factor resulting from optional SEARCH for nearest grid
6551 !------------------------------------------------------------------------------
6552 !
6553  q_scale = 1.
6554 !------------------------------------------------------------------------
6555 else
6556 !
6557 ! search nearest valid grid and compute additional WAM scale factor
6558 ! only active when IQ_SEARCH==1 .AND. IQ_TYPE==3
6559 !
6560  call q_searchgrid(depth,igrid)
6561 
6562 
6563  if(igrid/=0) then
6564  call q_error('e','NOGRID','No proper grid exists')
6565  goto 9999
6566  end if
6567 !
6568  if(iq_err /=0) goto 9999
6569 end if
6570 !
6571 !------------------------------------------------------------------------------
6572 ! convert input action density spectrum from A(sigma,theta) -> N(kx,ky)
6573 !
6574 do ikq=1,nkq
6575  call z_cmpcg(sigma(ikq),q_depth,q_grav,cg(ikq))
6576  do iaq=1,naq
6577  nspec(ikq,iaq) = aspec(ikq,iaq)/q_k(ikq)*cg(ikq)
6578  end do
6579 end do
6580 !
6581 !------------------------------------------------------------------------------
6582 !
6583 !--------------------------------------------------------------------------------------
6584 ! integration over all possible configurations
6585 !--------------------------------------------------------------------------------------
6586 xnl = 0.
6587 qn_max = maxval(nspec)
6588 !
6589 !--------------------------------------------------------------------------------------
6590 do ik1 = 1,nkq
6591  if(iq_screen >= 1) write(iscreen,'(a,2i4,e12.3)') 'Q_XNL4V4: k1 nk d:',ik1,nkq,q_depth
6592  jk3 = ik1
6593  if(iq_sym==0) jk3 = 1
6594 !
6595  do ia1 = iaq1,iaq2 ! loop over selected part of grid, set in q_init
6596 !
6597  qn1 = nspec(ik1,ia1)
6598 !
6599  do ik3 = jk3,nkq ! compute only half-plane
6600  do ia3 = 1,naq ! loop over all possible wave directions
6601  qn3 = nspec(ik3,ia3)
6602 !
6603  if(iq_screen>=3) write(iscreen,'(a,4i4)') 'Q_XNL4V4: ik1 ia1 ik3 ia3:',ik1,ia1,ik3,ia3
6604 !
6605 ! computes distances in wave number space
6606 !
6607  a_dif = 180. - abs(180. - abs(q_ad(ia1) - q_ad(ia3)))
6608  k_rat = max(q_k(ik1)/q_k(ik3), q_k(ik3)/q_k(ik1))
6609  qn_min = qf_frac*qn_max/(q_k(ik3)/q_k(1))**7.5
6610  qn_min = qf_frac*qn_max*q_kpow(ik3)
6611 !
6612  ifil_dir = 0
6613  ifil_krat = 0
6614  ifil_dens = 0
6615  ifil_tot = 0
6616 !
6617 ! perform filtering
6618 !
6619 ! directional difference
6620 !
6621  if(a_dif > qf_dmax) then
6622  ifil_dir = 1
6623  end if
6624 !
6625 ! wave number ratio
6626 !
6627  if(k_rat > qf_krat) then
6628  ifil_krat = 1
6629  end if
6630 !
6631 ! energy density filtering
6632 !
6633  if(qn1 < qn_min .and. qn3 < qn_min) then
6634  ifil_dens = 1
6635  end if
6636 !
6637 !
6638  if(ifil_dir==0 .and. ifil_krat==0 .and. ifil_dens==0 .or. iq_filt==0) then
6639 !? if(a_dif < qf_dmax .and. k_rat < qf_krat .or. iq_filt==0) then
6640 !
6641 ! perform integration along locus
6642 !
6643  call q_t13v4(ik1,ia1,ik3,ia3,t13,diagk1,diagk3)
6644 !
6645 !
6646  if(iq_err /= 0) goto 9999
6647 !
6648 ! check contribution T13 with the computed with triplet method
6649 !
6650 !!/R qt13 = 0.
6651 !!/R do iqtr = 1,ktriplets
6652 !!/R qt13 = qt13 + w_qtr(iqtr)*nspec(i_qtr(iqtr,1),i_qtr(iqtr,2))* &
6653 !!/R & nspec(i_qtr(iqtr,3),i_qtr(iqtr,4))*nspec(i_qtr(iqtr,5),i_qtr(iqtr,6))
6654 !!/R end do
6655 !!/R write(iscreen,*) 'CHECK T13 QT13:',t13,qt13
6656 !
6657 !
6658 ! take care of additional scale factor aring from search of nearest grid
6659 !
6660  t13 = t13*q_scale
6661  diagk1 = diagk1*q_scale
6662  diagk3 = diagk3*q_scale
6663 !
6664 ! take care of symmetric storing of interactions
6665 ! and factor 2 due to symmetry (if activated)
6666 !
6667  if(iq_sym==1) then
6668  t13 = 2.*t13
6669  diagk1 = 2.*diagk1
6670  diagk3 = 2.*diagk3
6671  end if
6672 !
6673  ja3 = ia3
6674  if(iq_grid==1 .and. ia3 < iaref) ja3 = naq-ia1+1
6675  xnl(ik1,ia1) = xnl(ik1,ia1) + t13*q_k(ik3)*q_delta*q_dk(ik3)
6676  if(iq_sym==1) xnl(ik3,ja3) = xnl(ik3,ja3) - t13*q_k(ik1)*q_delta*q_dk(ik1)
6677 !
6678 ! add diagonal term
6679 !
6680  diag(ik1,ia1) = diag(ik1,ia1) + diagk1*q_k(ik3)*q_delta*q_dk(ik3)
6681  if(iq_sym==1) diag(ik3,ia3) = diag(ik3,ia3) - diagk3*q_k(ik1)*q_delta*q_dk(ik1)
6682 !
6683  end if
6684 !
6685 !!/F write(luq_fil,'(a,4i3,3e11.3,2f7.2,4i2)') &
6686 !!/F & 'ik1 ia1 ik3 ia3 n1 n3 t13 adif krat fil1/2/3:', &
6687 !!/F & ik1,ia1,ik3,ia3,qn1,qn3,t13,a_dif,k_rat,&
6688 !!/F & ifil_dir,ifil_krat,ifil_dens,ifil_tot
6689  end do
6690  end do
6691  end do
6692 end do
6693 !
6694 !
6695 !
6696 !
6697 !
6698 ! write number of triplets that have been written
6699 !
6700 !
6701 !------------------------------------------------------------------------------
6702 ! in the case of a symmetric sector, copy results to other part
6703 !
6704 ! Examples: naq=5, iaref=3: 1,2,3,4,5 -> Q(1)=Q(5)
6705 ! Q(2)=Q(4)
6706 ! Q(3)=Q(3)
6707 ! iaq+jaq=naq+1
6708 ! naq=6, iaref=4: 1,2,3,4,5,6 -> Q(1)=Q(6)
6709 ! Q(2)=Q(5)
6710 ! Q(3)=Q(4)
6711 !
6712 if(iq_grid==1) then
6713  do ikq = 1,nkq
6714  do iaq=iaref,naq
6715  jaq = naq+1-iaq
6716  xnl(ikq,jaq) = xnl(ikq,iaq)
6717  end do
6718  end do
6719 end if
6720 !
6721 !------------------------------------------------------------------------------
6722 if(iq_screen>=2) write(iscreen,'(a)') 'Q_XNL4V4: Main computation ended'
6723 !
6724 ! Convert transfer from (kx,ky) grid to (sigma,theta) grid
6725 !
6726 do ikq=1,nkq
6727  jacobian = q_k(ikq)/cg(ikq)
6728  do iaq=1,naq
6729  xnl(ikq,iaq) = xnl(ikq,iaq)*jacobian
6730  end do
6731 end do
6732 ! !
6733 9999 continue
6734 !
6735 call q_stack('-q_xnl4v4')
6736 !
6737 return
6738 end subroutine
6739 !------------------------------------------------------------------------------
6751 
6752 real function x_cosk(k)
6753 !------------------------------------------------------------------------------
6754 !
6755 ! +-------+ ALKYON Hydraulic Consultancy & Research
6756 ! | | Gerbrant van Vledder
6757 ! | +---+
6758 ! | | +---+ Last update: 13 Aug. 2002
6759 ! +---+ | | Release: 4.0
6760 ! +---+
6761 !
6762 ! do not use m_xnldata
6763 use serv_xnl4v5, only: z_wnumb
6764 !
6765 implicit none
6766 !--------------------------------------------------------------------------------
6767 ! 0. Update history
6768 !
6769 ! Date Description
6770 !
6771 ! 13/08/2002 Initial version
6772 !
6773 ! 1. Purpose:
6774 !
6775 ! Compute cosine of points on locus for given wave number k
6776 !
6777 ! 2. Method
6778 !
6779 ! Explicit polar method, see Van Vledder 2000, Monterey paper
6780 ! Optionally using a fixed k-step, geometric k-step or adaptive stepping
6781 !
6782 ! 3. Parameters used:
6783 !
6784 real, intent(in) :: k ! wave number along symmetry axis of locus
6785 !
6786 ! 4. Error messages
6787 !
6788 ! 5. Called by:
6789 !
6790 ! Q_POLAR
6791 !
6792 ! 6. Subroutines used:
6793 !
6794 ! Z_WNUMB computation of wave number
6795 !
6796 ! 7. Remarks
6797 !
6798 ! The variables q, pmag and q_depth are accessed from module m_xnldata
6799 ! The variable q_grav is accessed from module m_constants
6800 !
6801 ! 8. Structure
6802 !
6803 ! 9. Switches
6804 !
6805 !
6806 ! 10. Source code
6807 !------------------------------------------------------------------------------
6808 ! Local variables
6809 !
6810 real qq ! constant in direct polar method qq=q/sqrt(g)
6811 real wk ! intemediate radian frequency
6812 real kz ! intermediate wave number
6813 !------------------------------------------------------------------------------
6814 select case(iq_disp)
6815 !
6816 case(1) ! deep water
6817 !
6818  qq = q/sqrt(q_grav)
6819  x_cosk = ((qq+sqrt(k))**4 - k**2 - pmag**2)/(2.*k*pmag)
6820 !
6821 case(2) ! finite depth
6822 !
6823  wk = q + x_disper(k,q_depth)
6824  kz = z_wnumb(wk,q_depth,q_grav)
6825  x_cosk = (kz**2-k**2 - pmag**2)/(2.*k*pmag)
6826 !
6827 end select
6828 !
6829 x_cosk = max(-1.,x_cosk)
6830 x_cosk = min( 1.,x_cosk)
6831 !
6832 end function x_cosk
6833 !------------------------------------------------------------------------------
6853 
6854 real function x_cple(k1x,k1y,k2x,k2y,k3x,k3y,k4x,k4y,iq_cple,depth,grav)
6855 !------------------------------------------------------------------------------
6856 !
6857 ! +-------+ ALKYON Hydraulic Consultancy & Research
6858 ! | | Gerbrant van Vledder
6859 ! | +---+
6860 ! | | +---+ Last update: 10 Sept. 2002
6861 ! +---+ | | Release: 5.0
6862 ! +---+
6863 !
6864 implicit none
6865 !
6866 ! 0. Update history
6867 !
6868 ! 25/02/1999 Initial version
6869 ! 25/10/1999 Names of some variables modified
6870 ! type and depth via interface
6871 ! 09/08/2002 Upgrade to release 4.0
6872 ! 10/09/2002 g included in interface
6873 !
6874 ! 1. Purpose:
6875 !
6876 ! Compute coupling coefficient between a quadruplet of
6877 ! interacting wave numbers
6878 !
6879 ! 2. Method
6880 !
6881 !
6882 ! 3. Parameter list:
6883 !
6884 ! Name I/O Type Description
6885 !
6886 !Type I/O Name Description
6887 !-----------------------------------------------------------------------------
6888 real, intent(in) :: k1x ! x-component of wave number k1
6889 real, intent(in) :: k1y ! y-component of wave number k1
6890 real, intent(in) :: k2x ! x-component of wave number k2
6891 real, intent(in) :: k2y ! y-component of wave number k2
6892 real, intent(in) :: k3x ! x-component of wave number k3
6893 real, intent(in) :: k3y ! y-component of wave number k3
6894 real, intent(in) :: k4x ! x-component of wave number k4
6895 real, intent(in) :: k4y ! y-component of wave number k4
6896 integer, intent(in) :: iq_cple ! Type of coupling coefficient
6897 real, intent(in) :: depth ! Water depth in meters
6898 real, intent(in) :: grav ! Gravitational acceleration
6899 !
6900 ! 4. Error messages
6901 !
6902 ! 5. Called by:
6903 !
6904 ! Q_CMPLOCUS
6905 !
6906 ! 6. Subroutines used
6907 !
6908 ! X_WEBB
6909 ! X_HH
6910 !
6911 ! 7. Remarks
6912 !
6913 ! 8. Structure
6914 !
6915 ! 9. Switches
6916 !
6917 ! 10. Source code:
6918 !-------------------------------------------------------------------------------
6919 ! Local variables
6920 ! ! real functions to compute coupling coefficient
6921 !!real xc_webb ! Webb, deep water
6922 !!real xc_hh ! Herterich and Hasselmann, finite depth
6923 !------------------------------------------------------------------------------
6924 if (iq_cple < 1 .or. iq_cple > 4) then
6925  x_cple = 0.
6926  goto 9999
6927 end if
6928 !
6929 select case(iq_cple)
6930 !
6931 ! 1) Deep water coupling coefficient of Webb
6932 !
6933 case(1)
6934  x_cple = xc_webb(k1x,k1y,k2x,k2y,k3x,k3y,k4x,k4y,grav)
6935 !
6936 ! 2) finite depth coupling coefficient of Herterich and Hasselmann
6937 ! as implemented in the Resio-Tracy program SB5
6938 !
6939 case(2)
6940  x_cple = xc_hh(k4x,k4y,k3x,k3y,k2x,k2y,k1x,k1y,depth)
6941 !
6942 ! x_cple = xc_hh2(k1x,k1y,k2x,k2y,k3x,k3y,depth,grav)
6943 !
6944 end select
6945 !
6946 9999 continue
6947 !
6948 return
6949 end function
6950 !------------------------------------------------------------------------------
6963 
6964 real function x_flocus(kxx,kyy)
6965 !------------------------------------------------------------------------------
6966 !
6967 ! +-------+ ALKYON Hydraulic Consultancy & Research
6968 ! | | Gerbrant van Vledder
6969 ! | +---+
6970 ! | | +---+ Last update: 9 Aug. 2002
6971 ! +---+ | | Release: 4.0
6972 ! +---+
6973 !
6974 ! do not use m_xnldata
6975 use m_constants
6976 implicit none
6977 !
6978 ! 0. Update history
6979 !
6980 ! 25/02/1999 Initial version
6981 ! 20/07/1999 Bug fixed when IDISP=2
6982 ! 09/10/1999 Values of w2 and w4 in double precision
6983 ! to improve accuracy of computation of z
6984 ! 09/08/2002 Upgrade to release 4.0
6985 !
6986 ! 1. Purpose:
6987 !
6988 ! Compute locus function used for the determination of the
6989 ! resonance condition
6990 !
6991 ! 2. Method
6992 !
6993 ! Explicit function evaluation
6994 !
6995 ! 3. Parameter list:
6996 !
6997 !Type I/O Name Description
6998 !-----------------------------------------------------------
6999 real, intent(in) :: kxx ! x-component of wave number
7000 real, intent(in) :: kyy ! y-component of wave number
7001 !
7002 ! 4. Error messages
7003 !
7004 !
7005 ! 5. Called by:
7006 !
7007 ! Q_LOCPOS
7008 !
7009 ! 6. Subroutines used
7010 !
7011 ! X_DISPER
7012 !
7013 ! 7. Remarks
7014 !
7015 ! if iq_disp not valid, then q_disper = -1
7016 !
7017 ! 8. Structure
7018 !
7019 ! 9. Switches
7020 !
7021 ! 10. Source code:
7022 !-------------------------------------------------------------------------------
7023 ! Local variables
7024 !
7025 real z ! diferrence
7026 real k2m,k4m ! wave number magnitudes
7027 real(kind=8) w2,w4 ! radian frequencies
7028 !!real x_disper
7029 !------------------------------------------------------------------------------
7030 !call q_stack('+x_flocus')
7031 !
7032 select case(iq_disp)
7033  case (1)
7034  w2 = sqrtg * (kxx**2 + kyy**2)**(0.25)
7035  w4 = sqrtg * ((kxx+px)**2 + (kyy+py)**2)**(0.25)
7036  z = q + w2 - w4
7037 !
7038  case (2)
7039  k2m = sqrt(kxx**2+kyy**2)
7040  k4m = sqrt((kxx+px)**2 + (kyy+py)**2)
7041  w2 = x_disper(k2m,q_depth)
7042  w4 = x_disper(k4m,q_depth)
7043  z = q + w2 - w4
7044 !
7045  case default
7046  z = -1
7047  end select
7048 !
7049 x_flocus = z
7050 !
7051 !call q_stack('-x_flocus')
7052 !
7053 return
7054 end function
7055 !------------------------------------------------------------------------------
7071 
7072 real function x_jacobian(x2,y2,x4,y4)
7073 !------------------------------------------------------------------------------
7074 !
7075 ! +-------+ ALKYON Hydraulic Consultancy & Research
7076 ! | | Gerbrant van Vledder
7077 ! | +---+
7078 ! | | +---+ Last update: 9 Aug. 2002
7079 ! +---+ | | Release: 4.0
7080 ! +---+
7081 !
7082 ! do not use m_xnldata
7083 !% use serv_xnl4v5, only: z_cmpcg
7084 !
7085 implicit none
7086 !
7087 ! 0. Update history
7088 !
7089 ! 25/02/1999 Initial version
7090 ! 12/10/1999 Overflow avoided by checking for argument k*d
7091 ! 29/10/1999 Bug fixed in computing finite depth gradient
7092 ! 27/12/1999 Factor SQRT(Grav) added
7093 ! 01/10/2001 Components of k4 wave number explicitly input
7094 ! New version of function X_GRAD
7095 ! 09/08/2002 Computation of Jacobian replace by |cg2-cg4|
7096 ! based on old routine X_GRAD2
7097 ! Upgrade to release 4.0
7098 !
7099 ! 1. Purpose:
7100 !
7101 ! Compute gradient/Jacobian term for a given point on the locus
7102 !
7103 ! 2. Method
7104 !
7105 ! Explicit expressions for gradient term
7106 ! Using expression of Rasmussen (1998)
7107 ! J = |cg2-cg4|
7108 !
7109 ! 3. Parameter list:
7110 !
7111 ! Type I/O Name Description
7112 !--------------------------------------------------------------------
7113 real, intent(in) :: x2 ! x-component of wave number k2
7114 real, intent(in) :: y2 ! y-component of wave number k2
7115 real, intent(in) :: x4 ! x-component of wave number k4
7116 real, intent(in) :: y4 ! y-component of wave number k4
7117 !
7118 ! 4. Error messages
7119 !
7120 ! 5. Called by:
7121 !
7122 ! Q_CMPLOCUS
7123 !
7124 ! 6. Subroutines used:
7125 !
7126 ! 7. Remarks
7127 !
7128 ! 8. Structure
7129 !
7130 ! 9. Switches
7131 !
7132 ! 10. Source code:
7133 !------------------------------------------------------------------------------
7134 ! local variables
7135 !
7136 real k2m,k4m ! wave number magnitudes
7137 real k2md,k4md ! k*d values
7138 real ang2,ang4 ! directions
7139 real cg2,cg4 ! group velocities
7140 real sig2,sig4 ! radian frequencies
7141 !------------------------------------------------------------------------------
7142 k2m = sqrt(x2**2 + y2**2)
7143 k4m = sqrt(x4**2 + y4**2)
7144 !
7145 ang2 = atan2(x2,y2)
7146 ang4 = atan2(x4,y4)
7147 !
7148 sig2 = sqrt(q_grav*k2m*tanh(k2m*q_depth))
7149 sig4 = sqrt(q_grav*k4m*tanh(k4m*q_depth))
7150 !
7151 k2md = k2m*q_depth
7152 k4md = k4m*q_depth
7153 !
7154 if(k2md > 20) then
7155  cg2 = 0.5*q_grav/sig2
7156 else
7157  cg2 = sig2/k2m*(0.5+k2md/sinh(2*k2md))
7158 end if
7159 !
7160 if(k4md > 20) then
7161  cg4 = 0.5*q_grav/sig4
7162 else
7163  cg4 = sig4/k4m*(0.5+k4md/sinh(2*k4md))
7164 end if
7165 !
7166 x_jacobian = sqrt(cg2**2+cg4**2-2*cg2*cg4*cos(ang2-ang4))
7167 !
7168 return
7169 end function
7170 !------------------------------------------------------------------------------
7189 
7190 real function x_disper(k,d)
7191 !------------------------------------------------------------------------------
7192 !
7193 ! +-------+ ALKYON Hydraulic Consultancy & Research
7194 ! | | Gerbrant van Vledder
7195 ! | +---+
7196 ! | | +---+ Last update: 9 Aug. 2002
7197 ! +---+ | | Release: 4.0
7198 ! +---+
7199 !
7200 ! do not use m_xnldata
7201 implicit none
7202 !
7203 ! 0. Update history
7204 !
7205 ! 16/02/1999 Initial version
7206 ! 25/02/1999 Short cut if kd > 10
7207 ! 09/08/2002 Upgrade to release 4.0
7208 !
7209 ! 1. Purpose:
7210 !
7211 ! Compute radian frequency for a given wave number and water depth
7212 !
7213 ! 2. Method
7214 !
7215 ! Depending on the value of the parameter iq_disp the radian
7216 ! wave number is computed as:
7217 ! 1) deep water
7218 ! 2) finite depth linear dispersion relation
7219 ! 3) finited depth non-linear dispersion relation (NOT YET implemented)
7220 !
7221 ! 3. Parameter list:
7222 !
7223 ! Type I/O Name Description
7224 !----------------------------------------------------------------------
7225 real, intent(in) :: k ! wave number
7226 real, intent(in) :: d ! water depth in m
7227 !
7228 ! 4. Error messages
7229 !
7230 ! if iq_type not valid, then q_disper = -1
7231 !
7232 ! 5. Called by:
7233 !
7234 ! Q_CHKRES
7235 !
7236 ! 6. Subroutines used
7237 !
7238 !
7239 ! 7. Remarks
7240 !
7241 ! Type of dispersion relation is determined by the parameter IQ_DISP:
7242 !
7243 ! IQ_DISP==1 deep water linear disperion relation is used
7244 ! 2 finite depth linear dispersion relation is used
7245 !
7246 ! 8. Structure
7247 !
7248 ! 9. Switches
7249 !
7250 ! 10. Source code
7251 !------------------------------------------------------------------------------
7252 ! Local variables
7253 !
7254 integer id ! copy of iq_type
7255 real kd ! k*d
7256 !
7257 kd = k * d
7258 id = iq_disp
7259 !
7260 if (kd > 20.) id = 1
7261 !
7262 select case(id)
7263  case (1) ! deep water w^2=g k
7264  x_disper = sqrt(q_grav*k)
7265  case (2) ! finite depth w^2 = g k tanh(k d)
7266  x_disper = sqrt(q_grav*k*tanh(k*d))
7267  case default
7268  x_disper = -1.
7269 end select
7270 !
7271 return
7272 end function
7273 !------------------------------------------------------------------------------
7284 
7285 real function x_locus1(k2)
7286 !------------------------------------------------------------------------------
7287 !
7288 ! +-------+ ALKYON Hydraulic Consultancy & Research
7289 ! | | Gerbrant van Vledder
7290 ! | +---+
7291 ! | | +---+ Last update: 9 AUg. 2002
7292 ! +---+ | | Release: 4.0
7293 ! +---+
7294 !
7295 ! do not use m_xnldata
7296 use m_constants
7297 implicit none
7298 !
7299 ! 0. Update history
7300 !
7301 ! Date Description
7302 !
7303 ! 23/11/1999 Initial version
7304 ! 9/08/2002 Upgrade to release 4.0
7305 !
7306 ! 1. Purpose:
7307 !
7308 ! Compute locus function along symmetry axis
7309 !
7310 ! 2. Method
7311 !
7312 ! See ALKYON, 1999
7313 !
7314 ! 3. Parameter list:
7315 !
7316 !Type I/O name Description
7317 !-------------------------------------------------------
7318 real, intent(in) :: k2 ! Magnitude of wave number k2
7319 !
7320 ! 4. Error messages
7321 !
7322 ! 5. Called by:
7323 !
7324 ! Q_LOCPOS
7325 !
7326 ! 6. Subroutines used
7327 !
7328 ! x_disper
7329 !
7330 ! 7. Remarks
7331 !
7332 ! The routine assumes that w1 < w3 or q<0
7333 ! implying that the directions of k2 and P are opposite
7334 !
7335 ! 8. Structure
7336 !
7337 ! 9. Switches
7338 !
7339 ! 10. Source code
7340 !------------------------------------------------------------------------------
7341 ! Local variables
7342 !
7343 real k4 ! wave number magnitudes of k4
7344 real w2,w4 ! radian frequencies of wave numbers k2 and k4
7345 real z ! function value
7346 !
7347 !!real x_disper
7348 !
7349 select case(iq_disp)
7350  case (1)
7351  w2 = sqrtg * sqrt(k2)
7352  w4 = sqrtg * sqrt(abs(-pmag+k2))
7353  z = q + w2 - w4
7354 !
7355  case (2)
7356  k4 = abs(-pmag+k2)
7357  w2 = x_disper(k2,q_depth)
7358  w4 = x_disper(k4,q_depth)
7359  z = q + w2 - w4
7360 !
7361  case default
7362  z = -1
7363  end select
7364 !
7365 x_locus1 = z
7366 !
7367 return
7368 end function
7369 !------------------------------------------------------------------------------
7380 
7381 real function x_locus2(lambda)
7382 !------------------------------------------------------------------------------
7383 !
7384 ! +-------+ ALKYON Hydraulic Consultancy & Research
7385 ! | | Gerbrant van Vledder
7386 ! | +---+
7387 ! | | +---+ Last update: 9 Aug. 2002
7388 ! +---+ | | Release: 4.0
7389 ! +---+
7390 !
7391 ! do not use m_xnldata
7392 use m_constants
7393 implicit none
7394 !
7395 ! 0. Update history
7396 !
7397 ! Date Description
7398 !
7399 ! 23/11/1999 Initial version
7400 ! 09/08/2002 Upgrade to release 4.0
7401 !
7402 ! 1. Purpose:
7403 !
7404 ! Compute locus function perpendicluar to symmetry axis
7405 !
7406 ! 2. Method
7407 !
7408 ! See ALKYON, 1999
7409 !
7410 ! 3. Parameter list:
7411 !
7412 ! Name I/O Type Description
7413 !
7414 real, intent(in) :: lambda
7415 !
7416 ! 4. Error messages
7417 !
7418 ! 5. Called by:
7419 !
7420 ! Q_LOCPOS
7421 !
7422 ! 6. Subroutines used
7423 !
7424 ! x_disper
7425 !
7426 ! 7. Remarks
7427 !
7428 ! The routine assumes that w1 < w3 or q<0
7429 ! implying that the directions of k2 and P are opposite
7430 !
7431 ! 8. Structure
7432 !
7433 ! 9. Switches
7434 !
7435 ! 10. Source code:
7436 !------------------------------------------------------------------------------
7437 ! local variables
7438 !
7439 real kk2x,kk2y,kk2m ! wave number components and magnitude for k2
7440 real kk4x,kk4y,kk4m ! wave number components and magnitude for k4
7441 real w2,w4 ! radian frequencies of wave numbers k2 and k4
7442 real z ! function value
7443 !!real x_disper
7444 kk2x = kmidx - lambda*py
7445 kk2y = kmidy + lambda*px
7446 kk2m = sqrt(kk2x**2 + kk2y**2)
7447 !
7448 kk4x = kk2x + px
7449 kk4y = kk2y + py
7450 kk4m = sqrt(kk4x**2 + kk4y**2)
7451 !
7452 select case(iq_disp)
7453  case (1)
7454  w2 = sqrtg * sqrt(kk2m)
7455  w4 = sqrtg * sqrt(kk4m)
7456  z = q + w2 - w4
7457 !
7458  case (2)
7459 !
7460  w2 = x_disper(kk2m,q_depth)
7461  w4 = x_disper(kk4m,q_depth)
7462  z = q + w2 - w4
7463 !
7464  case default
7465  z = -1
7466  end select
7467 !
7468 x_locus2 = z
7469 !
7470 return
7471 end function
7472 !------------------------------------------------------------------------------
7489 
7490 real function xc_hh(w1x0,w1y0,w2x0,w2y0,w3x0,w3y0,z4x,z4y,h)
7491 !------------------------------------------------------------------------------
7492 !
7493 ! factor EPS included
7494 !
7495 implicit none
7496 !
7497 real z4x,z4y ! dummy arguments
7498 !
7499 real w1x0,w1y0,w2x0,w2y0,w3x0,w3y0,h,dsq
7500 real om1,om2,om3,om4,scpl1,scpl2,scpl3,stot
7501 real t1,t2,t3,t4,t5,tot1,tot2,tot3,tot4,tot5
7502 real som1,som2,som3
7503 real s1,s2,s3,z1,z2,z3,z4,z5
7504 real p1,p2,p3,p4,di,tnz1,tnz2,tnz3,tnz23
7505 real csz1,csz2,csz3,csz23
7506 real e,g,gsq,omsq23,pi4
7507 real dot123,dot23
7508 !!real cosz,tanz
7509 !
7510 real eps
7511 !
7512 
7513 ! calculates coupling coefficient in shallow water given k1,k2,k3
7514  real k1,k2,k3,k1x,k2x,k3x,k1y,k2y,k3y,k23x,k23y,k23,k1x0,k1y0, &
7515  & k2x0,k2y0,k3x0,k3y0,k1zx,k1zy
7516  data pi4/0.785398163/
7517 !
7518 eps = 1.e-20
7519 g = 9.81
7520 !
7521 z4x = z4x
7522 z4y = z4y
7523 !
7524 ! print *,'entering cplesh depth = ',h
7525  k1x0=w1x0
7526  k1y0=w1y0
7527  k2x0=w2x0
7528  k2y0=w2y0
7529  k3x0=w3x0
7530  k3y0=w3y0
7531 
7532  tot1=0.
7533  tot2=0.
7534  tot3=0.
7535  tot4=0.
7536  tot5=0.
7537  z1=0.
7538  z2=0.
7539  z3=0.
7540  z4=0.
7541  z5=0.
7542  g=9.81
7543  gsq=g*g
7544 
7545  s1=1.
7546  s2=1.
7547  s3=-1.
7548 
7549 
7550  k1x=s1*k1x0
7551  k1y=s1*k1y0
7552  k2x=s2*k2x0
7553  k2y=s2*k2y0
7554  k3x=s3*k3x0
7555  k3y=s3*k3y0
7556 
7557  k1=sqrt(k1x**2+k1y**2)
7558  k2=sqrt(k2x**2+k2y**2)
7559  k3=sqrt(k3x**2+k3y**2)
7560 
7561  tnz1=tanz(k1*h)
7562  tnz2=tanz(k2*h)
7563  tnz3=tanz(k3*h)
7564  csz1=cosz(k1*h)
7565  csz2=cosz(k2*h)
7566  csz3=cosz(k3*h)
7567  om1=sqrt(g*k1*tnz1)
7568  om2=sqrt(g*k2*tnz2)
7569  om3=sqrt(g*k3*tnz3)
7570 
7571  som1=s1*om1
7572  som2=s2*om2
7573  som3=s3*om3
7574  dot23=k2x*k3x+k2y*k3y
7575 
7576  k23x=k2x+k3x
7577  k23y=k2y+k3y
7578  k23=sqrt(k23x**2+k23y**2)
7579  tnz23=tanz(k23*h)
7580  csz23=cosz(k23*h)
7581 
7582  omsq23=g*k23*tnz23
7583  dot123=k1x*k23x+k1y*k23y
7584 
7585 ! note the "i**2" factor is included in this term
7586  di=-(som2+som3)*(k2*k3*tnz2*tnz3-dot23) &
7587  & +0.5*(som2*k3**2/(csz3)**2+som3*k2**2/(csz2)**2)
7588 
7589  e=0.5/g *(dot23-som2*som3/gsq*(om2**2+om3**2+som2*som3))
7590 
7591  p1=2.*(som1+som2+som3)*(om1**2.*omsq23/gsq-dot123)
7592 
7593  p2=-som1*(k23)**2/(csz23)**2
7594 
7595  p3=-(som2+som3)*k1**2/(csz1)**2
7596 
7597  z1=z1+di
7598  z2=z2+omsq23-(som2+som3)**2
7599  z3=z3+p1
7600  z4=z4+p2
7601  z5=z5+p3
7602  t1=di/(omsq23-(som2+som3)**2 + eps ) * (p1+p2+p3)
7603 
7604  t2=-di*som1/gsq *(om1**2+omsq23)
7605 
7606  p4=g*k1**2/(csz1)**2
7607 
7608  t3=e*(som1**3*(som2+som3)/g - g*dot123 - p4)
7609 
7610  t4=0.5*som1/gsq*dot23*((som1+som2+som3)*(om2**2+om3**2) &
7611  & +som2*som3*(som2+som3))
7612 
7613  t5=-0.5*som1*om2**2*k3**2/gsq*(som1+som2+2.*som3) &
7614  & -0.5*som1*om3**2*k2**2/gsq*(som1+2.*som2+som3)
7615 
7616  scpl1=t1+t2+t3+t4+t5
7617  tot1=tot1+t1
7618  tot2=tot2+t2
7619  tot3=tot3+t3
7620  tot4=tot4+t4
7621  tot5=tot5+t5
7622 
7623  s1=1.
7624  s2=-1.
7625  s3=1.
7626  k1zx=k1x0
7627  k1zy=k1y0
7628  k1x0=k2x0
7629  k1y0=k2y0
7630  k2x0=k3x0
7631  k2y0=k3y0
7632  k3x0=k1zx
7633  k3y0=k1zy
7634 
7635 
7636  k1x=s1*k1x0
7637  k1y=s1*k1y0
7638  k2x=s2*k2x0
7639  k2y=s2*k2y0
7640  k3x=s3*k3x0
7641  k3y=s3*k3y0
7642 
7643  k1=sqrt(k1x**2+k1y**2)
7644  k2=sqrt(k2x**2+k2y**2)
7645  k3=sqrt(k3x**2+k3y**2)
7646  tnz1=tanz(k1*h)
7647  tnz2=tanz(k2*h)
7648  tnz3=tanz(k3*h)
7649  csz1=cosz(k1*h)
7650  csz2=cosz(k2*h)
7651  csz3=cosz(k3*h)
7652  om1=sqrt(g*k1*tnz1)
7653  om2=sqrt(g*k2*tnz2)
7654  om3=sqrt(g*k3*tnz3)
7655  som1=s1*om1
7656  som2=s2*om2
7657  som3=s3*om3
7658  dot23=k2x*k3x+k2y*k3y
7659  k23x=k2x+k3x
7660  k23y=k2y+k3y
7661  k23=sqrt(k23x**2+k23y**2)
7662  tnz23=tanz(k23*h)
7663  csz23=cosz(k23*h)
7664  omsq23=g*k23*tnz23
7665  dot123=k1x*k23x+k1y*k23y
7666 
7667 ! note the "i**2" factor is included in this term
7668  di=-(som2+som3)*(k2*k3*tnz2*tnz3-dot23) &
7669  & +0.5*(som2*k3**2/(csz3)**2+som3*k2**2/(csz2)**2)
7670 
7671  e=0.5/g *(dot23-som2*som3/gsq *(om2**2+om3**2+som2*som3))
7672 
7673  p1=2.*(som1+som2+som3)*(om1**2.*omsq23/gsq-dot123)
7674 
7675  p2=-som1*(k23)**2/(csz23)**2
7676 
7677  p3=-(som2+som3)*k1**2/(csz1)**2
7678  z1=z1+di
7679  z2=z2+omsq23-(som2+som3)**2
7680  z3=z3+p1
7681  z4=z4+p2
7682  z5=z5+p3
7683 
7684  t1=di/(omsq23-(som2+som3)**2) * (p1+p2+p3)
7685 
7686  t2=-di*som1/gsq *(om1**2+omsq23)
7687 
7688  p4=g*k1**2/(csz1)**2
7689 
7690  t3=e*(som1**3*(som2+som3)/g - g*dot123 - p4)
7691 
7692  t4=0.5*som1/gsq*dot23*((som1+som2+som3)*(om2**2+om3**2) &
7693  & +som2*som3*(som2+som3))
7694 
7695  t5=-0.5*som1*om2**2*k3**2/gsq*(som1+som2+2.*som3) &
7696  & -0.5*som1*om3**2*k2**2/gsq*(som1+2.*som2+som3)
7697 
7698  scpl2=t1+t2+t3+t4+t5
7699  tot1=tot1+t1
7700  tot2=tot2+t2
7701  tot3=tot3+t3
7702  tot4=tot4+t4
7703  tot5=tot5+t5
7704 
7705  s1=-1.
7706  s2=1.
7707  s3=1.
7708  k1zx=k1x0
7709  k1zy=k1y0
7710  k1x0=k2x0
7711  k1y0=k2y0
7712  k2x0=k3x0
7713  k2y0=k3y0
7714  k3x0=k1zx
7715  k3y0=k1zy
7716 
7717 
7718  k1x=s1*k1x0
7719  k1y=s1*k1y0
7720  k2x=s2*k2x0
7721  k2y=s2*k2y0
7722  k3x=s3*k3x0
7723  k3y=s3*k3y0
7724 
7725  k1=sqrt(k1x**2+k1y**2)
7726  k2=sqrt(k2x**2+k2y**2)
7727  k3=sqrt(k3x**2+k3y**2)
7728  tnz1=tanz(k1*h)
7729  tnz2=tanz(k2*h)
7730  tnz3=tanz(k3*h)
7731  csz1=cosz(k1*h)
7732  csz2=cosz(k2*h)
7733  csz3=cosz(k3*h)
7734  om1=sqrt(g*k1*tnz1)
7735  om2=sqrt(g*k2*tnz2)
7736  om3=sqrt(g*k3*tnz3)
7737  som1=s1*om1
7738  som2=s2*om2
7739  som3=s3*om3
7740  dot23=k2x*k3x+k2y*k3y
7741  k23x=k2x+k3x
7742  k23y=k2y+k3y
7743  k23=sqrt(k23x**2+k23y**2)
7744  tnz23=tanz(k23*h)
7745  csz23=cosz(k23*h)
7746  omsq23=g*k23*tnz23
7747  dot123=k1x*k23x+k1y*k23y
7748 
7749 ! note the "i**2" factor is included in this term
7750  di=-(som2+som3)*(k2*k3*tnz2*tnz3-dot23) &
7751  & +0.5*(som2*k3**2/(csz3)**2+som3*k2**2/(csz2)**2)
7752 
7753  e=0.5/g *(dot23-som2*som3/gsq *(om2**2+om3**2+som2*som3))
7754 
7755  p1=2.*(som1+som2+som3)*(om1**2.*omsq23/gsq-dot123)
7756 
7757  p2=-som1*(k23)**2/(csz23)**2
7758 
7759  p3=-(som2+som3)*k1**2/(csz1)**2
7760  z1=z1+di
7761  z2=z2+omsq23-(som2+som3)**2
7762  z3=z3+p1
7763  z4=z4+p2
7764  z5=z5+p3
7765 
7766  t1=di/(omsq23-(som2+som3)**2) * (p1+p2+p3)
7767 
7768  t2=-di*som1/gsq*(om1**2+omsq23)
7769 
7770  p4=g*k1**2/(cosz(k1*h))**2
7771 
7772  t3=e*(som1**3*(som2+som3)/g - g*dot123 - p4)
7773 
7774  t4=0.5*som1/gsq*dot23*((som1+som2+som3)*(om2**2+om3**2) &
7775  & +som2*som3*(som2+som3))
7776 
7777  t5=-0.5*som1*om2**2*k3**2/gsq*(som1+som2+2.*som3) &
7778  & -0.5*som1*om3**2*k2**2/gsq*(som1+2.*som2+som3)
7779 
7780  scpl3=t1+t2+t3+t4+t5
7781  tot1=tot1+t1
7782  tot2=tot2+t2
7783  tot3=tot3+t3
7784  tot4=tot4+t4
7785  tot5=tot5+t5
7786 
7787  stot=(scpl1+scpl2+scpl3)
7788  om4=om2+om3-om1
7789  dsq=stot*stot*pi4*gsq/(om1*om2*om3*om4+eps) ! eps by GVV
7790  xc_hh = dsq
7791 !
7792 ! possible bug fixed
7793 !
7794  xc_hh = xc_hh*gsq
7795 !
7796  RETURN
7797  end function
7798 
7807 
7808  real function tanz(x)
7809  real x
7810 ! print *,'inside tanz '
7811  if (x.gt.20.) x=25.
7812  tanz=tanh(x)
7813 ! print *,'after def of tanz'
7814  return
7815  end function
7816 
7825 
7826  real function cosz(x)
7827  real x
7828  if (x.gt.20.) x=25.
7829  cosz=cosh(x)
7830  return
7831  end function
7832 
7833 
7834 !------------------------------------------------------------------------------
7854 
7855 real function xc_webb(k1x,k1y,k2x,k2y,k3x,k3y,k4x,k4y,grav)
7856 !------------------------------------------------------------------------------
7857 !
7858 ! +-------+ ALKYON Hydraulic Consultancy & Research
7859 ! | | Gerbrant van Vledder
7860 ! | +---+
7861 ! | | +---+ Last update: 10 Sep. 2002
7862 ! +---+ | | Release: 5.0
7863 ! +---+
7864 !
7865 implicit none
7866 !
7867 ! 0. Update history
7868 !
7869 ! 25/02/1999 Initial version
7870 ! 10/09/2002 Upgrade of documention and interface
7871 !
7872 ! 1. Purpose:
7873 !
7874 ! Compute deep water coupling coefficient for
7875 ! non-linear quadruplet interactions
7876 !
7877 !
7878 ! 2. Method
7879 !
7880 ! Webb (1978) and modified and corrected by Dungey and Hui (1979)
7881 !
7882 ! 3. Parameter list:
7883 !
7884 ! Type I/O Name Description
7885 !--------------------------------------------------------------------
7886 real, intent(in) :: k1x ! x-component of wave number k1
7887 real, intent(in) :: k1y ! y-component of wave number k1
7888 real, intent(in) :: k2x ! x-component of wave number k2
7889 real, intent(in) :: k2y ! y-component of wave number k2
7890 real, intent(in) :: k3x ! x-component of wave number k3
7891 real, intent(in) :: k3y ! y-component of wave number k3
7892 real, intent(in) :: k4x ! x-component of wave number k4
7893 real, intent(in) :: k4y ! y-component of wave number k4
7894 real, intent(in) :: grav ! gravitational acceleration m/s^2
7895 !
7896 ! 4. Error messages
7897 !
7898 ! 5. Called by:
7899 !
7900 ! X_CPLE
7901 !
7902 ! 6. Subroutines used:
7903 !
7904 ! 7. Remarks
7905 !
7906 ! 8. Structure
7907 !
7908 ! 9. Switches
7909 !
7910 ! 10. Source code:
7911 !------------------------------------------------------------------------------
7912 ! local variables
7913 !
7914 !
7915 double precision wsqp12 ! derived variable
7916 double precision wsqm13 ! derived variable
7917 double precision wsq13 ! derived variable
7918 double precision wsqm14 ! derived variable
7919 double precision wsq14 ! derived variable
7920 double precision wsq12 ! derived variable
7921 real z,z12,z13,z14 ! derived variables
7922 real dwebb ! final coefficient
7923 real p1,p2,p3,p4,p5,p6,p7,p8,p9 ! partial summations
7924 real w1,w2,w3,w4 ! radian frequencies
7925 real k1,k2,k3,k4 ! wave number magnitudes
7926 real dot12 ! k1*k2
7927 real dot13 ! k1*k3
7928 real dot14 ! k1*k4
7929 real dot23 ! k2*k3
7930 real dot24 ! k2*k4
7931 real dot34 ! k3*k4
7932 real pi ! pi
7933 real pi4 ! pi/4
7934 real eps ! internal accuracy
7935 !---------------------------------------------------------------------
7936 ! initialisations
7937 !---------------------------------------------------------------------
7938 pi = 4.*atan(1.)
7939 pi4 = 0.25*pi
7940 !
7941 eps = 1.0e-30
7942 !
7943 k1 = sqrt(k1x*k1x + k1y*k1y)
7944 k2 = sqrt(k2x*k2x + k2y*k2y)
7945 k3 = sqrt(k3x*k3x + k3y*k3y)
7946 k4 = sqrt(k4x*k4x + k4y*k4y)
7947 !
7948 w1 = sqrt(k1)
7949 w2 = sqrt(k2)
7950 w3 = sqrt(k3)
7951 w4 = sqrt(k4)
7952 !
7953 dot12 = k1x*k2x + k1y*k2y
7954 dot13 = k1x*k3x + k1y*k3y
7955 dot14 = k1x*k4x + k1y*k4y
7956 dot23 = k2x*k3x + k2y*k3y
7957 dot24 = k2x*k4x + k2y*k4y
7958 dot34 = k3x*k4x + k3y*k4y
7959 !
7960 wsqp12= sqrt((k1x+k2x)*(k1x+k2x)+(k1y+k2y)*(k1y+k2y))
7961 wsq12 = (w1+w2)*(w1+w2)
7962 wsqm13= sqrt((k1x-k3x)*(k1x-k3x)+(k1y-k3y)*(k1y-k3y))
7963 wsq13 = (w1-w3)*(w1-w3)
7964 wsqm14= sqrt((k1x-k4x)*(k1x-k4x)+(k1y-k4y)*(k1y-k4y))
7965 wsq14 = (w1-w4)*(w1-w4)
7966 z12 = wsqp12-wsq12
7967 z13 = wsqm13-wsq13
7968 z14 = wsqm14-wsq14
7969 z = 2.*wsq12*(k1*k2-dot12)*(k3*k4-dot34)
7970 p1 = z/(z12+eps)
7971 z = 2.*wsq13*(k1*k3+dot13)*(k2*k4+dot24)
7972 p2 = z/(z13+eps)
7973 z = 2.*wsq14*(k1*k4+dot14)*(k2*k3+dot23)
7974 p3 = z/(z14+eps)
7975 p4 = 0.5 *(dot12*dot34 + dot13*dot24 + dot14*dot23)
7976 p5 = 0.25*(dot13+dot24) * wsq13 * wsq13
7977 p6 = -0.25*(dot12+dot34) * wsq12 * wsq12
7978 p7 = 0.25*(dot14+dot23) * wsq14 * wsq14
7979 p8 = 2.5*k1*k2*k3*k4
7980 p9 = wsq12*wsq13*wsq14* (k1 + k2 + k3 + k4)
7981 !
7982 dwebb = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9
7983 xc_webb = grav**2*pi4*dwebb*dwebb/(w1*w2*w3*w4+eps)
7984 !
7985 return
7986 end function
7987 !
7988 end module
m_xnldata::quad_zz
real, dimension(:,:,:), allocatable quad_zz
compound product of cple*ds*sym/jac
Definition: mod_xnl4v5.f90:272
m_xnldata::q_scale
real q_scale
additional scale factor resulting from SEARCH for neasrest grid
Definition: mod_xnl4v5.f90:369
m_xnldata::rel_k
real rel_k
relative accuracy for equality check of k
Definition: mod_xnl4v5.f90:373
m_xnldata::q_cmplocus
subroutine q_cmplocus(ka, kb, km, kw, loclen)
Compute locus function used for the determination of the resonnance condition.
Definition: mod_xnl4v5.f90:1677
m_xnldata::q_grav
real q_grav
gravitational acceleration (Earth = 9.81 m/s^2)
Definition: mod_xnl4v5.f90:66
m_xnldata::t_w4k2
real, dimension(:), allocatable t_w4k2
transformed weight 4 for k2
Definition: mod_xnl4v5.f90:325
m_xnldata::r_w4k2
real, dimension(:), allocatable r_w4k2
corresponding declarations
Definition: mod_xnl4v5.f90:338
m_xnldata::q_polar2
subroutine q_polar2(kmin, kmax, kx_beg, ky_beg, kx_end, ky_end, loclen, ierr)
Compute position of locus for given k1-k3 vector.
Definition: mod_xnl4v5.f90:4535
m_xnldata::wk_k2
real, dimension(:), allocatable wk_k2
position of k2 and k4 wave number
Definition: mod_xnl4v5.f90:311
m_xnldata::q_df
real, dimension(:), allocatable q_df
step size of frequency grid
Definition: mod_xnl4v5.f90:352
m_xnldata::q_f
real, dimension(:), allocatable q_f
frequencies accociated to wave number/depth
Definition: mod_xnl4v5.f90:351
m_xnldata::qf_krat
real qf_krat
maximum ratio of the interacting wave numbers k1 and k3
Definition: mod_xnl4v5.f90:72
m_xnldata::k4a_mod
real, dimension(:), allocatable k4a_mod
k4 angle around locus
Definition: mod_xnl4v5.f90:307
m_xnldata::luq_loc
integer luq_loc
statistics about computed loci
Definition: mod_xnl4v5.f90:56
m_xnldata::fqmax
real fqmax
highest frequency in Hz
Definition: mod_xnl4v5.f90:207
m_xnldata::loc_yz
real loc_yz
y-coordinate of center of gravity of locus in (kx,ky)-space
Definition: mod_xnl4v5.f90:246
m_xnldata::loc_area
real loc_area
area of locus, measured in (kx-ky)- space
Definition: mod_xnl4v5.f90:244
m_xnldata::quad_ik4
integer, dimension(:,:,:), allocatable quad_ik4
lower wave number index of k4
Definition: mod_xnl4v5.f90:262
m_xnldata::kmid
real kmid
wave number at midpoint of locus along symmetry axis
Definition: mod_xnl4v5.f90:240
m_xnldata::ds_mod
real, dimension(:), allocatable ds_mod
step size around locus
Definition: mod_xnl4v5.f90:299
m_xnldata::k4y
real k4y
components of k4 wave number
Definition: mod_xnl4v5.f90:231
m_xnldata::q_deltad
real q_deltad
directional spacing of angular grid in degrees
Definition: mod_xnl4v5.f90:391
m_xnldata::x_disper
real function x_disper(k, d)
Compute radian frequency for a given wave number and water depth.
Definition: mod_xnl4v5.f90:7191
m_xnldata::iq_type
integer iq_type
method for computing the nonlinear interactions depending on the value of iq_type a number of setting...
Definition: mod_xnl4v5.f90:414
m_xnldata::q_modify
subroutine q_modify
Modify points along the locus, such that they are evenly distributed only when intended,...
Definition: mod_xnl4v5.f90:4149
serv_xnl4v5::z_cmpcg
subroutine z_cmpcg(sigma, depth, grav, cg)
Definition: serv_xnl4v5.f90:46
serv_xnl4v5::z_steps
subroutine z_steps(x, dx, nx)
Definition: serv_xnl4v5.f90:382
m_xnldata::r_w2k4
real, dimension(:), allocatable r_w2k4
Definition: mod_xnl4v5.f90:339
m_xnldata::iaq2
integer iaq2
indices of do-loop for directions
Definition: mod_xnl4v5.f90:387
m_xnldata::a_pol
real, dimension(:), allocatable a_pol
angles of polar locus
Definition: mod_xnl4v5.f90:289
m_xnldata::iamax
integer iamax
maximum difference in indices for sector grids
Definition: mod_xnl4v5.f90:386
m_xnldata::k4x
real k4x
Definition: mod_xnl4v5.f90:231
m_xnldata::nk1d
real, dimension(:), allocatable nk1d
Internal 1d action density spectrum N(k)
Definition: mod_xnl4v5.f90:360
m_xnldata::luq_cfg
integer luq_cfg
user defined configuration
Definition: mod_xnl4v5.f90:51
m_xnldata::q_sector
real q_sector
half plane width in degrees (for iq_grid=1,2)
Definition: mod_xnl4v5.f90:208
m_xnldata::k2m_mod
real, dimension(:), allocatable k2m_mod
k2 magnitude around locus
Definition: mod_xnl4v5.f90:304
m_xnldata::luq_grd
integer luq_grd
ASCII file storing and retrieving precomputed loci.
Definition: mod_xnl4v5.f90:54
m_xnldata::iq_compact
integer iq_compact
switch to compact data == 0, do not compact == 1, compact data by elimiting zero contribution along l...
Definition: mod_xnl4v5.f90:78
m_xnldata::r_ws
real, dimension(:), allocatable r_ws
corresponding declarations
Definition: mod_xnl4v5.f90:340
m_fileio::z_fclose
subroutine z_fclose(iunit)
Close file with unit number IUNIT, and set IUNIT=-1.
Definition: mod_fileio.f90:364
m_xnldata::q_getlocus
subroutine q_getlocus(ik1, ia1, ik3, ia3, ifnd)
Retrieve locus from basic locus as stored in the database.
Definition: mod_xnl4v5.f90:2742
m_xnldata::z_mod
real, dimension(:), allocatable z_mod
data value around locus
Definition: mod_xnl4v5.f90:297
m_xnldata::quad_w1k4
real, dimension(:,:,:), allocatable quad_w1k4
weight 1 of k4
Definition: mod_xnl4v5.f90:268
m_xnldata::r_header
character(len=21) r_header
header of Binary Quadruplet File as exists in BQF-file
Definition: mod_xnl4v5.f90:196
m_xnldata::ncirc
integer ncirc
number of angles on a full circle
Definition: mod_xnl4v5.f90:201
m_xnldata::iscreen
integer iscreen
identifier for screen, set in XNL_INIT
Definition: mod_xnl4v5.f90:46
m_xnldata::q_chkconfig
subroutine q_chkconfig
Check configuration for computation of non-linear transfer.
Definition: mod_xnl4v5.f90:1237
m_xnldata::q_a
real, dimension(:), allocatable q_a
directions of quadruplet grid in radians
Definition: mod_xnl4v5.f90:356
m_xnldata::ds_loc
real, dimension(:), allocatable ds_loc
step size around locus
Definition: mod_xnl4v5.f90:282
m_xnldata::cosz
real function cosz(x)
N/A.
Definition: mod_xnl4v5.f90:7827
serv_xnl4v5::z_root2
real function z_root2(func, x1, x2, xacc, iprint, ierr)
Definition: serv_xnl4v5.f90:432
m_xnldata::nlocus
integer nlocus
number of points on locus, equal to klocus
Definition: mod_xnl4v5.f90:219
m_xnldata::wt_k2
real, dimension(:), allocatable wt_k2
weight factor in tail,
Definition: mod_xnl4v5.f90:315
m_xnldata::luq_bqf
integer luq_bqf
binary file storing and retrieving precomputed loci
Definition: mod_xnl4v5.f90:50
m_xnldata::mlocus
integer mlocus
maximum number of points on locus for defining arrays
Definition: mod_xnl4v5.f90:213
m_xnldata::q_loc_w1w3
subroutine q_loc_w1w3(k1x, k1y, k3x, k3y, npts, k2x, k2y, k4x, k4y, s)
Compute locus for the special case w1=w3.
Definition: mod_xnl4v5.f90:6221
m_xnldata::quad_nloc
integer, dimension(:,:), allocatable quad_nloc
number of points on locus
Definition: mod_xnl4v5.f90:259
m_xnldata::quad_w4k2
real, dimension(:,:,:), allocatable quad_w4k2
weight 4 of k2
Definition: mod_xnl4v5.f90:267
m_xnldata::iq_test
integer iq_test
test level, output is directed to unit luqtst == 0, no test output == 1, output of basic I/O == 2,...
Definition: mod_xnl4v5.f90:165
m_xnldata::sym_mod
real, dimension(:), allocatable sym_mod
factor for symmetry between k3 and k4
Definition: mod_xnl4v5.f90:302
m_xnldata::q_ang2
real q_ang2
lower and upper angle of grid in degrees
Definition: mod_xnl4v5.f90:389
m_xnldata::q_sk
real, dimension(:), allocatable q_sk
step size of extended wave number array
Definition: mod_xnl4v5.f90:345
m_xnldata::q_allocate
subroutine q_allocate
Check configuration for non-linear transfer.
Definition: mod_xnl4v5.f90:1012
m_xnldata::pang
real pang
angle related of P-vector, Pang = atan2(py,px), (radians)
Definition: mod_xnl4v5.f90:234
m_xnldata::iq_geom
integer iq_geom
type of scaling == 0, no geometric scaling, only directional scaling of loci == 1,...
Definition: mod_xnl4v5.f90:107
m_xnldata::q_ang1
real q_ang1
Definition: mod_xnl4v5.f90:389
m_xnldata::q_searchgrid
subroutine q_searchgrid(depth, igrid)
Search nearest valid grid, read grid file and scale factor.
Definition: mod_xnl4v5.f90:5051
m_xnldata::iq_integ
integer iq_integ
option to output integration results ==0 no output of integration ==1 only sum per locus ==2 also inf...
Definition: mod_xnl4v5.f90:117
m_xnldata::q_ctrgrid
subroutine q_ctrgrid(itask, igrid)
Control of interaction grid administration.
Definition: mod_xnl4v5.f90:1968
m_xnldata::luq_trf
integer luq_trf
testing transformation of loci
Definition: mod_xnl4v5.f90:59
m_xnldata::q_depth
real q_depth
local water depth in m
Definition: mod_xnl4v5.f90:365
m_xnldata::s_mod
real, dimension(:), allocatable s_mod
coordinate along locus
Definition: mod_xnl4v5.f90:298
m_xnldata::q_init
subroutine q_init
Initializing module for quadruplets and setting default settings.
Definition: mod_xnl4v5.f90:3121
m_xnldata::k3y
real k3y
components of k3 wave number
Definition: mod_xnl4v5.f90:230
m_xnldata::q_setconfig
subroutine q_setconfig(iquad)
Set settings for computing the nonlinear interactions.
Definition: mod_xnl4v5.f90:4795
m_xnldata::r_jac
real, dimension(:), allocatable r_jac
Definition: mod_xnl4v5.f90:340
m_xnldata::a
real, dimension(:,:), allocatable a
Action density on wave number grid A(sigma,theta)
Definition: mod_xnl4v5.f90:358
m_xnldata::k1x
real k1x
Definition: mod_xnl4v5.f90:228
m_constants::rade
real rade
conversion from radians to degrees
Definition: mod_constants.f90:33
m_xnldata::crf1
real crf1
estimated circumference of locus
Definition: mod_xnl4v5.f90:380
m_xnldata::quad_w2k2
real, dimension(:,:,:), allocatable quad_w2k2
weight 2 of k2
Definition: mod_xnl4v5.f90:265
m_xnldata::q_cg
real, dimension(:), allocatable q_cg
group velocity (m/s)
Definition: mod_xnl4v5.f90:355
m_xnldata::jac_loc
real, dimension(:), allocatable jac_loc
jacobian term around locus
Definition: mod_xnl4v5.f90:283
m_xnldata::q_setversion
subroutine q_setversion
Subroutine has automatically been written by MODULE5.
Definition: mod_xnl4v5.f90:5279
m_xnldata::q_ffac
real q_ffac
geometric factor between subsequent frequencies
Definition: mod_xnl4v5.f90:393
m_xnldata::qnl
real, dimension(:,:), allocatable qnl
Nonlinear energy transfer Snl(k,theta)
Definition: mod_xnl4v5.f90:361
m_xnldata::mq_stack
integer, parameter mq_stack
maximum number of elements in stack
Definition: mod_xnl4v5.f90:211
m_xnldata::x_locus1
real function x_locus1(k2)
Compute locus function along symmetry axis.
Definition: mod_xnl4v5.f90:7286
m_xnldata::k2y
real k2y
components of k2 wave number
Definition: mod_xnl4v5.f90:229
m_xnldata::iq_grid
integer iq_grid
type of spectral grid == 1, sector & symmetric around zero == 2, sector & symmetric around zero & non...
Definition: mod_xnl4v5.f90:112
m_xnldata::k2x
real k2x
Definition: mod_xnl4v5.f90:229
m_xnldata::x_jacobian
real function x_jacobian(x2, y2, x4, y4)
Compute gradient/Jacobian term for a given point on the locus.
Definition: mod_xnl4v5.f90:7073
m_xnldata::r_ik2
integer, dimension(:), allocatable r_ik2
corresponding declarations r_ik2
Definition: mod_xnl4v5.f90:334
m_xnldata::q_version
character(len=60) q_version
version string
Definition: mod_xnl4v5.f90:39
m_xnldata::q_dird2
real q_dird2
first and last direction of host model (via XNL_INIT) degrees
Definition: mod_xnl4v5.f90:364
m_xnldata::fqmin
real fqmin
lowest frequency in Hz
Definition: mod_xnl4v5.f90:206
m_xnldata::qf_tail
real qf_tail
power of spectral tail of E(f), e.g.
Definition: mod_xnl4v5.f90:67
m_xnldata::loc_crf
real loc_crf
circumference of locus in (kx,ky)-space
Definition: mod_xnl4v5.f90:243
m_xnldata::k0y
real k0y
Definition: mod_xnl4v5.f90:226
m_xnldata::quad_w3k2
real, dimension(:,:,:), allocatable quad_w3k2
weight 3 of k2
Definition: mod_xnl4v5.f90:266
m_xnldata::dt13
real, dimension(:), allocatable dt13
increment along locus
Definition: mod_xnl4v5.f90:342
m_xnldata::c_pol
real, dimension(:), allocatable c_pol
cosines during polar generation of locus
Definition: mod_xnl4v5.f90:288
m_xnldata::iq_prt
integer iq_prt
switch to activate print output, to file QBASE//.PRT == 0, No print output == 1, print output
Definition: mod_xnl4v5.f90:149
m_xnldata::x_locus2
real function x_locus2(lambda)
Compute locus function perpendicluar to symmetry axis.
Definition: mod_xnl4v5.f90:7382
m_xnldata::nlocus0
integer nlocus0
preferred number of points on locus
Definition: mod_xnl4v5.f90:214
m_xnldata::q_kfac
real q_kfac
geometric factor between subsequent wave numbers (only valid for IQ_IDISP==1)
Definition: mod_xnl4v5.f90:394
m_xnldata::cple_mod
real, dimension(:), allocatable cple_mod
coupling coefficient around locus
Definition: mod_xnl4v5.f90:301
m_xnldata::r_w1k2
real, dimension(:), allocatable r_w1k2
Definition: mod_xnl4v5.f90:338
serv_xnl4v5::z_intp1
subroutine z_intp1(x1, y1, x2, y2, n1, n2, ierr)
Definition: serv_xnl4v5.f90:102
m_xnldata::x_cple
real function x_cple(k1x, k1y, k2x, k2y, k3x, k3y, k4x, k4y, iq_cple, depth, grav)
Compute coupling coefficient between a quadruplet of interacting wave numbers.
Definition: mod_xnl4v5.f90:6855
m_xnldata::x4_loc
real, dimension(:), allocatable x4_loc
k4x coordinates around locus
Definition: mod_xnl4v5.f90:280
m_xnldata::q_lambda
real q_lambda
geometric scaling factor for 'deep' water loci
Definition: mod_xnl4v5.f90:368
m_xnldata::sub_name
character(len=20) sub_name
Name of active subroutine.
Definition: mod_xnl4v5.f90:41
m_xnldata::eps_k
real eps_k
absolute accuracy for equality check of k
Definition: mod_xnl4v5.f90:372
m_xnldata::x4_mod
real, dimension(:), allocatable x4_mod
k4x coordinates along locus
Definition: mod_xnl4v5.f90:295
m_xnldata::iaq1
integer iaq1
Definition: mod_xnl4v5.f90:387
m_xnldata::k3x
real k3x
Definition: mod_xnl4v5.f90:230
m_xnldata::bqname
character(len=13) bqname
name of binary quadruplet grid file
Definition: mod_xnl4v5.f90:193
m_xnldata::nkq
integer nkq
number of wave numbers of quad-grid
Definition: mod_xnl4v5.f90:199
m_xnldata::t_w3k4
real, dimension(:), allocatable t_w3k4
transformed weight 3 for k4
Definition: mod_xnl4v5.f90:328
m_xnldata::iag1
integer iag1
Definition: mod_xnl4v5.f90:388
m_xnldata::iq_trace
integer iq_trace
trace option == 0, no trace of subroutine calls 0, maximum number of traces per subroutine < 0,...
Definition: mod_xnl4v5.f90:170
m_xnldata::k0x
real k0x
Definition: mod_xnl4v5.f90:226
m_xnldata::q_dstep
real q_dstep
step size for generating BQF files
Definition: mod_xnl4v5.f90:209
m_xnldata::iq_sym
integer iq_sym
switch to activate use of symmetry reduction == 0, no symmetries are used == 1, symmetry activated (d...
Definition: mod_xnl4v5.f90:161
m_xnldata::wk_k4
real, dimension(:), allocatable wk_k4
w.r.t.
Definition: mod_xnl4v5.f90:312
m_xnldata::q_sig
real, dimension(:), allocatable q_sig
radian frequencies associated to wave number/depth
Definition: mod_xnl4v5.f90:353
m_xnldata::q_dird1
real q_dird1
Definition: mod_xnl4v5.f90:364
m_xnldata::kqmax
real kqmax
highest wave number
Definition: mod_xnl4v5.f90:223
m_xnldata::kmidx
real kmidx
x-component of wave number at midpoint of locus along symmetry axis
Definition: mod_xnl4v5.f90:241
m_xnldata::q_summary
subroutine q_summary
Write summary of GurboQuad settings to print file.
Definition: mod_xnl4v5.f90:5431
m_xnldata::sym_loc
real, dimension(:), allocatable sym_loc
factor for symmetry between k3 and k4
Definition: mod_xnl4v5.f90:285
serv_xnl4v5::z_upper
subroutine z_upper(str)
Definition: serv_xnl4v5.f90:630
m_xnldata::iq_cple
integer iq_cple
type of coupling coefficient == 1, deep water coefficient of Webb == 2, deep water coefficient of Zak...
Definition: mod_xnl4v5.f90:82
m_xnldata::iq_mod
integer iq_mod
option to redistribute points on locus == 0, Points will be used as computed by tracing algortihm == ...
Definition: mod_xnl4v5.f90:145
m_xnldata::y4_loc
real, dimension(:), allocatable y4_loc
k4y coordinates around locus
Definition: mod_xnl4v5.f90:281
m_xnldata::iq_t13
integer iq_t13
option to output T13 integration ==0, no output ==1, test output of T13 per locus
Definition: mod_xnl4v5.f90:179
m_xnldata::xnl_init
subroutine xnl_init(sigma, dird, nsigma, ndir, pftail, x_grav, depth, ndepth, iquad, iqgrid, iproc, ierr)
Initialize coefficients, integration space, file i/o for computation nonlinear quadruplet wave-wave i...
Definition: mod_xnl4v5.f90:465
m_xnldata::iq_screen
integer iq_screen
option to send output to the screen == 0, no output is send to screen == 1, output is send to screen
Definition: mod_xnl4v5.f90:157
m_xnldata::k_pol
real, dimension(:), allocatable k_pol
wave numbers during polar generation of locus
Definition: mod_xnl4v5.f90:287
m_xnldata::iq_trf
integer iq_trf
option to print transformed loci to special output file == 0, no output to data file unit luqtrf == 1...
Definition: mod_xnl4v5.f90:175
m_xnldata::y2_mod
real, dimension(:), allocatable y2_mod
k2y coordinates along locus
Definition: mod_xnl4v5.f90:294
m_xnldata::ia_k3
integer ia_k3
Definition: mod_xnl4v5.f90:204
m_xnldata::x_flocus
real function x_flocus(kxx, kyy)
Compute locus function used for the determination of the resonance condition.
Definition: mod_xnl4v5.f90:6965
m_xnldata::luq_fil
integer luq_fil
test output for filtering
Definition: mod_xnl4v5.f90:53
m_xnldata::cple_loc
real, dimension(:), allocatable cple_loc
coupling coefficient around locus
Definition: mod_xnl4v5.f90:284
m_xnldata::iq_gauleg
integer iq_gauleg
switch for Gauss-Legendre interpolation == 0, No Gauss-Legendre, default 0 Gauss-Legendre,...
Definition: mod_xnl4v5.f90:103
m_xnldata::luq_txt
integer luq_txt
reading (error) text file
Definition: mod_xnl4v5.f90:61
m_xnldata::sk_max
real sk_max
maximum wave number in extended array
Definition: mod_xnl4v5.f90:346
m_xnldata::q_chkcons
subroutine q_chkcons(xnl, nk, ndir, sum_e, sum_a, sum_mx, sum_my)
Check conservation laws of non-linear transfer.
Definition: mod_xnl4v5.f90:1435
m_xnldata::q_xk
real, dimension(:), allocatable q_xk
extended wave number array starting at index 0
Definition: mod_xnl4v5.f90:344
m_xnldata::iq_interp
integer iq_interp
type of interpolation to retrieve action density == 1, bi-linear interpolation in discrete spectrum (...
Definition: mod_xnl4v5.f90:123
m_xnldata::t_ia4
integer, dimension(:), allocatable t_ia4
transformed weight for k4
Definition: mod_xnl4v5.f90:321
m_xnldata::luq_tst
integer luq_tst
test file for quadruplets
Definition: mod_xnl4v5.f90:60
m_xnldata::loc_xz
real loc_xz
x-coordinate of center of gravity of locus in (kx,ky)-space
Definition: mod_xnl4v5.f90:245
m_xnldata::qf_error
character(len=20) qf_error
name of file with error messages
Definition: mod_xnl4v5.f90:43
m_constants::sqrtg
real sqrtg
square root of grav
Definition: mod_constants.f90:20
m_constants::pi
real pi
circular constant, 3.1415...
Definition: mod_constants.f90:29
m_xnldata::k1y
real k1y
components of k1 wave number
Definition: mod_xnl4v5.f90:228
m_xnldata::ia_k1
integer ia_k1
Definition: mod_xnl4v5.f90:203
m_xnldata::q_dscale
subroutine q_dscale(n, sigma, angle, nsig, nang, depth, grav, q_dfac)
Compute scaling factor for nonlinear transfer in finite depth.
Definition: mod_xnl4v5.f90:2397
m_xnldata::s_loc
real, dimension(:), allocatable s_loc
coordinate along locus
Definition: mod_xnl4v5.f90:279
m_xnldata::iq_lump
integer iq_lump
switch to activate lumping on locus == 0, No lumping == 1, Lumping along locus
Definition: mod_xnl4v5.f90:136
m_xnldata::t_ik2
integer, dimension(:), allocatable t_ik2
transformed weight for k2-magnitude
Definition: mod_xnl4v5.f90:318
m_xnldata::q_weight
subroutine q_weight
Compute interpolation weights of locus.
Definition: mod_xnl4v5.f90:5998
m_xnldata::iq_xdia
integer iq_xdia
switch to activate output to extended DIA data file == 0, no output 0, output to data file,...
Definition: mod_xnl4v5.f90:183
m_xnldata::luq_err
integer luq_err
file with error messages
Definition: mod_xnl4v5.f90:52
m_xnldata::iq_filt
integer iq_filt
switch to activate filtering in wave number space ==0, no filtering ==1, filtering activated
Definition: mod_xnl4v5.f90:99
m_xnldata::t_w3k2
real, dimension(:), allocatable t_w3k2
transformed weight 3 for k2
Definition: mod_xnl4v5.f90:324
m_xnldata::xc_webb
real function xc_webb(k1x, k1y, k2x, k2y, k3x, k3y, k4x, k4y, grav)
Compute deep water coupling coefficient for non-linear quadruplet interactions.
Definition: mod_xnl4v5.f90:7856
m_xnldata::q_k
real, dimension(:), allocatable q_k
wave number grid [1/m]
Definition: mod_xnl4v5.f90:348
m_xnldata::q_ad
real, dimension(:), allocatable q_ad
directions of quadruplet grid in degrees
Definition: mod_xnl4v5.f90:357
m_xnldata::q_mindepth
real q_mindepth
minimum water depth, set in XNL_INIT, used in Q_CTRGRID
Definition: mod_xnl4v5.f90:367
m_xnldata::quad_w2k4
real, dimension(:,:,:), allocatable quad_w2k4
weight 2 of k4
Definition: mod_xnl4v5.f90:269
m_xnldata::luq_int
integer luq_int
test file for test output of integration
Definition: mod_xnl4v5.f90:55
m_xnldata::q_makegrid
subroutine q_makegrid
Set-up grid for computation of loci.
Definition: mod_xnl4v5.f90:3764
m_xnldata::q_delta
real q_delta
directional spacing of angular grid in radians
Definition: mod_xnl4v5.f90:390
m_xnldata::iq_dscale
integer iq_dscale
switch to activate depth scaling according to Herterich and Hasselmann == 0, No depth scaling == 1,...
Definition: mod_xnl4v5.f90:94
m_xnldata::aqname
character(len=13) aqname
name of ASCII grid file
Definition: mod_xnl4v5.f90:192
m_xnldata::iq_disp
integer iq_disp
type of dispersion relation, viz.
Definition: mod_xnl4v5.f90:89
m_xnldata::q_maxdepth
real q_maxdepth
maximum water depth, set in XNL_INIT, used in Q_CTRGRID
Definition: mod_xnl4v5.f90:366
m_xnldata::iq_warn
integer iq_warn
counts the number of warnings
Definition: mod_xnl4v5.f90:428
m_xnldata::pmag
real pmag
magnitude of P-vector
Definition: mod_xnl4v5.f90:233
m_xnldata::iq_search
integer iq_search
switch to determine search for a proper grid == 0, no search is carried out == 1, search nearest (rel...
Definition: mod_xnl4v5.f90:153
m_xnldata::py
real py
components of difference k1-k3 wave number
Definition: mod_xnl4v5.f90:232
m_xnldata::lq_grid
logical lq_grid
flag to make (new) interaction grid
Definition: mod_xnl4v5.f90:197
m_xnldata::k4m_mod
real, dimension(:), allocatable k4m_mod
k4 magnitude around locus
Definition: mod_xnl4v5.f90:306
m_xnldata::xang
real xang
angle of locus for the case that w1=w3, Xang=atan2(-px,py), (radians)
Definition: mod_xnl4v5.f90:236
m_xnldata::wt_k4
real, dimension(:), allocatable wt_k4
wt==1 for wave numbers inside k-grid
Definition: mod_xnl4v5.f90:316
m_xnldata::iq_err
integer iq_err
counts the number of errors if no error occurred, IQ_ERR = 0 for each occuring error,...
Definition: mod_xnl4v5.f90:422
m_xnldata::id_facmax
integer id_facmax
Factor for determining range of depth search (Q_SEARCHGRID)
Definition: mod_xnl4v5.f90:363
m_xnldata::wa_k4
real, dimension(:), allocatable wa_k4
w.r.t.
Definition: mod_xnl4v5.f90:314
m_xnldata::t_w4k4
real, dimension(:), allocatable t_w4k4
transformed weight 4 for k4
Definition: mod_xnl4v5.f90:329
m_xnldata::qk_tail
real qk_tail
power of spectral tail of N(k), computed from qf_tail
Definition: mod_xnl4v5.f90:396
m_xnldata::q_kpow
real, dimension(:), allocatable q_kpow
wave number to a certain power, used in filtering
Definition: mod_xnl4v5.f90:350
m_xnldata::wa_k2
real, dimension(:), allocatable wa_k2
position of k2 and k4 wave number
Definition: mod_xnl4v5.f90:313
m_xnldata::luq_prt
integer luq_prt
general print file for quadruplets
Definition: mod_xnl4v5.f90:58
m_xnldata::r_w2k2
real, dimension(:), allocatable r_w2k2
Definition: mod_xnl4v5.f90:338
m_constants
Module for m_constants.
Definition: mod_constants.f90:14
m_xnldata::quad_ia2
integer, dimension(:,:,:), allocatable quad_ia2
lower direction index of k2
Definition: mod_xnl4v5.f90:261
m_xnldata::kmidy
real kmidy
y-component of wave number at midpoint of locus along symmetry axis
Definition: mod_xnl4v5.f90:242
m_xnldata::r_w1k4
real, dimension(:), allocatable r_w1k4
Definition: mod_xnl4v5.f90:339
m_xnldata::q_xnl4v4
subroutine q_xnl4v4(aspec, sigma, angle, nsig, nang, depth, xnl, diag, ierr)
Compute nonlinear transfer for a given action density spectrum on a given wave number and direction g...
Definition: mod_xnl4v5.f90:6373
m_xnldata::q_stack
subroutine q_stack(mod_name)
Add or remove mod_name name from module stack.
Definition: mod_xnl4v5.f90:5310
m_xnldata::iq_stack
integer iq_stack
Sequence number of stack with subroutine calls.
Definition: mod_xnl4v5.f90:375
m_xnldata::iq_make
integer iq_make
option to make quadruplet grid == 1, make when needed (default) == 2, always make quadruplet grid == ...
Definition: mod_xnl4v5.f90:140
m_xnldata::luq_t13
integer luq_t13
test of basis integration
Definition: mod_xnl4v5.f90:62
m_xnldata::cstack
character(len=21), dimension(mq_stack) cstack
Stack with module names.
Definition: mod_xnl4v5.f90:376
m_xnldata::q_dsig
real, dimension(:), allocatable q_dsig
step size of radian frequency grid
Definition: mod_xnl4v5.f90:354
m_xnldata::krefx
real krefx
Definition: mod_xnl4v5.f90:227
m_xnldata::kmax_loc
real kmax_loc
maximum wave number of locus along symmetry axis
Definition: mod_xnl4v5.f90:239
m_xnldata::ik_k3
integer ik_k3
indices of main loop variables
Definition: mod_xnl4v5.f90:204
m_xnldata::sang
real sang
angle of symmytry axis of locus, SANG = PANG +/ pi° (radians)
Definition: mod_xnl4v5.f90:235
m_xnldata::r_ik4
integer, dimension(:), allocatable r_ik4
corresponding declarations r_ik4
Definition: mod_xnl4v5.f90:336
m_xnldata::ik_k1
integer ik_k1
indices of main loop variables
Definition: mod_xnl4v5.f90:203
m_constants::dera
real dera
conversion from degrees to radians
Definition: mod_constants.f90:32
m_xnldata::tanz
real function tanz(x)
N/A.
Definition: mod_xnl4v5.f90:7809
m_xnldata::quad_w1k2
real, dimension(:,:,:), allocatable quad_w1k2
weight 1 of k2
Definition: mod_xnl4v5.f90:264
m_xnldata::y4_mod
real, dimension(:), allocatable y4_mod
k4y coordinates along locus
Definition: mod_xnl4v5.f90:296
m_xnldata::t_w2k4
real, dimension(:), allocatable t_w2k4
transformed weight 2 for k4
Definition: mod_xnl4v5.f90:327
m_xnldata::nlocusx
integer nlocusx
number of points on locus for use in computation (nlocusx <= nlocus)
Definition: mod_xnl4v5.f90:220
m_xnldata::klocus
integer klocus
number of points on locus as stored in quadruplet database based on nlocus0, iq_gauleg and iq_lump (w...
Definition: mod_xnl4v5.f90:216
m_xnldata::iaref
integer iaref
index of first angle of reference wave numbers
Definition: mod_xnl4v5.f90:385
m_xnldata::dk0
real dk0
components of initial wave number of locus,
Definition: mod_xnl4v5.f90:226
m_xnldata::q_symmetry
subroutine q_symmetry(k1x, k1y, k3x, k3y, k4x, k4y, symfac, nloc)
Compute symmetry factor to reduce integration.
Definition: mod_xnl4v5.f90:5649
serv_xnl4v5::z_polyarea
subroutine z_polyarea(xpol, ypol, npol, area)
Definition: serv_xnl4v5.f90:291
m_xnldata::naq
integer naq
number of angles of quad-grad
Definition: mod_xnl4v5.f90:200
m_xnldata::t_zz
real, dimension(:), allocatable t_zz
product term
Definition: mod_xnl4v5.f90:330
m_xnldata::quad_ik2
integer, dimension(:,:,:), allocatable quad_ik2
lower wave number index of k2
Definition: mod_xnl4v5.f90:260
serv_xnl4v5::y_gauleg
subroutine y_gauleg(x1, x2, x, w, n)
Definition: serv_xnl4v5.f90:4
m_xnldata::q_error
subroutine q_error(err_type, err_name, err_msg)
Error handling routine.
Definition: mod_xnl4v5.f90:2544
m_xnldata::r_ia2
integer, dimension(:), allocatable r_ia2
corresponding declarations r_ia2
Definition: mod_xnl4v5.f90:335
m_xnldata::r_w3k2
real, dimension(:), allocatable r_w3k2
Definition: mod_xnl4v5.f90:338
m_xnldata::px
real px
Definition: mod_xnl4v5.f90:232
m_xnldata::iq_locus
integer iq_locus
Option for computation of locus ==1, explicit polar method with fixed k-step ==2, explicit polar meth...
Definition: mod_xnl4v5.f90:127
m_xnldata::lastquadfile
character(len=13) lastquadfile
name of last retrieved BQF file
Definition: mod_xnl4v5.f90:194
m_xnldata::x2_loc
real, dimension(:), allocatable x2_loc
k2x coordinates around locus
Definition: mod_xnl4v5.f90:276
m_xnldata
Module for computing the quadruplet interaction.
Definition: mod_xnl4v5.f90:14
m_xnldata::r_cple
real, dimension(:), allocatable r_cple
Definition: mod_xnl4v5.f90:340
m_xnldata::kmin_loc
real kmin_loc
minimum wave number of locus along symmetry axis
Definition: mod_xnl4v5.f90:238
m_xnldata::krefy
real krefy
components of reference wave number for quad-grid
Definition: mod_xnl4v5.f90:227
m_xnldata::xnl_main
subroutine xnl_main(aspec, sigma, angle, nsig, ndir, depth, iquad, xnl, diag, iproc, ierr)
Compute nonlinear transfer for a given action density spectrum on a given sigma and direction grid (W...
Definition: mod_xnl4v5.f90:810
m_xnldata::eps_q
real eps_q
absolute accuracy for check of Q
Definition: mod_xnl4v5.f90:371
m_xnldata::r_ia4
integer, dimension(:), allocatable r_ia4
corresponding declarations r_ia4
Definition: mod_xnl4v5.f90:337
serv_xnl4v5
Definition: serv_xnl4v5.f90:1
m_xnldata::k2a_mod
real, dimension(:), allocatable k2a_mod
k2 angle around locus
Definition: mod_xnl4v5.f90:305
m_xnldata::quad_w4k4
real, dimension(:,:,:), allocatable quad_w4k4
weight 4 of k4
Definition: mod_xnl4v5.f90:271
m_xnldata::t_w1k2
real, dimension(:), allocatable t_w1k2
transformed weight 1 for k2
Definition: mod_xnl4v5.f90:322
m_xnldata::y2_loc
real, dimension(:), allocatable y2_loc
k2y coordinates around locus
Definition: mod_xnl4v5.f90:277
m_xnldata::t_ia2
integer, dimension(:), allocatable t_ia2
transformed direction for k2
Definition: mod_xnl4v5.f90:319
serv_xnl4v5::z_wnumb
real function z_wnumb(w, d, grav)
Definition: serv_xnl4v5.f90:680
m_xnldata::q_header
character(len=21) q_header
header of Binary Quadruplet File as intended in BQF-file
Definition: mod_xnl4v5.f90:195
m_fileio::z_fileio
subroutine z_fileio(filename, qual, iufind, iunit, iostat)
Open file with name FILENAME and determine unit number IUNIT.
Definition: mod_fileio.f90:84
m_xnldata::r_zz
real, dimension(:), allocatable r_zz
Definition: mod_xnl4v5.f90:340
m_xnldata::kqmin
real kqmin
lowest wave number
Definition: mod_xnl4v5.f90:222
m_xnldata::quad_ia4
integer, dimension(:,:,:), allocatable quad_ia4
lower direction index of k4
Definition: mod_xnl4v5.f90:263
m_xnldata::r_w4k4
real, dimension(:), allocatable r_w4k4
corresponding declarations
Definition: mod_xnl4v5.f90:339
m_xnldata::r_w3k4
real, dimension(:), allocatable r_w3k4
Definition: mod_xnl4v5.f90:339
m_xnldata::quad_w3k4
real, dimension(:,:,:), allocatable quad_w3k4
weight 3 of k4
Definition: mod_xnl4v5.f90:270
m_xnldata::nspec
real, dimension(:,:), allocatable nspec
Action density on wave number grid N(kx,ky)
Definition: mod_xnl4v5.f90:359
m_fileio
Module for storing file i/o related variables.
Definition: mod_fileio.f90:17
m_xnldata::r_sym
real, dimension(:), allocatable r_sym
Definition: mod_xnl4v5.f90:340
m_xnldata::z_loc
real, dimension(:), allocatable z_loc
data value around locus
Definition: mod_xnl4v5.f90:278
m_xnldata::iufind
integer iufind
Specifies handling of unit numbers, see Z_FILEIO.
Definition: mod_xnl4v5.f90:45
m_xnldata::q
real q
difference of radian frequencies, used in Resio-Tracy method
Definition: mod_xnl4v5.f90:237
m_xnldata::wk_max
real wk_max
maximum weight for wave number interpolation, set in Q_INIT
Definition: mod_xnl4v5.f90:224
m_xnldata::qbase
character(len=20) qbase
base name for I/O files
Definition: mod_xnl4v5.f90:42
m_xnldata::t_w1k4
real, dimension(:), allocatable t_w1k4
transformed weight 1 for k4
Definition: mod_xnl4v5.f90:326
m_xnldata::t_ik4
integer, dimension(:), allocatable t_ik4
transformed tail factor for k2
Definition: mod_xnl4v5.f90:320
m_xnldata::x_cosk
real function x_cosk(k)
Compute cosine of points on locus for given wave number k.
Definition: mod_xnl4v5.f90:6753
m_xnldata::q_locpos
subroutine q_locpos(ka, kb, km, kw, loclen)
Compute characteristics of locus used to optimize its acutal computation.
Definition: mod_xnl4v5.f90:3414
m_xnldata::x2_mod
real, dimension(:), allocatable x2_mod
k2x coordinates along locus
Definition: mod_xnl4v5.f90:293
m_xnldata::iq_log
integer iq_log
switch to activate logging to file QBASE//.LOG == 0, No print output == 1, print output
Definition: mod_xnl4v5.f90:132
m_xnldata::jac_mod
real, dimension(:), allocatable jac_mod
jacobian term around locus
Definition: mod_xnl4v5.f90:300
m_xnldata::q_dk
real, dimension(:), allocatable q_dk
width of wave number bins [1/m]
Definition: mod_xnl4v5.f90:349
m_xnldata::q_t13v4
subroutine q_t13v4(ik1, ia1, ik3, ia3, t13, diagk1, diagk3)
Compute the function T13, defined as a line integral around a locus.
Definition: mod_xnl4v5.f90:5746
m_xnldata::nlocus1
integer nlocus1
number of points on locus as computed in Q_CMPLOCUS
Definition: mod_xnl4v5.f90:215
m_xnldata::luq_log
integer luq_log
logging
Definition: mod_xnl4v5.f90:57
m_xnldata::qf_frac
real qf_frac
fraction of maximum action density to filter
Definition: mod_xnl4v5.f90:74
m_xnldata::qf_dmax
real qf_dmax
maximum directional difference between k1 and k3
Definition: mod_xnl4v5.f90:73
m_xnldata::t_w2k2
real, dimension(:), allocatable t_w2k2
transformed weight 2 for k2
Definition: mod_xnl4v5.f90:323
m_xnldata::q_chkres
subroutine q_chkres(k1x, k1y, k2x, k2y, k3x, k3y, k4x, k4y, dep, sum_kx, sum_ky, sum_w)
Check resonance conditions of 4 interacting wave numbers for a given water depth and dispersion relat...
Definition: mod_xnl4v5.f90:1574
m_xnldata::xc_hh
real function xc_hh(w1x0, w1y0, w2x0, w2y0, w3x0, w3y0, z4x, z4y, h)
N/A.
Definition: mod_xnl4v5.f90:7491
m_xnldata::iag2
integer iag2
range of directions for precomputed interaction grid
Definition: mod_xnl4v5.f90:388