KTH framework for Nek5000 toolboxes; testing version  0.0.1
gSyEM.f
Go to the documentation of this file.
1 
9 !=======================================================================
13  subroutine gsyem_register()
14  implicit none
15 
16  include 'SIZE'
17  include 'INPUT'
18  include 'FRAMELP'
19  include 'GSYEMD'
20 
21  ! local variables
22  integer lpmid, il
23  real ltim
24  character*2 str
25 
26  ! functions
27  real dnekclock
28 !-----------------------------------------------------------------------
29  ! timing
30  ltim = dnekclock()
31 
32  ! check if the current module was already registered
33  call mntr_mod_is_name_reg(lpmid,gsyem_name)
34  if (lpmid.gt.0) then
35  call mntr_warn(lpmid,
36  $ 'module ['//trim(gsyem_name)//'] already registered')
37  return
38  endif
39 
40  ! find parent module
41  call mntr_mod_is_name_reg(lpmid,'FRAME')
42  if (lpmid.le.0) then
43  lpmid = 1
44  call mntr_abort(lpmid,
45  $ 'parent module ['//'FRAME'//'] not registered')
46  endif
47 
48  ! register module
49  call mntr_mod_reg(gsyem_id,lpmid,gsyem_name,
50  $ 'Generalised Synthetic Eddy Method')
51 
52  ! check compilation parameters
53  if(ldim.ne.3) call mntr_abort(gsyem_id,
54  $ 'This code must be compiled with ldim=3')
55 
56  ! register timer
57  call mntr_tmr_is_name_reg(lpmid,'FRM_TOT')
58  call mntr_tmr_reg(gsyem_ttot_id,lpmid,gsyem_id,
59  $ 'GSYEM_TOT','GSYEM total time',.false.)
60 
61  call mntr_tmr_reg(gsyem_tini_id,gsyem_ttot_id,gsyem_id,
62  $ 'GSYEM_INI','GSYEM initialisation time',.true.)
63 
64  call mntr_tmr_reg(gsyem_tevl_id,gsyem_ttot_id,gsyem_id,
65  $ 'GSYEM_EVL','GSYEM evolution time',.true.)
66 
67  call mntr_tmr_reg(gsyem_tchp_id,gsyem_ttot_id,gsyem_id,
68  $ 'GSYEM_CHP','GSYEM checkpoint saving time',.true.)
69 
70  ! register and set active section
71  call rprm_sec_reg(gsyem_sec_id,gsyem_id,'_'//adjustl(gsyem_name),
72  $ 'Runtime paramere section for gSyEM module')
73  call rprm_sec_set_act(.true.,gsyem_sec_id)
74 
75  ! register parameters
76  call rprm_rp_reg(gsyem_mode_id,gsyem_sec_id,'MODE',
77  $ 'gSyEM mode',rpar_int,1,0.0,.false.,' ')
78 
79  call rprm_rp_reg(gsyem_nfam_id,gsyem_sec_id,'NFAM',
80  $ 'Family number',rpar_int,1,0.0,.false.,' ')
81 
82  do il=1, gsyem_nfam_max
83  write(str,'(I2.2)') il
84  call rprm_rp_reg(gsyem_neddy_id(il),gsyem_sec_id,'NEDDY'//str,
85  $ 'Numer of eddies per family',rpar_int,10,0.0,.false.,' ')
86  call rprm_rp_reg(gsyem_fambc_id(il),gsyem_sec_id,'FAMBC'//str,
87  $ 'Family BC index',rpar_int,1,0.0,.false.,' ')
88  call rprm_rp_reg(gsyem_sig_max_id(il),gsyem_sec_id,
89  $ 'FAMASIG'//str,'Family max edge size',rpar_real,
90  $ 1,0.025,.false.,' ')
91  call rprm_rp_reg(gsyem_sig_min_id(il),gsyem_sec_id,
92  $ 'FAMISIG'//str,'Family min edge size',rpar_real,
93  $ 1,0.001,.false.,' ')
94  call rprm_rp_reg(gsyem_dir_id(1,il),gsyem_sec_id,'FAMDIRX'//str,
95  $ 'Family normal X component',rpar_real,1,0.0,.false.,' ')
96  call rprm_rp_reg(gsyem_dir_id(2,il),gsyem_sec_id,'FAMDIRY'//str,
97  $ 'Family normal Y component',rpar_real,1,0.0,.false.,' ')
98  call rprm_rp_reg(gsyem_dir_id(3,il),gsyem_sec_id,'FAMDIRZ'//str,
99  $ 'Family normal Z component',
100  $ rpar_real,1,0.0,.false.,' ')
101  enddo
102 
103  ! set initialisation flag
104  gsyem_ifinit=.false.
105 
106  ! timing
107  ltim = dnekclock() - ltim
108  call mntr_tmr_add(gsyem_tini_id,1,ltim)
109 
110  return
111  end subroutine
112 !=======================================================================
116  subroutine gsyem_init()
117  implicit none
118 
119  include 'SIZE'
120  include 'INPUT'
121  include 'TSTEP'
122  include 'GEOM'
123  include 'FRAMELP'
124  include 'GSYEMD'
125 
126  ! local variables
127  integer itmp
128  real rtmp, ltim
129  logical ltmp
130  character*20 ctmp
131 
132  ! to get checkpoint runtime parameters
133  integer ierr, lmid, lsid, lrpid
134 
135  integer il, jl
136 
137  ! functions
138  real dnekclock
139 !-----------------------------------------------------------------------
140  ! check if the module was already initialised
141  if (gsyem_ifinit) then
142  call mntr_warn(gsyem_id,
143  $ 'module ['//trim(gsyem_name)//'] already initiaised.')
144  return
145  endif
146 
147  ! timing
148  ltim = dnekclock()
149 
150  ! get runtime parameters
151  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_mode_id,rpar_int)
152  gsyem_mode = itmp
153 
154  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_nfam_id,rpar_int)
155  gsyem_nfam = itmp
156  if(gsyem_nfam.gt.gsyem_nfam_max) call mntr_abort(gsyem_id,
157  $ 'Too many families')
158 
159  do il=1,gsyem_nfam
160  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_neddy_id(il),rpar_int)
161  gsyem_neddy(il) = itmp
162  if(itmp.gt.gsyem_neddy_max) call mntr_abort(gsyem_id,
163  $ 'Too many edies per family')
164 
165  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_fambc_id(il),rpar_int)
166  gsyem_fambc(il)=itmp
167 
168  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_sig_max_id(il),
169  $ rpar_real)
170  gsyem_sig_max(il)=rtmp
171 
172  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_sig_min_id(il),
173  $ rpar_real)
174  gsyem_sig_min(il)=rtmp
175 
176  do jl=1,ldim
177  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,gsyem_dir_id(jl,il),
178  $ rpar_real)
179  gsyem_dir(jl,il)=rtmp
180  enddo
181  enddo
182 
183  ! check the restart flag
184  ! check if checkpointing module was registered and take parameters
185  ierr = 0
186  call mntr_mod_is_name_reg(lmid,'CHKPT')
187  if (lmid.gt.0) then
188  call rprm_sec_is_name_reg(lsid,lmid,'_CHKPT')
189  if (lsid.gt.0) then
190  ! restart flag
191  call rprm_rp_is_name_reg(lrpid,lsid,'READCHKPT',rpar_log)
192  if (lrpid.gt.0) then
193  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,lrpid,rpar_log)
194  gsyem_chifrst = ltmp
195  else
196  ierr = 1
197  goto 30
198  endif
199  if (gsyem_chifrst) then
200  ! checkpoint set number
201  call rprm_rp_is_name_reg(lrpid,lsid,'CHKPFNUMBER',
202  $ rpar_int)
203  if (lrpid.gt.0) then
204  call rprm_rp_get(itmp,rtmp,ltmp,ctmp,lrpid,rpar_int)
205  gsyem_fnum = itmp
206  else
207  ierr = 1
208  goto 30
209  endif
210  endif
211  else
212  ierr = 1
213  endif
214  else
215  ierr = 1
216  endif
217 
218  30 continue
219 
220  ! check for errors
221  call mntr_check_abort(gsyem_id,ierr,
222  $ 'Error reading checkpoint parameters')
223 
224  ! get number of snapshots in a set
225  if (param(27).lt.0) then
226  gsyem_nsnap = nbdinp
227  else
228  gsyem_nsnap = 3
229  endif
230 
231  ! set calculated family normal falg
232  do il=1,gsyem_nfam
233  gsyem_dirl(il) = .true.
234  do jl=1,ldim
235  if (gsyem_dir(jl,il).ne.0.0) gsyem_dirl(il) = .false.
236  enddo
237  enddo
238 
239  ! calculate eddy offset
240  gsyem_eoff(1) = 1
241  do il=1,gsyem_nfam
242  gsyem_eoff(il+1) = gsyem_eoff(il) + gsyem_neddy(il)
243  enddo
244 
245  ! initialise random number genrator with clock time
246  itmp = 0
247  call math_zbqlini(itmp)
248 
249  ! read profile data
250  call gsyem_prof_read(gsyem_pnpoint,gsyem_ppoff,gsyem_prpos,
251  $ gsyem_pumean,gsyem_ptke,gsyem_pdss)
252 
253  ! create mesh dependent information
254  call gsyem_mesh_setup()
255 
256  ! initialise eddy position and orientation; possible rfestart
257  if (gsyem_chifrst) then
258  ! read checkpoint
259  call gsyem_rst_read()
260  else
261  if (gsyem_mode.eq.1) then
262  do il=1,gsyem_nfam
263  call gsyem_gen_eall(il)
264  enddo
265  elseif (gsyem_mode.eq.2) then
266  elseif (gsyem_mode.eq.3) then
267  do il=1,gsyem_nfam
268  call gsyem_gen_mall(il)
269  enddo
270  endif
271  endif
272 
273  ! everything is initialised
274  gsyem_ifinit=.true.
275 
276  ! timing
277  ltim = dnekclock() - ltim
278  call mntr_tmr_add(gsyem_tini_id,1,ltim)
279 
280  return
281  end subroutine
282 !=======================================================================
286  logical function gsyem_is_initialised()
287  implicit none
288 
289  include 'SIZE'
290  include 'GSYEMD'
291 !-----------------------------------------------------------------------
292  gsyem_is_initialised = gsyem_ifinit
293 
294  return
295  end function
296 !=======================================================================
299  subroutine gsyem_main
300  implicit none
301 
302  include 'SIZE'
303  include 'TSTEP'
304  include 'GSYEMD'
305 
306  ! local variables
307  real ltim
308 
309  ! functions
310  real dnekclock
311 !-----------------------------------------------------------------------
312  ! take into account restart
313  if ((gsyem_chifrst.and.(istep.lt.(gsyem_nsnap-1))).or.
314  $ istep.eq.0) return
315 
316 #ifndef AMR
317  ! to be consistent with saved velocity field first write checkpoint
318  call gsyem_rst_write
319 #endif
320  ! update vertices position
321  ! timing
322  ltim = dnekclock()
323  call gsyem_evolve()
324  ! timing
325  ltim = dnekclock() - ltim
326  call mntr_tmr_add(gsyem_tevl_id,1,ltim)
327 
328  return
329  end subroutine
330 !=======================================================================
335  subroutine gsyem_rst_write
336  implicit none
337 
338  include 'SIZE'
339  include 'INPUT'
340  include 'TSTEP'
341  include 'FRAMELP'
342  include 'GSYEMD'
343 #ifdef AMR
344  include 'AMR'
345 #endif
346  ! local variables
347  integer step_cnt, set_out
348  integer ierr
349  real ltim
350  character*132 fname
351  character*6 str
352 
353  character*132 hdr
354  integer ahdsize
355  parameter(ahdsize=132)
356 
357  real*4 test_pattern
358 
359  integer il
360  integer itmp(4), itmp2
361 
362  real*4 workla4(2*ldim*gsyem_neddy_max)
363  real*8 workla8(ldim*gsyem_neddy_max)
364  equivalence(workla4,workla8)
365 
366  ! functions
367  real dnekclock
368 !-----------------------------------------------------------------------
369 #ifdef AMR
370  set_out = mod(amr_iorset,amr_ioset_max)
371  step_cnt = 1
372 #else
373  ! avoid writing during possible restart reading
374  call mntr_get_step_delay(step_cnt)
375  if (istep.le.step_cnt) return
376 
377  ! get step count and file set number
378  call chkpt_get_fset(step_cnt, set_out)
379 #endif
380  ! we write everything in single step
381  if (step_cnt.eq.1) then
382  ltim = dnekclock()
383 
384  call mntr_log(gsyem_id,lp_inf,'Writing checkpoint snapshot')
385 
386  ierr = 0
387  ! for current implementation I/O on master only
388  if(nid.eq.0) then
389  ! get file name
390  fname='GSEM'//trim(adjustl(session))//'_rs.'
391  write(str,'(i5.5)') set_out + 1
392  fname=trim(fname)//trim(str(1:5))//char(0)
393 
394  ! open file
395  call byte_open(fname,ierr)
396 
397  if (ierr.eq.0) then
398  ! write number of families
399  call blank(hdr,ahdsize)
400 
401  write(hdr,10) gsyem_mode, gsyem_nfam, time
402  10 format('#gsem',1x,i2,1x,i2,1x,1pe14.7)
403 
404  call byte_write(hdr,ahdsize/4,ierr)
405  if (ierr.gt.0) goto 20
406 
407  ! write test pattern for byte swap
408  test_pattern = 6.54321
409 
410  call byte_write(test_pattern,1,ierr)
411  if (ierr.gt.0) goto 20
412 
413  ! loop over families
414  do il=1,gsyem_nfam
415  ! collect and write integer varialbes
416  itmp(1) = gsyem_fambc(il)
417  itmp(2) = gsyem_neddy(il)
418  itmp(3) = gsyem_gfnum(il)
419  itmp(4) = gsyem_genum(il)
420 
421  call byte_write(itmp,4,ierr)
422  if (ierr.gt.0) goto 20
423 
424  itmp2 = ldim*gsyem_neddy(il)
425  call copy(workla8,gsyem_epos(1,gsyem_eoff(il)),itmp2)
426  call byte_write(workla4,2*itmp2,ierr)
427  if (ierr.gt.0) goto 20
428 
429  call byte_write(gsyem_eps(1,gsyem_eoff(il)),itmp2,ierr)
430  if (ierr.gt.0) goto 20
431  enddo
432 
433  ! close file
434  call byte_close(ierr)
435  endif
436  endif
437 
438  20 continue
439 
440  call mntr_check_abort(gsyem_id,ierr,
441  $ 'gsyem_rst_write: Error writing restart file.')
442 
443  call nekgsync()
444  ! timing
445  ltim = dnekclock() - ltim
446  call mntr_tmr_add(gsyem_tchp_id,1,ltim)
447  endif
448 
449  return
450  end subroutine
451 !=======================================================================
456  subroutine gsyem_rst_read
457  implicit none
458 
459  include 'SIZE'
460  include 'INPUT'
461  include 'PARALLEL'
462  include 'FRAMELP'
463  include 'GSYEMD'
464 
465  ! local variables
466  integer ierr
467  character*132 fname
468  character*6 str
469 
470  ! local variable copies
471  integer lgsyem_mode, lgsyem_nfam, lgsyem_fambc, lgsyem_neddy
472  integer lgsyem_gfnum, lgsyem_genum
473  real ltime
474 
475  character*132 hdr
476  character*5 dummy
477  integer ahdsize
478  parameter(ahdsize=132)
479 
480  real*4 test_pattern
481 
482  integer il
483  integer itmp(4), itmp2
484 
485  real*4 workla4(2*ldim*gsyem_neddy_max)
486  real*8 workla8(ldim*gsyem_neddy_max)
487  equivalence(workla4,workla8)
488  logical if_byte_swap_test, if_byte_sw_loc
489 
490  ! functions
491  integer indx2
492 !-----------------------------------------------------------------------
493  ! stamp logs
494  call mntr_log(gsyem_id,lp_inf,'Reading checkpoint')
495 
496  ierr = 0
497  ! for current implementationI/O on master only
498  if(nid.eq.0) then
499  ! get file name
500  fname='GSEM'//trim(adjustl(session))//'_rs.'
501  write(str,'(i5.5)') gsyem_fnum
502  fname=trim(fname)//trim(str(1:5))//char(0)
503 
504  ! open file
505  call byte_open(fname,ierr)
506 
507  if (ierr.eq.0) then
508  ! read header
509  call blank(hdr,ahdsize)
510 
511  call byte_read(hdr,ahdsize/4,ierr)
512  if (ierr.gt.0) goto 20
513 
514  if (indx2(hdr,132,'#gsem',5).eq.1) then
515  read(hdr,*) dummy,lgsyem_mode,lgsyem_nfam,ltime
516  else
517  call mntr_log(gsyem_id,lp_err,
518  $ 'gsyem_rst_read; Error reading header')
519  ierr=1
520  goto 20
521  endif
522 
523  if(lgsyem_mode.ne.gsyem_mode.or.lgsyem_nfam.
524  $ ne.gsyem_nfam) then
525  call mntr_log(gsyem_id,lp_err,
526  $ 'gsyem_rst_read; Inconsistent header values')
527  ierr=1
528  goto 20
529  endif
530 
531  ! read test pattern for byte swap
532  call byte_read(test_pattern,1,ierr)
533  if (ierr.gt.0) goto 20
534  ! determine endianess
535  if_byte_sw_loc = if_byte_swap_test(test_pattern,ierr)
536  if (ierr.gt.0) goto 20
537 
538  ! loop over families
539  do il=1,gsyem_nfam
540  ! read integer varialbes
541  call byte_read(itmp,4,ierr)
542  if (if_byte_sw_loc) then
543  call byte_reverse(itmp,4,ierr)
544  if (ierr.gt.0) goto 20
545  endif
546  if(itmp(1).ne.gsyem_fambc(il).or.
547  $ itmp(2).ne.gsyem_neddy(il).or.
548  $ itmp(3).ne.gsyem_gfnum(il).or.
549  $ itmp(4).ne.gsyem_genum(il)) then
550  call mntr_log(gsyem_id,lp_err,
551  $ 'gsyem_rst_read; Inconsistent family data')
552  ierr=1
553  goto 20
554  endif
555 
556  itmp2 = ldim*gsyem_neddy(il)
557  call byte_read(workla4,2*itmp2,ierr)
558  if (ierr.gt.0) goto 20
559  if (if_byte_sw_loc) then
560  call byte_reverse(workla4,2*itmp2,ierr)
561  if (ierr.gt.0) goto 20
562  endif
563  call copy(gsyem_epos(1,gsyem_eoff(il)),workla8,itmp2)
564 
565  call byte_read(gsyem_eps(1,gsyem_eoff(il)),itmp2,ierr)
566  if (ierr.gt.0) goto 20
567  if (if_byte_sw_loc) then
568  call byte_reverse(gsyem_eps(1,gsyem_eoff(il)),itmp2,
569  $ ierr)
570  if (ierr.gt.0) goto 20
571  endif
572  enddo
573 
574  ! close file
575  call byte_close(ierr)
576  endif
577  endif
578 
579  20 continue
580 
581  call mntr_check_abort(gsyem_id,ierr,
582  $ 'gsyem_rst_read: Error reading restart file.')
583 
584  ! broadcast data
585  itmp2 = ldim*(gsyem_eoff(gsyem_nfam + 1) - 1)
586  call bcast(gsyem_epos,itmp2*wdsize)
587  call bcast(gsyem_eps,itmp2*isize)
588 
589  return
590  end subroutine
591 !=======================================================================
596  subroutine gsyem_mesh_setup()
597  implicit none
598  include 'SIZE'
599  include 'INPUT'
600  include 'GEOM'
601  include 'TSTEP'
602  include 'FRAMELP'
603  include 'GSYEMD'
604 
605  ! local variables
606  integer ierr, itmp, itmp2, il, iel, iface, jl
607  integer nface
608  character*3 cbcl
609 
610  ! face to face mapping
611  integer iffmap(4,6)
612  save iffmap
613  data iffmap / 2,4,5,6, 1,3,5,6, 2,4,5,6, 1,3,5,6,
614  $ 1,2,3,4, 1,2,3,4 /
615 
616  ! face to edge mapping
617  integer ifemap(4,6)
618  save ifemap
619  data ifemap / 10,9,1,3, 10,12,6,8, 12,11,2,4, 9,11,5,7,
620  $ 1,6,2,5, 3,8,4,7 /
621 
622  ! functions
623  integer iglsum
624 !-----------------------------------------------------------------------
625  ! generate faces/edges mapping and check if all families
626  ! correspond to Dirichlet bc
627  ierr = 0
628  nface = 2*ndim
629  call izero(gsyem_lfnum,gsyem_nfam_max)
630  call izero(gsyem_gfnum,gsyem_nfam_max)
631  call izero(gsyem_lenum,gsyem_nfam_max)
632  call izero(gsyem_genum,gsyem_nfam_max)
633  itmp = 2*lelt*gsyem_nfam_max
634  call izero(gsyem_lfmap,itmp)
635  call izero(gsyem_lemap,itmp)
636  do il=1,gsyem_nfam
637  itmp=0 ! count family faces
638  itmp2=0 ! count family edges
639  do iel=1,nelv
640  do iface = 1, nface
641  if(boundaryid(iface,iel).eq.gsyem_fambc(il)) then
642  itmp = itmp +1
643  if(cbc(iface,iel,1).eq.'v ') then
644  gsyem_lfmap(1,itmp,il) = iel
645  gsyem_lfmap(2,itmp,il) = iface
646  ! get edges
647  do jl=1,(ndim-1)*2
648  cbcl = cbc(iffmap(jl,iface),iel,1)
649  if(cbcl(1:1).eq.'W'.or.cbcl(1:1).eq.'m') then
650  itmp2 = itmp2 +1
651  gsyem_lemap(1,itmp2,il) = iel
652  gsyem_lemap(2,itmp2,il) = ifemap(jl,iface)
653  endif
654  enddo
655  else
656  ierr = 1
657  endif
658  endif
659  enddo
660  enddo
661  gsyem_lfnum(il) = itmp
662  gsyem_gfnum(il) = iglsum(gsyem_lfnum(il),1)
663  if (gsyem_gfnum(il).eq.0) call mntr_abort(gsyem_id,
664  $ 'Empty family BC')
665  gsyem_lenum(il) = itmp2
666  gsyem_genum(il) = iglsum(gsyem_lenum(il),1)
667  enddo
668  call mntr_check_abort(gsyem_id,ierr,'Non Dirichlet family BC')
669 
670  ! calculate face offset
671  gsyem_foff(1) = 1
672  do il=1,gsyem_nfam
673  gsyem_foff(il+1) = gsyem_foff(il) + gsyem_lfnum(il)
674  enddo
675 
676  ! generate family information
677  call gsyem_fam_setup(gsyem_pnpoint,gsyem_ppoff,gsyem_prpos,
678  $ gsyem_pumean,gsyem_ptke,gsyem_pdss)
679 
680  return
681  end subroutine
682 !=======================================================================
687  subroutine gsyem_fam_setup(npoint,poff,rpos,umean,tke,dss)
688  implicit none
689  include 'SIZE'
690  include 'INPUT'
691  include 'GEOM'
692  include 'TSTEP' ! PI
693  include 'FRAMELP'
694  include 'GSYEMD'
695 
696  ! argument list
697  ! profiles for given family
698  ! number of points in profile per family
699  integer npoint(gsyem_nfam_max)
700  ! family profile array offset
701  integer poff(gsyem_nfam_max+1)
702  ! position in a profile
703  real rpos(gsyem_npoint_max*gsyem_nfam_max)
704  ! mean velocity
705  real umean(gsyem_npoint_max*gsyem_nfam_max)
706  ! turbulence kinetic energy
707  real tke(gsyem_npoint_max*gsyem_nfam_max)
708  ! dissipation rate
709  real dss(gsyem_npoint_max*gsyem_nfam_max)
710 
711 
712  ! local variables
713  integer il, jl, kl, ll, ml, nl
714  integer iel, ifc, ied, ifn, itmp
715  real rtmp, epsl
716  parameter(epsl=1.0e-06)
717 
718  ! work arrays
719  real xyz_ewall(ldim,lx1,gsyem_edge_max,gsyem_nfam_max)
720  real vrtmp(lx1*lz1), work(lx1*ldim*gsyem_edge_max)
721  real drtmp(ldim,lx1*lz1)
722 
723  ! functions
724  integer igl_running_sum
725  real vlmin, vlmax, vlsum
726 !-----------------------------------------------------------------------
727  call mntr_log(gsyem_id,lp_inf,'Generate family information')
728 
729  ! extract edge position;
730  ! This is necessary to get distance of the point from the edge
731  ! Not very fancy, but done only once, so not urgent to improve
732  call mntr_log(gsyem_id,lp_inf,'Extract edge position')
733  ! initial values
734  call rzero(xyz_ewall,ldim*lx1*gsyem_edge_max*gsyem_nfam_max)
735  ! loop over families
736  do il=1,gsyem_nfam
737  ! check array sizes
738  if (gsyem_genum(il).gt.gsyem_edge_max) call mntr_abort(gsyem_id,
739  $ 'Too many edges per family')
740  ! get offset
741  itmp = igl_running_sum(gsyem_lenum(il)) - gsyem_lenum(il)
742  do jl=1,gsyem_lenum(il)
743  iel = gsyem_lemap(1,jl,il)
744  ied = gsyem_lemap(2,jl,il)
745 
746  ! copy coordinates
747  call math_etovec(vrtmp,ied,xm1(1,1,1,iel),lx1,ly1,lz1)
748  do kl=1,lx1
749  xyz_ewall(1,kl,itmp+jl,il) = vrtmp(kl)
750  enddo
751  call math_etovec(vrtmp,ied,ym1(1,1,1,iel),lx1,ly1,lz1)
752  do kl=1,lx1
753  xyz_ewall(2,kl,itmp+jl,il) = vrtmp(kl)
754  enddo
755  call math_etovec(vrtmp,ied,zm1(1,1,1,iel),lx1,ly1,lz1)
756  do kl=1,lx1
757  xyz_ewall(ldim,kl,itmp+jl,il) = vrtmp(kl)
758  enddo
759  enddo
760  ! global distribution
761  call gop(xyz_ewall(1,1,1,il),work,'+ ',ldim*lx1*gsyem_edge_max)
762  enddo
763 
764  ! extract bounding box, average coordinate, normal, area
765  call mntr_log(gsyem_id,lp_inf,'Extract bounding box information')
766  ! initial values
767  do il=1,gsyem_nfam
768  rtmp = 99.0e20
769  call cfill(gsyem_bmin(1,il),rtmp,ldim)
770  rtmp = -99.0e20
771  call cfill(gsyem_bmax(1,il),rtmp,ldim)
772  enddo
773  call rzero(gsyem_bcrd,ldim*gsyem_nfam_max)
774  call rzero(gsyem_bnrm,ldim*gsyem_nfam_max)
775  call rzero(gsyem_area,gsyem_nfam_max)
776  itmp=lx1*lz1
777  ! face loop
778  do il=1,gsyem_nfam
779  do jl=1,gsyem_lfnum(il)
780  iel = gsyem_lfmap(1,jl,il)
781  ifc = gsyem_lfmap(2,jl,il)
782 
783  ! bnd. box, centre crd., normal
784  call ftovec(vrtmp,xm1,iel,ifc,lx1,ly1,lz1)
785  rtmp = vlmin(vrtmp,itmp)
786  gsyem_bmin(1,il) = min(gsyem_bmin(1,il),rtmp)
787  rtmp = vlmax(vrtmp,itmp)
788  gsyem_bmax(1,il) = max(gsyem_bmax(1,il),rtmp)
789  rtmp = vlsum(vrtmp,itmp)
790  gsyem_bcrd(1,il) = gsyem_bcrd(1,il) + rtmp
791  rtmp = vlsum(unx(1,1,ifc,iel),itmp)
792  gsyem_bnrm(1,il) = gsyem_bnrm(1,il) + rtmp
793 
794  call ftovec(vrtmp,ym1,iel,ifc,lx1,ly1,lz1)
795  rtmp = vlmin(vrtmp,itmp)
796  gsyem_bmin(2,il) = min(gsyem_bmin(2,il),rtmp)
797  rtmp = vlmax(vrtmp,itmp)
798  gsyem_bmax(2,il) = max(gsyem_bmax(2,il),rtmp)
799  rtmp = vlsum(vrtmp,itmp)
800  gsyem_bcrd(2,il) = gsyem_bcrd(2,il) + rtmp
801  rtmp = vlsum(uny(1,1,ifc,iel),itmp)
802  gsyem_bnrm(2,il) = gsyem_bnrm(2,il) + rtmp
803 
804  call ftovec(vrtmp,zm1,iel,ifc,lx1,ly1,lz1)
805  rtmp = vlmin(vrtmp,itmp)
806  gsyem_bmin(ldim,il) = min(gsyem_bmin(ldim,il),rtmp)
807  rtmp = vlmax(vrtmp,itmp)
808  gsyem_bmax(ldim,il) = max(gsyem_bmax(ldim,il),rtmp)
809  rtmp = vlsum(vrtmp,itmp)
810  gsyem_bcrd(ldim,il) = gsyem_bcrd(ldim,il) + rtmp
811  rtmp = vlsum(unz(1,1,ifc,iel),itmp)
812  gsyem_bnrm(ldim,il) = gsyem_bnrm(ldim,il) + rtmp
813 
814  ! family area
815  gsyem_area(il) = gsyem_area(il)+vlsum(area(1,1,ifc,iel),itmp)
816  enddo
817  enddo
818 
819  ! global average
820  call gop(gsyem_bmin,work,'m ',ldim*gsyem_nfam_max)
821  call gop(gsyem_bmax,work,'M ',ldim*gsyem_nfam_max)
822  call gop(gsyem_bcrd,work,'+ ',ldim*gsyem_nfam_max)
823  call gop(gsyem_bnrm,work,'+ ',ldim*gsyem_nfam_max)
824  call gop(gsyem_area,work,'+ ',gsyem_nfam_max)
825 
826  do il=1,gsyem_nfam
827  rtmp = 1.0/real(lx1*lx1*gsyem_gfnum(il))
828  call cmult(gsyem_bcrd(1,il),rtmp,ldim)
829  ! as nek normal point outwards change normal sign ???????????
830  rtmp=-1.0*rtmp
831  call cmult(gsyem_bnrm(1,il),rtmp,ldim)
832  ! this shouldn't be necessary, but just in case normalise vector
833  rtmp = 0.0
834  do jl=1,ldim
835  rtmp = rtmp + gsyem_bnrm(jl,il)**2
836  enddo
837  rtmp = 1.0/sqrt(rtmp)
838  call cmult(gsyem_bnrm(1,il),rtmp,ldim)
839  enddo
840 
841  ! rotation axis and angle
842  do il=1,gsyem_nfam
843  if(gsyem_bnrm(3,il).gt.(1.0-epsl)) then
844  gsyem_raxs(1,il) = 1.0
845  gsyem_raxs(2,il) = 0.0
846  gsyem_raxs(3,il) = 0.0
847  gsyem_rang(il) = 0.0
848  elseif(gsyem_bnrm(3,il).lt.(epsl-1.0)) then
849  gsyem_raxs(1,il) = 1.0
850  gsyem_raxs(2,il) = 0.0
851  gsyem_raxs(3,il) = 0.0
852  gsyem_rang(il) = pi
853  else
854  gsyem_raxs(1,il) = -gsyem_bnrm(2,il)
855  gsyem_raxs(2,il) = gsyem_bnrm(1,il)
856  gsyem_raxs(3,il) = 0.0
857  rtmp = sqrt(gsyem_bnrm(1,il)**2 + gsyem_bnrm(2,il)**2)
858  gsyem_rang(il) = atan2(rtmp,gsyem_bnrm(3,il))
859  endif
860  enddo
861 
862  ! Redefine bounding box using average normal and current box extend
863  ! In this step I simply project bounding box vectors on a surface
864  ! orthogonal to normal vector moving coordinate centre to
865  ! averaged family position
866  do il=1,gsyem_nfam
867  ! min
868  rtmp = 0.0
869  do jl=1,ldim
870  rtmp = rtmp + (gsyem_bmin(jl,il) - gsyem_bcrd(jl,il))*
871  $ gsyem_bnrm(jl,il)
872  enddo
873  do jl=1,ldim
874  gsyem_bmin(jl,il) = (gsyem_bmin(jl,il) - gsyem_bcrd(jl,il)) -
875  $ rtmp*gsyem_bnrm(jl,il)
876  enddo
877  ! max
878  rtmp = 0.0
879  do jl=1,ldim
880  rtmp = rtmp + (gsyem_bmax(jl,il) - gsyem_bcrd(jl,il))*
881  $ gsyem_bnrm(jl,il)
882  enddo
883  do jl=1,ldim
884  gsyem_bmax(jl,il) = (gsyem_bmax(jl,il) - gsyem_bcrd(jl,il)) -
885  $ rtmp*gsyem_bnrm(jl,il)
886  enddo
887 
888  ! rotate bounding box to get 2D constraint; THIS IS NOT FINISHED
889  call math_rot3da(drtmp,gsyem_bmin(1,il),
890  $ gsyem_raxs(1,il),-gsyem_rang(il))
891  call math_rot3da(drtmp,gsyem_bmax(1,il),
892  $ gsyem_raxs(1,il),-gsyem_rang(il))
893 
894  ! Should I shift edges to the surface normal to gsyem_bcrd???????
895 
896  ! update max allowed vertex size looking for min distance
897  ! between family averaged centre and the edge
898  ! This part is different form the original code !!!!!!
899  gsyem_cln_min(il) = 99.0e20
900  gsyem_cln_max(il) = -99.0e20
901  do jl = 1,gsyem_genum(il)
902  do ll=1,lx1
903  rtmp = 0.0
904  do kl=1,ldim
905  rtmp = rtmp +
906  $ (gsyem_bcrd(kl,il)-xyz_ewall(kl,ll,jl,il))**2
907  enddo
908  rtmp = sqrt(rtmp)
909  gsyem_cln_min(il) = min(gsyem_cln_min(il),rtmp)
910  gsyem_cln_max(il) = max(gsyem_cln_max(il),rtmp)
911  enddo
912  enddo
913  enddo
914  call gop(gsyem_cln_min,work,'m ',gsyem_nfam_max)
915  call gop(gsyem_cln_max,work,'M ',gsyem_nfam_max)
916  ! In the origianl code this should be ralated to sigma_max
917 
918  ! Generate face information
919  call mntr_log(gsyem_id,lp_inf,'Generate face information')
920  ! initial values
921  rtmp = -99.0e20
922  call cfill(gsyem_mdst,rtmp,gsyem_nfam_max)
923  call rzero(gsyem_sigma,lx1*lz1*6*lelt)
924  call rzero(gsyem_umean,lx1*lz1*6*lelt)
925  call rzero(gsyem_intn,lx1*lz1*6*lelt)
926  call rzero(gsyem_ub,ldim*gsyem_nfam_max)
927  itmp=lx1*lz1
928  ! face loop
929  do il=1,gsyem_nfam
930  do jl=1,gsyem_lfnum(il)
931  iel = gsyem_lfmap(1,jl,il)
932  ifc = gsyem_lfmap(2,jl,il)
933 
934  ! extract coordinates
935  call ftovec(vrtmp,xm1,iel,ifc,lx1,ly1,lz1)
936  do kl=1,itmp
937  drtmp(1,kl) = vrtmp(kl)
938  enddo
939  call ftovec(vrtmp,ym1,iel,ifc,lx1,ly1,lz1)
940  do kl=1,itmp
941  drtmp(2,kl) = vrtmp(kl)
942  enddo
943  call ftovec(vrtmp,zm1,iel,ifc,lx1,ly1,lz1)
944  do kl=1,itmp
945  drtmp(ldim,kl) = vrtmp(kl)
946  enddo
947 
948  ! Should I shift drtmp to the surface normal to gsyem_bcrd?????
949 
950  ! get min distance from the wall edge
951  ! Not very fancy, but done only once, so not urgent to improve
952  rtmp = 99.0e20
953  call cfill(vrtmp,rtmp,lx1*lz1)
954  do kl=1,gsyem_genum(il)
955  do ll=1,lx1
956  do ml=1,lx1*lz1
957  rtmp = 0.0
958  do nl=1,ldim
959  rtmp = rtmp +
960  $ (xyz_ewall(nl,ll,kl,il)-drtmp(nl,ml))**2
961  enddo
962  rtmp = sqrt(rtmp)
963  vrtmp(ml) = min(vrtmp(ml),rtmp)
964  enddo
965  enddo
966  enddo
967  ! fill face arrays with profile values
968  ifn = gsyem_foff(il) + jl - 1
969  call gsyem_face_prof(il,poff,rpos,umean,tke,dss,
970  $ iel,ifc,ifn,vrtmp)
971 
972  ! update max distance
973  rtmp = vlmax(vrtmp,lx1*lz1)
974  gsyem_mdst(il) = max(gsyem_mdst(il),rtmp)
975  enddo
976  enddo
977  ! global operations
978  call gop(gsyem_ub,work,'+ ',ldim*gsyem_nfam_max)
979  call gop(gsyem_mdst,work,'M ',gsyem_nfam_max)
980 
981  ! average bulk velocity and project it on normal direction
982  do il=1,gsyem_nfam
983  rtmp = 1.0/gsyem_area(il)
984  do jl=1,ldim
985  gsyem_ub(jl,il) = gsyem_ub(jl,il)*rtmp
986  enddo
987  if (gsyem_dirl(il)) then
988  gsyem_un(il) = 0.0
989  do jl=1,ldim
990  gsyem_un(il) = gsyem_un(il) +
991  $ gsyem_ub(jl,il)*gsyem_bnrm(jl,il)
992  enddo
993  else
994  gsyem_un(il) = 0.0
995  do jl=1,ldim
996  gsyem_un(il) = gsyem_un(il) + gsyem_ub(jl,il)**2
997  enddo
998  gsyem_un(il) = sqrt(gsyem_un(il))
999  endif
1000 
1001  ! box extent in normal direction
1002  gsyem_bext(il) = min(gsyem_sig_max(il),gsyem_cln_min(il))
1003  enddo
1004 
1005  ! stamp logs
1006  call mntr_log(gsyem_id,lp_inf,'General family information')
1007  do il=1,gsyem_nfam
1008  call mntr_logi(gsyem_id,lp_inf,'Family: ',il)
1009  call mntr_log(gsyem_id,lp_inf,'Boundary box:')
1010  call mntr_logr(gsyem_id,lp_inf,'min x=',gsyem_bmin(1,il))
1011  call mntr_logr(gsyem_id,lp_inf,'min y=',gsyem_bmin(2,il))
1012  call mntr_logr(gsyem_id,lp_inf,'min z=',gsyem_bmin(3,il))
1013  call mntr_logr(gsyem_id,lp_inf,'max x=',gsyem_bmax(1,il))
1014  call mntr_logr(gsyem_id,lp_inf,'max y=',gsyem_bmax(2,il))
1015  call mntr_logr(gsyem_id,lp_inf,'max z=',gsyem_bmax(3,il))
1016  call mntr_log(gsyem_id,lp_inf,'Average centre coordiantes:')
1017  call mntr_logr(gsyem_id,lp_inf,'x=',gsyem_bcrd(1,il))
1018  call mntr_logr(gsyem_id,lp_inf,'y=',gsyem_bcrd(2,il))
1019  call mntr_logr(gsyem_id,lp_inf,'z=',gsyem_bcrd(3,il))
1020  call mntr_log(gsyem_id,lp_inf,'Average normal:')
1021  call mntr_logr(gsyem_id,lp_inf,'x=',gsyem_bnrm(1,il))
1022  call mntr_logr(gsyem_id,lp_inf,'y=',gsyem_bnrm(2,il))
1023  call mntr_logr(gsyem_id,lp_inf,'z=',gsyem_bnrm(3,il))
1024  call mntr_log(gsyem_id,lp_inf,'Rotation axis:')
1025  call mntr_logr(gsyem_id,lp_inf,'rx=',gsyem_raxs(1,il))
1026  call mntr_logr(gsyem_id,lp_inf,'ry=',gsyem_raxs(2,il))
1027  call mntr_logr(gsyem_id,lp_inf,'rz=',gsyem_raxs(3,il))
1028  call mntr_log(gsyem_id,lp_inf,'Rotation angle:')
1029  call mntr_logr(gsyem_id,lp_inf,'ang=',gsyem_rang(il))
1030  call mntr_log(gsyem_id,lp_inf,'Characteristic length:')
1031  call mntr_logr(gsyem_id,lp_inf,'min=',gsyem_cln_min(il))
1032  call mntr_logr(gsyem_id,lp_inf,'max=',gsyem_cln_max(il))
1033  call mntr_log(gsyem_id,lp_inf,'Box extent in norm. dir.:')
1034  call mntr_logr(gsyem_id,lp_inf,'bext=',2.0*gsyem_bext(il))
1035  call mntr_log(gsyem_id,lp_inf,'Max point distance:')
1036  call mntr_logr(gsyem_id,lp_inf,'min=',gsyem_mdst(il))
1037  call mntr_log(gsyem_id,lp_inf,'Surface area:')
1038  call mntr_logr(gsyem_id,lp_inf,'area=',gsyem_area(il))
1039  call mntr_log(gsyem_id,lp_inf,'Bulk velocity:')
1040  call mntr_logr(gsyem_id,lp_inf,'ubx=',gsyem_ub(1,il))
1041  call mntr_logr(gsyem_id,lp_inf,'uby=',gsyem_ub(2,il))
1042  call mntr_logr(gsyem_id,lp_inf,'ubz=',gsyem_ub(3,il))
1043  call mntr_log(gsyem_id,lp_inf,'Projected bulk velocity:')
1044  call mntr_logr(gsyem_id,lp_inf,'un=',gsyem_un(il))
1045  enddo
1046 
1047  return
1048  end subroutine
1049 !=======================================================================
1058  subroutine gsyem_prof_read(npoint,poff,rpos,umean,tke,dss)
1059  implicit none
1060 
1061  include 'SIZE'
1062  include 'INPUT'
1063  include 'PARALLEL'
1064  include 'FRAMELP'
1065  include 'GSYEMD'
1066 
1067  ! argument list
1068  integer npoint(gsyem_nfam_max), poff(gsyem_nfam_max+1)
1069  real rpos(gsyem_npoint_max*gsyem_nfam_max)
1070  real umean(gsyem_npoint_max*gsyem_nfam_max)
1071  real tke(gsyem_npoint_max*gsyem_nfam_max)
1072  real dss(gsyem_npoint_max*gsyem_nfam_max)
1073 
1074  ! local variables
1075  integer itmp, il, jl, ierr, iunit
1076  character*132 fname
1077  character*3 str
1078 !-----------------------------------------------------------------------
1079  ! stamp logs
1080  call mntr_log(gsyem_id,lp_prd,'Reading family profiles')
1081 
1082  ! zero arrays
1083  itmp = gsyem_npoint_max*gsyem_nfam_max
1084  call rzero(rpos,itmp)
1085  call rzero(umean,itmp)
1086  call rzero(tke,itmp)
1087  call rzero(dss,itmp)
1088 
1089  ! reading done by master only
1090  ierr = 0
1091  if (nid.eq.0) then
1092  ! loop over families
1093  poff(1) = 1
1094  do il=1,gsyem_nfam
1095  call io_file_freeid(iunit, ierr)
1096  if (ierr.eq.0) then
1097  write(str,'(i2.2)') gsyem_fambc(il)
1098  fname='gsyem_prof_'//trim(adjustl(str))//'.txt'
1099  open(unit=iunit,file=fname,status='old',iostat=ierr)
1100  if (ierr.eq.0) then
1101  read(iunit,*,iostat=ierr) ! skip header
1102  read(iunit,*,iostat=ierr) npoint(il)
1103  if (npoint(il).gt.gsyem_npoint_max.or.
1104  $ npoint(il).le.0) then
1105  call mntr_log_local(gsyem_id,lp_prd,
1106  $ 'Wrong piont number in '//trim(adjustl(fname)),nid)
1107  ierr=1
1108  exit
1109  endif
1110  read(iunit,*) ! skip header
1111  do jl=0,npoint(il) - 1
1112  itmp = poff(il) + jl
1113  read(iunit,*,iostat=ierr) rpos(itmp),umean(itmp),
1114  $ tke(itmp),dss(itmp)
1115  if(ierr.ne.0) exit
1116  enddo
1117  close(iunit)
1118  poff(il+1) = poff(il) + npoint(il)
1119  endif
1120  endif
1121  if (ierr.ne.0) exit
1122  enddo
1123  endif
1124  call mntr_check_abort(gsyem_id,ierr,'Error reading profile file')
1125 
1126  ! broadcast data
1127  call bcast(npoint,gsyem_nfam*isize)
1128  call bcast(poff,(gsyem_nfam+1)*isize)
1129  itmp = (poff(gsyem_nfam+1)-1)*wdsize
1130  call bcast(rpos,itmp)
1131  call bcast(umean,itmp)
1132  call bcast(tke,itmp)
1133  call bcast(dss,itmp)
1134 
1135  return
1136  end subroutine
1137 !=======================================================================
1150  subroutine gsyem_face_prof(nfam,poff,rpos,umean,tke,dss,
1151  $ iel,ifc,ifn,dist)
1152  implicit none
1153 
1154  include 'SIZE'
1155  include 'INPUT'
1156  include 'GEOM'
1157  include 'FRAMELP'
1158  include 'GSYEMD'
1159 
1160  ! argument list
1161  integer nfam, iel, ifc, ifn
1162  integer poff(gsyem_nfam_max+1)
1163  real rpos(gsyem_npoint_max*gsyem_nfam_max)
1164  real umean(gsyem_npoint_max*gsyem_nfam_max)
1165  real tke(gsyem_npoint_max*gsyem_nfam_max)
1166  real dss(gsyem_npoint_max*gsyem_nfam_max)
1167  real dist(lx1,lz1)
1168 
1169  ! local variables
1170  integer itmp, il, jl, kl
1171  real nrtmp1(lx1*lz1), nrtmp2(lx1*lz1)
1172  real pvel, ptke, pdss, int1, int2, rtmp
1173  real twothr
1174  parameter(twothr=2.0/3.0)
1175 
1176  ! functions
1177  real vlsum
1178 !-----------------------------------------------------------------------
1179  ! get profile values
1180  do jl=1,lz1
1181  do il=1,lx1
1182  ! find position in a profile
1183  ! not very efficient, but done only dutring intialisation
1184  ! so improvemnt not urgent
1185  itmp = poff(nfam+1)-1
1186  pvel = umean(itmp)
1187  ptke = tke(itmp)
1188  pdss = dss(itmp)
1189  do kl=poff(nfam)+1,itmp
1190  if (dist(il,jl).le.rpos(kl)) then
1191  rtmp = 1.0/(rpos(kl) - rpos(kl-1))
1192  int1 = (rpos(kl) - dist(il,jl))*rtmp
1193  int2 = (dist(il,jl)-rpos(kl-1))*rtmp
1194  pvel = int1*umean(kl-1) + int2*umean(kl)
1195  ptke = int1*tke(kl-1) + int2*tke(kl)
1196  pdss = int1*dss(kl-1) + int2*dss(kl)
1197  exit
1198  endif
1199  enddo
1200  ! find vertex size
1201  ! formula 8.2.3 of Poletto's PhD
1202  rtmp = ptke**1.5/pdss
1203 
1204  ! Limit eddy size far away from wall
1205  ! to Prandtl's mixing length
1206  ! kappa is .41, max_range is the distance to the wall
1207  ! THIS PART OF THE CODE IS MODIFIED
1208  rtmp = min(rtmp,0.41*gsyem_cln_max(nfam))
1209 
1210  ! make eddies no larger than box
1211  rtmp = min(rtmp,dist(il,jl))
1212 
1213  ! avoid creating too small eddies (0.001 is chosen arbitrarly)
1214  ! THIS SHOULD BE RELATED TO RESOLUTION
1215  rtmp = max(rtmp,0.001*gsyem_cln_min(nfam))
1216 
1217  ! apply user defined cutoff
1218  rtmp = min(max(rtmp,gsyem_sig_min(nfam)),gsyem_sig_max(nfam))
1219 
1220  ! fill in profiles
1221  gsyem_sigma(il,jl,ifn) = rtmp
1222  gsyem_umean(il,jl,ifn) = pvel
1223  gsyem_intn(il,jl,ifn) = sqrt(twothr*ptke)
1224  enddo
1225  enddo
1226 
1227  ! get bulk velocity depending on family normal flag
1228  itmp = lx1*lz1
1229  call col3(nrtmp1,gsyem_umean(1,1,ifn),area(1,1,ifc,iel),itmp)
1230  if (gsyem_dirl(nfam)) then
1231  call col3(nrtmp2,nrtmp1,unx(1,1,ifc,iel),itmp)
1232  gsyem_ub(1,nfam) = gsyem_ub(1,nfam) - vlsum(nrtmp2,itmp)
1233  call col3(nrtmp2,nrtmp1,uny(1,1,ifc,iel),itmp)
1234  gsyem_ub(2,nfam) = gsyem_ub(2,nfam) - vlsum(nrtmp2,itmp)
1235  call col3(nrtmp2,nrtmp1,unz(1,1,ifc,iel),itmp)
1236  gsyem_ub(3,nfam) = gsyem_ub(3,nfam) - vlsum(nrtmp2,itmp)
1237  else
1238  do il=1,ldim
1239  call copy(nrtmp2,nrtmp1,itmp)
1240  call cmult(nrtmp2,gsyem_dir(il,nfam),itmp)
1241  gsyem_ub(il,nfam) = gsyem_ub(il,nfam) + vlsum(nrtmp2,itmp)
1242  enddo
1243  endif
1244 
1245  return
1246  end subroutine
1247 !=======================================================================
1255  subroutine gsyem_gen_elist(elist,neddy,nfam,ifinit)
1256  implicit none
1257 
1258  include 'SIZE'
1259  include 'PARALLEL'
1260  include 'FRAMELP'
1261  include 'GSYEMD'
1262 
1263  ! argument list
1264  integer neddy, nfam, elist(neddy)
1265  logical ifinit
1266 
1267  ! local variables
1268  integer il, itmp1, itmp2, ierr
1269  character*50 str
1270 
1271  ! work arrays USE SCRATCH IN THE FUTURE !!!!!!
1272  real eposl(ldim,gsyem_neddy_max)
1273  integer epsl(ldim,gsyem_neddy_max)
1274 
1275  ! function
1276  integer mntr_lp_def_get
1277 !-----------------------------------------------------------------------
1278  ! generate set of eddies
1279  if (nid.eq.0) then
1280  do il=1,neddy
1281  call usr_gen_eddy(eposl(1,il),epsl(1,il),nfam,ifinit)
1282  enddo
1283  endif
1284 
1285  ! broadcast eddy data
1286  call bcast(neddy,isize)
1287  call bcast(elist,neddy*isize)
1288  call bcast(eposl,ldim*neddy*wdsize)
1289  call bcast(epsl,ldim*neddy*isize)
1290 
1291  ! put data on place
1292  itmp1 = gsyem_eoff(nfam)
1293  itmp2 = gsyem_eoff(nfam+1)-1
1294  ierr = 0
1295  do il=1,neddy
1296  ! sanity check
1297  if (elist(il).lt.itmp1.or.elist(il).gt.itmp2) then
1298  ierr = 1
1299  exit
1300  endif
1301  call copy(gsyem_epos(1,elist(il)),eposl(1,il),ldim)
1302  call icopy(gsyem_eps(1,elist(il)),epsl(1,il),ldim)
1303  enddo
1304  call mntr_check_abort(gsyem_id,ierr,'Eddy outside family range')
1305 
1306  ! stamp logs
1307  call mntr_logi(gsyem_id,lp_prd,'Generated new eddies neddy=',
1308  $ neddy)
1309  ! verbose output
1310  if (mntr_lp_def_get().lt.lp_inf) then
1311  do il=1,neddy
1312  write(str,20) elist(il),eposl(1,il),eposl(2,il),eposl(3,il)
1313  20 format('edn=',i6,' ex=',f9.5,' ey=',f9.5,' ez=',f9.5)
1314  call mntr_log(gsyem_id,lp_vrb,str)
1315  enddo
1316  endif
1317 
1318  return
1319  end subroutine
1320 !=======================================================================
1324  subroutine gsyem_gen_eall(nfam)
1325  implicit none
1326 
1327  include 'SIZE'
1328  include 'FRAMELP'
1329  include 'GSYEMD'
1330 
1331  ! argument list
1332  integer nfam
1333 
1334  ! local variables
1335  integer neddy, il
1336  logical ifinit
1337 
1338  ! work arrays USE SCRATCH IN THE FUTURE !!!!!!
1339  integer elist(gsyem_neddy_max)
1340 !-----------------------------------------------------------------------
1341  ! stamp logs
1342  call mntr_logi(gsyem_id,lp_prd,'Initilise eddies for family=',
1343  $ nfam)
1344 
1345  ! take all eddies in the family and set initialisation flag
1346  neddy = gsyem_neddy(nfam)
1347  do il=1,neddy
1348  elist(il) = gsyem_eoff(nfam) + il - 1
1349  enddo
1350  ifinit = .true.
1351 
1352  call gsyem_gen_elist(elist,neddy,nfam,ifinit)
1353 
1354  return
1355  end subroutine
1356 !=======================================================================
1360  subroutine gsyem_adv_eddy(nfam)
1361  implicit none
1362 
1363  include 'SIZE'
1364  include 'TSTEP' ! DT
1365  include 'FRAMELP'
1366  include 'GSYEMD'
1367 
1368  ! argument list
1369  integer nfam
1370 
1371  ! local variables
1372  integer neddy, il, jl, itmp
1373  real rtmp
1374  logical ifinit
1375 
1376  ! work arrays USE SCRATCH IN THE FUTURE !!!!!!
1377  integer elist(gsyem_neddy_max)
1378 !-----------------------------------------------------------------------
1379  ! stamp logs
1380  call mntr_logi(gsyem_id,lp_prd,'Advect eddies for family=',nfam)
1381 
1382  ! advect eddies and mark the once to be recycled
1383  neddy=0
1384  do il=0,gsyem_neddy(nfam)-1
1385  itmp = gsyem_eoff(nfam)+il
1386  rtmp = 0.0
1387  do jl=1,ldim
1388  gsyem_epos(jl,itmp) = gsyem_epos(jl,itmp) +
1389  $ dt*gsyem_un(nfam)*gsyem_bnrm(jl,nfam)
1390  ! get distance with respect to family centre
1391  rtmp = rtmp + (gsyem_epos(jl,itmp)-gsyem_bcrd(jl,nfam))*
1392  $ gsyem_bnrm(jl,nfam)
1393  enddo
1394  if (rtmp.gt.gsyem_bext(nfam)) then
1395  neddy=neddy+1
1396  elist(neddy) = itmp
1397  endif
1398  enddo
1399 
1400  ! recreate eddies
1401  ifinit = .false.
1402  call gsyem_gen_elist(elist,neddy,nfam,ifinit)
1403 
1404  return
1405  end subroutine
1406 !=======================================================================
1410  subroutine gsyem_gen_mall(nfam)
1411  implicit none
1412 
1413  include 'SIZE'
1414  include 'TSTEP' ! pi
1415  include 'PARALLEL'
1416  include 'FRAMELP'
1417  include 'GSYEMD'
1418 
1419  ! argument list
1420  integer nfam
1421 
1422  ! local variables
1423  integer il, jl, itmp
1424 
1425  ! functions
1426  real math_ran_rng
1427 !-----------------------------------------------------------------------
1428  ! stamp logs
1429  call mntr_logi(gsyem_id,lp_prd,'Initilise modes for family=',nfam)
1430 
1431  ! set all modes
1432  if (nid.eq.0) then
1433  do il=0,gsyem_neddy(nfam)-1
1434  itmp = gsyem_eoff(nfam)+il
1435  do jl=1,ldim
1436  gsyem_eamp(jl,itmp) = math_ran_rng(0.0,1.0)
1437  gsyem_ephs(jl,itmp) = math_ran_rng(0.0,2.0*pi)
1438  enddo
1439  enddo
1440  endif
1441 
1442  ! broadcast modes
1443  call bcast(gsyem_eamp(1,gsyem_eoff(nfam)),
1444  $ ldim*gsyem_neddy(nfam)*wdsize)
1445  call bcast(gsyem_ephs(1,gsyem_eoff(nfam)),
1446  $ ldim*gsyem_neddy(nfam)*wdsize)
1447 
1448  return
1449  end subroutine
1450 !=======================================================================
1453  subroutine gsyem_evolve()
1454  implicit none
1455 
1456  include 'SIZE'
1457  include 'GSYEMD'
1458 
1459  ! local variables
1460  integer il
1461 !-----------------------------------------------------------------------
1462  ! for different gSyEM modes
1463  if (gsyem_mode.eq.1) then
1464  do il=1,gsyem_nfam
1465  call gsyem_adv_eddy(il)
1466  call gsyem_iso(il)
1467  enddo
1468  elseif (gsyem_mode.eq.2) then
1469  elseif (gsyem_mode.eq.3) then
1470  do il=1,gsyem_nfam
1471  call gsyem_dairay(il)
1472  enddo
1473  endif
1474 
1475  return
1476  end subroutine
1477 !=======================================================================
1482  subroutine gsyem_iso(nfam)
1483  implicit none
1484 
1485  include 'SIZE'
1486  include 'TSTEP' ! PI
1487  include 'GEOM'
1488  include 'SOLN'
1489  include 'FRAMELP'
1490  include 'GSYEMD'
1491 
1492  ! argument list
1493  integer nfam
1494 
1495  ! local variables
1496  integer il, jl, kl, ll, ml
1497  integer iel, ifc, ifn, itmp, itmp2
1498  real vrtmp(lx1*lz1,ldim), drtmp(ldim,lx1*lz1)
1499  real sqrt32
1500  parameter(sqrt32=sqrt(1.5))
1501  real bulk_vel(ldim), vb
1502  real sqrtn, dr(ldim), rtmp, rtmp2, fc(ldim), fcm
1503  ! to spped up eddy search
1504  integer icount, ipos, iepos(gsyem_neddy_max)
1505  real el_dist, el_cnt(ldim)
1506 
1507  ! functions
1508  real vlsum, vlmax
1509 !-----------------------------------------------------------------------
1510  call rzero(bulk_vel,ldim)
1511  ! this definition can differ slightly from origianl code !!!!!!
1512  ! approximated volume of controlled region
1513  vb = 2.0*gsyem_area(nfam)*gsyem_bext(nfam)
1514  ! weighting parameter
1515  sqrtn = sqrt(16.0*vb/15/pi/real(gsyem_neddy(nfam)))
1516 
1517  ! loop over faces
1518  itmp = lx1*lz1
1519  do il=1,gsyem_lfnum(nfam)
1520  ! local element and face number
1521  iel = gsyem_lfmap(1,il,nfam)
1522  ifc = gsyem_lfmap(2,il,nfam)
1523  ! position in face arrays
1524  ifn = gsyem_foff(nfam) + il - 1
1525 
1526  ! extract coordinates and get element centre
1527  rtmp = 1.0/real(itmp)
1528  call ftovec(vrtmp,xm1,iel,ifc,lx1,ly1,lz1)
1529  do jl=1,itmp
1530  drtmp(1,jl) = vrtmp(jl,1)
1531  enddo
1532  el_cnt(1) = rtmp*vlsum(vrtmp,itmp)
1533  call ftovec(vrtmp,ym1,iel,ifc,lx1,ly1,lz1)
1534  do jl=1,itmp
1535  drtmp(2,jl) = vrtmp(jl,1)
1536  enddo
1537  el_cnt(2) = rtmp*vlsum(vrtmp,itmp)
1538  call ftovec(vrtmp,zm1,iel,ifc,lx1,ly1,lz1)
1539  do jl=1,itmp
1540  drtmp(ldim,jl) = vrtmp(jl,1)
1541  enddo
1542  el_cnt(ldim) = rtmp*vlsum(vrtmp,itmp)
1543 
1544  ! to speed up eddy search
1545  ! get characteristic element lenght (max centre-vertex distance)
1546  call rzero(vrtmp,itmp)
1547  do jl=1,ldim
1548  vrtmp(1,1) = vrtmp(1,1)+(drtmp(jl,1)-el_cnt(jl))**2
1549  vrtmp(2,1) = vrtmp(2,1)+(drtmp(jl,lx1)-el_cnt(jl))**2
1550  vrtmp(3,1) = vrtmp(3,1)+(drtmp(jl,itmp-lx1+1)-el_cnt(jl))**2
1551  vrtmp(4,1) = vrtmp(4,1)+(drtmp(jl,itmp)-el_cnt(jl))**2
1552  enddo
1553  el_dist = sqrt(vlmax(vrtmp,4))
1554  ! add max vertex size for given face
1555  el_dist = el_dist + vlmax(gsyem_sigma(1,1,ifn),itmp)
1556  ! safety buffer
1557  el_dist = 1.1*el_dist
1558 
1559  ! find eddies inside a sphere surrounding element centre
1560  ! loop over all eddies
1561  icount = 0
1562  call izero(iepos,gsyem_neddy_max)
1563  do kl=0,gsyem_neddy(nfam)-1
1564  ipos = gsyem_eoff(nfam)+kl
1565  rtmp = 0.0
1566  do ll=1,ldim
1567  dr(ll) = el_cnt(ll) - gsyem_epos(ll,ipos)
1568  rtmp = rtmp + dr(ll)**2
1569  enddo
1570  rtmp = sqrt(rtmp)
1571  if (rtmp.le.el_dist) then
1572  icount = icount + 1
1573  iepos(icount) = ipos
1574  endif
1575  enddo
1576 
1577  ! add velocity profile
1578  if (gsyem_dirl(nfam)) then
1579  call rzero(vrtmp,lx1*lz1*ldim)
1580  call subcol3(vrtmp(1,1),unx(1,1,ifc,iel),
1581  $ gsyem_umean(1,1,ifn),itmp)
1582  call subcol3(vrtmp(1,2),uny(1,1,ifc,iel),
1583  $ gsyem_umean(1,1,ifn),itmp)
1584  call subcol3(vrtmp(1,3),unz(1,1,ifc,iel),
1585  $ gsyem_umean(1,1,ifn),itmp)
1586  else
1587  do kl=1,ldim
1588  call copy(vrtmp(1,kl),gsyem_umean(1,1,ifn),itmp)
1589  call cmult(vrtmp(1,kl),gsyem_dir(kl,nfam),itmp)
1590  enddo
1591  endif
1592 
1593  ! loop over all points in the face
1594  do jl=1,lz1
1595  itmp2 = (jl-1)*lz1
1596  do kl=1,lx1
1597  ! loop over all marked eddies
1598  do ll=1,icount
1599  rtmp = 0.0
1600  do ml=1,ldim
1601  dr(ml)=drtmp(ml,itmp2+kl)-gsyem_epos(ml,iepos(ll))
1602  rtmp = rtmp + dr(ml)**2
1603  enddo
1604  rtmp = sqrt(rtmp)
1605  rtmp2 = gsyem_sigma(kl,jl,ifn)
1606  if (rtmp.le.rtmp2) then
1607  rtmp2 = 1.0/rtmp2
1608 
1609  ! vector product of eddy relative position and
1610  ! eddy orientation
1611  ! NOTICE eddy orientation is not rotated
1612  fc(1) = dr(2)*gsyem_eps(3,iepos(ll)) -
1613  $ dr(3)*gsyem_eps(2,iepos(ll))
1614  fc(2) = dr(3)*gsyem_eps(1,iepos(ll)) -
1615  $ dr(1)*gsyem_eps(3,iepos(ll))
1616  fc(3) = dr(1)*gsyem_eps(2,iepos(ll)) -
1617  $ dr(2)*gsyem_eps(1,iepos(ll))
1618 
1619  ! perturbation amplitude
1620  ! original code looks strange !!!!!!!!!
1621  ! short version
1622  fcm = sqrtn*gsyem_intn(kl,jl,ifn)*sqrt(rtmp2)*
1623  $ sin(pi*rtmp*rtmp2)**2/rtmp**2
1624 
1625  ! update purturbed velocity
1626  do ml=1,ldim
1627  vrtmp(itmp2+kl,ml) = vrtmp(itmp2+kl,ml) +
1628  $ fcm*fc(ml)
1629  enddo
1630  endif
1631  enddo
1632  enddo
1633  enddo
1634 
1635  ! fill in velocity array
1636  call vectof(vx,vrtmp(1,1),iel,ifc,lx1,ly1,lz1)
1637  call vectof(vy,vrtmp(1,2),iel,ifc,lx1,ly1,lz1)
1638  call vectof(vz,vrtmp(1,3),iel,ifc,lx1,ly1,lz1)
1639 
1640  ! get current bulk velocity
1641  do ml=1,ldim
1642  call col2(vrtmp(1,ml),area(1,1,ifc,iel),itmp)
1643  bulk_vel(ml) = bulk_vel(ml) + vlsum(vrtmp(1,ml),itmp)
1644  enddo
1645  enddo
1646 
1647  ! global operations
1648  call gop(bulk_vel,fc,'+ ',ldim)
1649 
1650  ! average bulk velocity
1651  rtmp = 1.0/gsyem_area(nfam)
1652  call cmult(bulk_vel,rtmp,ldim)
1653 
1654  ! correct inflow velocity
1655  itmp = lx1*lz1
1656  do ml=1,ldim
1657  rtmp = gsyem_ub(ml,nfam) - bulk_vel(ml)
1658  call cfill(vrtmp(1,ml),rtmp,itmp)
1659  enddo
1660  ! loop over faces
1661  do il=1,gsyem_lfnum(nfam)
1662  ! local element and face number
1663  iel = gsyem_lfmap(1,il,nfam)
1664  ifc = gsyem_lfmap(2,il,nfam)
1665  call vectof_add(vx,vrtmp(1,1),iel,ifc,lx1,ly1,lz1)
1666  call vectof_add(vy,vrtmp(1,2),iel,ifc,lx1,ly1,lz1)
1667  call vectof_add(vz,vrtmp(1,3),iel,ifc,lx1,ly1,lz1)
1668  enddo
1669 
1670 ! call nekgsync()
1671 
1672  return
1673  end subroutine
1674 !=======================================================================
1679  subroutine gsyem_dairay(nfam)
1680  implicit none
1681 
1682  include 'SIZE'
1683 ! include 'TSTEP' ! PI
1684  include 'GEOM'
1685  include 'SOLN'
1686  include 'FRAMELP'
1687  include 'GSYEMD'
1688 
1689  ! argument list
1690  integer nfam
1691 
1692  ! local variables
1693 !-----------------------------------------------------------------------
1694 
1695 
1696  return
1697  end subroutine
1698 !=======================================================================
#define byte_open
Definition: byte.c:35
#define byte_reverse
Definition: byte.c:33
#define byte_write
Definition: byte.c:39
#define byte_close
Definition: byte.c:36
#define byte_read
Definition: byte.c:38
subroutine gop(x, w, op, n)
Definition: comm_mpi.f:201
subroutine nekgsync()
Definition: comm_mpi.f:502
subroutine bcast(buf, len)
Definition: comm_mpi.f:431
subroutine ftovec(a, b, ie, iface, nx, ny, nz)
Definition: dssum.f:417
subroutine vectof_add(b, a, ie, iface, nx, ny, nz)
Definition: dssum.f:364
subroutine vectof(b, a, ie, iface, nx, ny, nz)
Definition: dssum.f:435
subroutine chkpt_get_fset(step_cnt, set_out)
Get step count to the checkpoint and a set number.
Definition: chkpt.f:256
subroutine gsyem_dairay(nfam)
Fill velocity array with eddies; Dairay.
Definition: gSyEM.f:1680
subroutine gsyem_adv_eddy(nfam)
Advect/recycle eddies (gsyem_mode.eq.1) for a given family.
Definition: gSyEM.f:1361
subroutine gsyem_register()
Register gSyEM module.
Definition: gSyEM.f:14
subroutine gsyem_evolve()
Time evolution of eddies.
Definition: gSyEM.f:1454
subroutine gsyem_gen_mall(nfam)
Inital generation of all modes (gsyem_mode.eq.3) for a given family.
Definition: gSyEM.f:1411
subroutine gsyem_gen_eall(nfam)
Inital generation of all eddies (gsyem_mode.eq.1) for a given family.
Definition: gSyEM.f:1325
subroutine gsyem_init()
Initilise gSyEM module.
Definition: gSyEM.f:117
subroutine gsyem_rst_write
Create checkpoint.
Definition: gSyEM.f:336
subroutine gsyem_fam_setup(npoint, poff, rpos, umean, tke, dss)
Generate family information.
Definition: gSyEM.f:688
subroutine gsyem_gen_elist(elist, neddy, nfam, ifinit)
Generate eddies from the list for a given family.
Definition: gSyEM.f:1256
subroutine gsyem_main
Main gSyEM interface.
Definition: gSyEM.f:300
subroutine gsyem_mesh_setup()
Generate mesh dependent information.
Definition: gSyEM.f:597
subroutine gsyem_rst_read
Read from checkpoint.
Definition: gSyEM.f:457
subroutine gsyem_prof_read(npoint, poff, rpos, umean, tke, dss)
Read profiles for all familes.
Definition: gSyEM.f:1059
logical function gsyem_is_initialised()
Check if module was initialised.
Definition: gSyEM.f:287
subroutine gsyem_face_prof(nfam, poff, rpos, umean, tke, dss, iel, ifc, ifn, dist)
Generate profile information for given family face.
Definition: gSyEM.f:1152
subroutine gsyem_iso(nfam)
Fill velocity array with eddies; ISO.
Definition: gSyEM.f:1483
subroutine io_file_freeid(iunit, ierr)
Get free file unit number and store max unit value.
Definition: io_tools.f:47
subroutine math_etovec(vec, edg, vfld, nx, ny, nz)
Extract 3D element edge.
Definition: math_tools.f:299
subroutine math_zbqlini(seed)
Initialise Marsaglia-Zaman random number generator.
Definition: math_tools.f:180
subroutine math_rot3da(vo, vi, va, an)
3D rotation of a vector along given axis.
Definition: math_tools.f:332
subroutine mntr_logi(mid, priority, logs, ivar)
Write log message adding single integer.
Definition: mntrlog.f:709
subroutine mntr_tmr_is_name_reg(mid, mname)
Check if timer name is registered and return its id.
Definition: mntrtmr.f:146
subroutine mntr_logr(mid, priority, logs, rvar)
Write log message adding single real.
Definition: mntrlog.f:731
subroutine mntr_warn(mid, logs)
Write warning message.
Definition: mntrlog.f:803
subroutine mntr_tmr_add(mid, icount, time)
Check if timer id is registered. This operation is performed locally.
Definition: mntrtmr.f:237
subroutine mntr_mod_is_name_reg(mid, mname)
Check if module name is registered and return its id.
Definition: mntrlog.f:459
subroutine mntr_abort(mid, logs)
Abort simulation.
Definition: mntrlog.f:837
subroutine mntr_log(mid, priority, logs)
Write log message.
Definition: mntrlog.f:600
subroutine mntr_mod_reg(mid, pmid, mname, mdscr)
Register new module.
Definition: mntrlog.f:346
subroutine mntr_get_step_delay(dstep)
Get step delay.
Definition: mntrlog.f:277
subroutine mntr_log_local(mid, priority, logs, prid)
Write log message from given process.
Definition: mntrlog.f:655
subroutine mntr_tmr_reg(mid, pmid, modid, mname, mdscr, ifsum)
Register new timer.
Definition: mntrtmr.f:16
subroutine mntr_check_abort(mid, ierr, logs)
Abort simulation.
Definition: mntrlog.f:856
subroutine rprm_rp_is_name_reg(rpid, mid, pname, ptype)
Check if parameter name is registered and return its id. Check flags as well.
Definition: rprm.f:658
subroutine rprm_rp_get(ipval, rpval, lpval, cpval, rpid, ptype)
Get runtime parameter form active section. This operation is performed locally.
Definition: rprm.f:883
subroutine rprm_sec_is_name_reg(rpid, mid, pname)
Check if section name is registered and return its id. Check mid as well.
Definition: rprm.f:284
subroutine rprm_rp_reg(rpid, mid, pname, pdscr, ptype, ipval, rpval, lpval, cpval)
Register new runtime parameter.
Definition: rprm.f:484
subroutine rprm_sec_set_act(ifact, rpid)
Set section's activation flag. Master value is broadcasted.
Definition: rprm.f:422
subroutine rprm_sec_reg(rpid, mid, pname, pdscr)
Register new parameter section.
Definition: rprm.f:165
subroutine col3(a, b, c, n)
Definition: math.f:598
subroutine icopy(a, b, n)
Definition: math.f:289
subroutine col2(a, b, n)
Definition: math.f:564
subroutine copy(a, b, n)
Definition: math.f:260
subroutine blank(A, N)
Definition: math.f:19
subroutine izero(a, n)
Definition: math.f:215
subroutine subcol3(a, b, c, n)
Definition: math.f:186
subroutine cmult(a, const, n)
Definition: math.f:315
subroutine cfill(a, b, n)
Definition: math.f:244
subroutine rzero(a, n)
Definition: math.f:208