KTH framework for Nek5000 toolboxes; testing version  0.0.1
pertsupport.f
Go to the documentation of this file.
1 c Various support routines for perturbation related calculuations.
2 c------------------------------------------------------------------------
3  subroutine flushbuffer(k)
4  integer k
5 
6 c call flush(k) ! this works most places (including the pgi compiler)
7  call flush_(k) ! this works on nersc seaborg
8 
9  return
10  end
11 c------------------------------------------------------------------------
12 
13  function opnormold(v1,v2,v3,weight)
14  include 'SIZE'
15  include 'INPUT'
16 c
17  real v1(1),v2(1),v3(1),weight(1)
18  real normsq1,normsq2,normsq3,opnormold,opnorm
19 c
20  ntotv=lx1*ly1*lz1*nelv
21  normsq1=glsc3(v1,weight,v1,ntotv)
22  normsq2=glsc3(v2,weight,v2,ntotv)
23  if(if3d) then
24  normsq3=glsc3(v3,weight,v3,ntotv)
25  else
26  normsq3=0
27  endif
28 
29  opnorm=normsq1+normsq2+normsq3
30  if (opnorm.gt.0) opnormold=sqrt(opnorm)
31  return
32  end
33 c-----------------------------------------------------------------------
34 
35  function opnorm2(v1,v2,v3)
36  include 'SIZE'
37  include 'TOTAL'
38 c
39  real v1(1) , v2(1), v3(1)
40  real normsq1,normsq2,normsq3,opnorm
41 c
42  ntotv=lx1*ly1*lz1*nelv
43  normsq1=glsc3(v1,bm1,v1,ntotv)
44  normsq2=glsc3(v2,bm1,v2,ntotv)
45  if(if3d) then
46  normsq3=glsc3(v3,bm1,v3,ntotv)
47  else
48  normsq3=0
49  endif
50 
51  opnorm2=normsq1+normsq2+normsq3
52  if (opnorm2.gt.0) opnorm2=sqrt(opnorm2/volvm1)
53  return
54  end
55 c-----------------------------------------------------------------------
56 
57  function tnorm(temp)
58  include 'SIZE'
59  include 'TOTAL'
60 
61  real temp(*)
62 c
63  ntotv = lx1*ly1*lz1*nelv
64  tnorm = sqrt( glsc3(temp,bm1,temp,ntotv) /voltm1)
65 c
66  return
67  end
68 c--------------------------------------------
69  function dmnorm(v1,v2,v3,temp)
70 c Norm weighted by mass matrix
71  include 'SIZE'
72  include 'TOTAL'
73 
74  real v1(1),v2(1),v3(1),temp(1)
75  real normsq1,normsq2,normsq3,normsqt,dmnorm
76  common/normset/pran, ray, rayc
77 
78  ntotv=lx1*ly1*lz1*nelv
79  normsq1=(rayc)*glsc3(v1,bm1,v1,ntotv)
80  normsq2=(rayc)*glsc3(v2,bm1,v2,ntotv)
81  if(if3d) then
82  normsq3=(rayc)*glsc3(v3,bm1,v3,ntotv)
83  else
84  normsq3=0
85  endif
86 
87  if(ifheat) then
88  normsqt = (pran*ray*ray)*glsc3(temp,bm1,temp,ntotv)
89  else
90  normsqt = 0
91  endif
92 
93  dmnorm=sqrt((normsq1+normsq2+normsq3+normsqt)/volvm1)
94 
95  return
96  end
97 
98 c---------------------------------------------------------------
99  subroutine opscale(v1,v2,v3,temp,alpha)
100 c v = alpha*v
101  include 'SIZE'
102  include 'INPUT'
103 
104  real alpha
105  real v1(1),v2(1),v3(1),temp(1)
106 
107  ltotv=lx1*ly1*lz1*lelv
108  ltott=lx1*ly1*lz1*lelt
109 
110  call cmult(v1,alpha,ltotv)
111  call cmult(v2,alpha,ltotv)
112  if (if3d) call cmult(v3,alpha,ltotv)
113  if (ifheat) call cmult(temp,alpha,ltott*ldimt)
114 
115  return
116  end
117 
118 c---------------------------------------------------------------
119  subroutine opscalev(v1,v2,v3,alpha)
120 c v = alpha*v
121  include 'SIZE'
122  include 'INPUT'
123  real alpha
124  real v1(*),v2(*),v3(*)
125 
126  ntotv=lx1*ly1*lz1*nelv
127 
128  call cmult(v1,alpha,ntotv)
129  call cmult(v2,alpha,ntotv)
130 
131  if (if3d) call cmult(v3,alpha,ntotv)
132 c
133  return
134  end
135 
136 c-----------------------------------------------------------------------
137  subroutine computelyap
138  include 'SIZE'
139  include 'TOTAL'
140 
141  do jpp=1,npert ! Loop through each Lyapunov eigenvalue
142  call computelyap1
143  $ (vxp(1,jpp),vyp(1,jpp),vzp(1,jpp),tp(1,1,jpp),jpp)
144  enddo
145 
146  return
147  end
148 c-----------------------------------------------------------------------
149 
150  subroutine computelyap1(vxq,vyq,vzq,tq,jpp)
151  include 'SIZE'
152  include 'TOTAL'
153 
154  real vxq(1),vyq(1),vzq(1),tq(1)
155  real lyapsum,twt
156  common /pertsave/ timestart,tinitial
157 
158  integer icount
159  save icount
160  data icount /0/
161 
162  logical if_restart,if_ortho_lyap
163  common/restar/if_restart,if_ortho_lyap
164 
165  character*132 lyprestart
166  common/restflename/lyprestart !file for restart data
167 
168  twt = param(126) !time to wait to start computing exponents
169 
170  if (nio.eq.0)
171  $ write(6,8) istep,icount,time,twt,(lyap(k,jpp),k=1,3),jpp
172  8 format(i9,i4,2f8.4,1p3e12.4,i3,'clyap')
173 
174  if(time.lt.twt) then
175 c
176 c For a fresh simulation, then we wait 5 vertical diffusion
177 c times before we start measuring, so in this case just rescale
178 c
179  pertnorm = dmnorm(vxq,vyq,vzq,tq)
180  pertinvnorm = 1.0/pertnorm
181  call rescalepert(pertnorm,pertinvnorm,jpp)
182  lyap(3,jpp) = pertnorm !store latest norm
183  timestart = time
184  tinitial = time
185  icount = 0
186  return
187  else
188  if (jpp.eq.1) icount = icount + 1
189  endif
190 
191  irescale = param(128)
192  if (icount.eq.irescale) then
193 
194  lyapsum = lyap(2,jpp)
195  oldpertnorm = lyap(3,jpp)
196  pertnorm=dmnorm(vxq,vyq,vzq,tq)
197 c
198  lyap(1,jpp) = log(pertnorm/oldpertnorm)/(time-timestart)
199  lyapsum = lyapsum + log(pertnorm/oldpertnorm)
200  lyap(2,jpp) = lyapsum
201 
202  if(nid.eq.0) then ! write out results to the .lyp file
203 
204  write(6 ,1) istep,time,lyap(1,jpp),lyapsum,pertnorm,jpp
205  write(79,2) time,lyap(1,jpp),lyapsum,pertporm,oldpertnorm,jpp
206  1 format(i9,1p4e17.8,i4,'lyap')
207  2 format(1p5e17.8,i4,'lyap')
208  call flushbuffer(79)
209 
210  if (jpp.eq.1) open(unit=96,file=lyprestart)
211  write(96,9) lyapsum,timestart,timeinit,jpp
212  9 format(1p3e19.11,i9)
213  if (jpp.eq.npert) close(96)
214  endif
215 
216  pertinvnorm = 1.0/pertnorm
217  call rescalepert(pertnorm,pertinvnorm,jpp)
218  lyap(3,jpp) = pertnorm !save current pertnorm as old pertnorm
219 
220  if (jpp.eq.npert) then
221  icount = 0
222  timestart = time
223  endif
224 
225  if_ortho_lyap = .false.
226  if (param(125).gt.0) if_ortho_lyap = .true.
227  if (jpp.eq.npert .and. if_ortho_lyap) call pert_ortho_norm
228 
229  endif
230 
231  return
232  end
233 c-----------------------------------------------------------------------
234 
235  subroutine rescalepert(pertnorm,pertinvnorm,jpp)
236  include 'SIZE'
237  include 'TOTAL'
238 
239  ntotp = lx2*ly2*lz2*nelv
240 
241  call opscale !normalize vectors to unit norm
242  $ (vxp(1,jpp),vyp(1,jpp),vzp(1,jpp),tp(1,1,jpp),pertinvnorm)
243  call cmult(prp(1,jpp),pertinvnorm,ntotp)
244 
245  call opscale(exx1p(1,jpp),exy1p(1,jpp),exz1p(1,jpp)
246  $ ,vgradt1p(1,1,jpp),pertinvnorm)
247  call opscale(exx2p(1,jpp),exy2p(1,jpp),exz2p(1,jpp)
248  $ ,vgradt2p(1,1,jpp),pertinvnorm)
249 
250  ltotv = lx1*ly1*lz1*lelv
251  ltotp = lx2*ly2*lz2*lelv
252 
253  call cmult( tlagp(1,1,1,jpp),pertinvnorm,ltotv*(lorder-1)*ldimt)
254  call cmult(vxlagp(1,1,jpp),pertinvnorm,ltotv*(lorder-1))
255  call cmult(vylagp(1,1,jpp),pertinvnorm,ltotv*(lorder-1))
256  call cmult(vzlagp(1,1,jpp),pertinvnorm,ltotv*(lorder-1))
257  call cmult(prlagp(1,1,jpp),pertinvnorm,ltotp*(lorder-2))
258 
259  if (nio.eq.0) write(6,1) istep,pertnorm,pertinvnorm,jpp,'PNORM'
260  1 format(i4,1p2e12.4,i4,a5)
261  pertnorm = pertnorm*pertinvnorm
262 
263  return
264  end
265 c-----------------------------------------------------------------------
266  subroutine initialize
267  include 'SIZE'
268  include 'TOTAL'
269 
270  do jpp = 1,npert
271  call initialize1(jpp)
272  enddo
273 
274  return
275  end
276 c----------------------------------------------------------------------
277  subroutine initialize1(jpp)
278  include 'SIZE'
279  include 'TOTAL'
280 
281  real tmp(4),lyapSum,timeStart
282  common/pertsave/timestart,tinitial
283  common/normset/pran,ray,rayc
284  character*1 lyp(4),sch(5)
285  character*4 lyp4
286  character*5 sch5
287  character*7 lypres,lypold
288  CHARACTER*1 SESS1(132),PATH1(132),NAM1(132)
289  equivalence(session,sess1)
290  equivalence(path,path1)
291  equivalence(name,nam1)
292  equivalence(lyp,lyp4)
293  equivalence(sch,sch5)
294  data lyp4 /'.lyp'/
295  data sch5 /'.schp'/
296  data lypold /'.lypold'/
297  data lypres /'.lypsum'/
298  character*132 lypfile,lypfileold,lyprestart,lypsch
299  common/restflename/lyprestart !file where restart data is written
300  logical if_restart
301  common/restar/if_restart
302  logical ifdebug
303  common/debug/ ifdebug
304 
305  ntotv = lx1*ly1*lz1*nelv
306  ntotp = lx2*ly2*lz2*nelv
307  nconv_max = nbdinp
308  nconv = nconv_max
309  nconv = 1
310  nprex = 0
311  nprex_max = max(0,nbdinp-2)
312 
313  nr = lx1-1
314  ns = ly1-1
315  nt = lz1-1
316 
317  if(param(31).eq.0) return !param(31) is number of exponents
318 
319  tinitial = time
320 
321  call opzero(bfxp(1,jpp),bfyp(1,jpp),bfzp(1,jpp))
322 
323  itmp = lx1*ly1*lz1*lelv*(lorder-1)
324 
325  call rzero(vxlagp(1,1,jpp),itmp)
326  call rzero(vylagp(1,1,jpp),itmp)
327  if(if3d) call rzero(vzlagp(1,1,jpp),itmp)
328  if(ifheat) call rzero(tlagp(1,1,1,jpp),itmp*ldimt)
329 
330  call opzero(exx1p(1,jpp),exy1p(1,jpp),exz1p(1,jpp))
331  call opzero(exx2p(1,jpp),exy2p(1,jpp),exz2p(1,jpp))
332 
333  pertvnorm = sqrt(rayc)*opnorm2(vxp(1,jpp),vyp(1,jpp),vzp(1,jpp))
334  perttnorm = sqrt(pran*ray*ray)*tnorm(tp(1,1,jpp))
335  pertnorm = sqrt(pertvnorm**2+perttnorm**2)
336 
337  if(param(64).ne.1) then !fresh start, param(64) is restart flag
338  call opzero(vxp(1,jpp),vyp(1,jpp),vzp(1,jpp))
339  call rzero(tp(1,1,jpp),ntotv)
340  call get_useric
341  if_restart = .false.
342  call rzero(lyap(1,jpp),3)
343  else
344  if(nio.eq.0) write(6,*)jpp,'norm of pert IC=',pertnorm
345  if_restart = .true.
346  pertinvnorm = 1.0/pertnorm
347  call rescalepert(pertnorm,pertinvnorm,jpp)
348  if(nio.eq.0) write(6,*) jpp,'Rescaled the perturbation'
349  call rzero(lyap(1,jpp),3)
350  lyap(3,jpp) = pertnorm
351  endif
352 c
353  ifdebug=.false.
354 
355 c opening the lyp file in unit=79
356 
357  call blank(lypfile,132)
358  call blank(lypfileold,132)
359  call blank(lyprestart,132)
360  call blank(lypsch,132)
361 
362  ls = ltrunc(session,132)
363  lpp = ltrunc(path,132)
364 
365  call chcopy(nam1( 1),path1,lpp)
366  call chcopy(nam1(lpp+1),sess1,ls )
367  l1 = lpp+ls+1
368  ln = lpp+ls+4
369 
370  call chcopy(nam1(l1),lyp , 4)
371  call chcopy(lypfile ,nam1,ln)
372 
373  lns = lpp+ls+5
374  call chcopy(nam1(l1),sch , 5)
375  call chcopy(lypsch ,nam1,lns)
376 
377  ln2 = lpp+ls+7
378  call chcopy(nam1(l1),lypold , 7)
379  call chcopy(lypfileold ,nam1,ln2)
380 
381  call chcopy(nam1(l1),lypres , 7)
382  call chcopy(lyprestart ,nam1,ln2)
383 
384  if(nid.eq.0.and.jpp.eq.1) then
385  write(6,*) 'opening file ',lypfile
386  open(unit=79,file=lypfile,status='UNKNOWN')
387  write(79,5757) ! put a header on the lyp file
388 5757 format(1x,"time",5x,"lyap",5x,"lyapsum",5x,"pertnorm",
389  & 5x,"oldpertnorm")
390 
391  write(6,*) 'opening file ',lypsch
392  open(unit=146,file=lypsch)
393  endif
394 
395  if(if_restart) then
396  if(nid.eq.0) then
397  if (jpp.eq.1) then
398  print*,'opening file ',lypfileold
399  open(unit=86,file=lypfileold,status='OLD')
400  endif
401  read(86,*) tmp(1) !lyapsum
402  read(86,*) tmp(2) !timeStart
403  if (jpp.eq.npert) close(86)
404  endif
405  len = 4*wdsize
406  call bcast(tmp,len) !broadcast to all cpus
407  lyapsum = tmp(1)
408  timestart = tmp(2)
409  lyap(2,jpp) = lyapsum
410  print*,'nid,lyapsum,timestart=',nid,lyapsum,timestart,jpp
411  if(timestart.gt.time) then
412  write(6,*) nid,.gt.' reporting! timestarttime! time=',time
413  call exitt
414  endif
415  endif
416 
417  return
418  end
419 c------------------------------------------------------------------------
420 
421  subroutine get_useric
422 c
423  include 'SIZE'
424  include 'TOTAL'
425  include 'NEKUSE'
426 c
427  integer e,eg
428 c
429  do jp=1,npert
430  l = 0
431  do iel=1,nelv
432  ielg = lglel(iel) ! Global element number
433  do k=1,lz1
434  do j=1,ly1
435  do i=1,lx1
436  l = l+1
437 c call set_nekuse (l)
438  call nekasgnp (i,j,k,iel,l)
439  call useric (i,j,k,ielg)
440  vxp(l,jp) = ux
441  vyp(l,jp) = uy
442  vzp(l,jp) = uz
443  tp(l,1,jp) = temp
444  enddo
445  enddo
446  enddo
447  enddo
448  enddo
449 c
450  return
451  end
452 c-----------------------------------------------------------------------
453  subroutine out_pert ! dump perturbation .fld files
454 c
455  include 'SIZE'
456  include 'TOTAL'
457  include 'NEKUSE'
458 c
459  character*3 s3
460 c
461  do jpp=1,npert
462  write(s3,3) jpp
463  3 format('p',i2.2)
464  call outpost2
465  $ (vxp(1,jpp),vyp(1,jpp),vzp(1,jpp),prp(1,jpp),tp(1,1,jpp),
466  $ 1,s3)
467  enddo
468 c
469  return
470  end
471 c-----------------------------------------------------------------------
472  subroutine pert_add2s2(i,j,scale) ! xi = xi + scale * xj
473  include 'SIZE'
474  include 'TOTAL'
475 
476  ntotp = lx2*ly2*lz2*nelv
477  ntotv = lx1*ly1*lz1*nelv
478  ntott = lx1*ly1*lz1*nelt
479 
480  call add2s2(vxp(1,i),vxp(1,j),scale,ntotv)
481  call add2s2(vyp(1,i),vyp(1,j),scale,ntotv)
482  if (if3d) call add2s2(vzp(1,i),vzp(1,j),scale,ntotv)
483  call add2s2(prp(1,i),prp(1,j),scale,ntotp)
484 
485  do l=1,lorder-1
486  call add2s2(vxlagp(1,l,i),vxlagp(1,l,j),scale,ntotv)
487  call add2s2(vylagp(1,l,i),vylagp(1,l,j),scale,ntotv)
488  if (if3d) call add2s2(vzlagp(1,l,i),vzlagp(1,l,j),scale,ntotv)
489  call add2s2(prlagp(1,l,i),prlagp(1,l,j),scale,ntotp)
490  enddo
491 
492  call add2s2(exx1p(1,i),exx1p(1,j),scale,ntotv)
493  call add2s2(exy1p(1,i),exy1p(1,j),scale,ntotv)
494  if (if3d) call add2s2(exz1p(1,i),exz1p(1,j),scale,ntotv)
495 
496  call add2s2(exx2p(1,i),exx2p(1,j),scale,ntotv)
497  call add2s2(exy2p(1,i),exy2p(1,j),scale,ntotv)
498  if (if3d) call add2s2(exz2p(1,i),exz2p(1,j),scale,ntotv)
499 
500  if (ifheat) then
501  do k=0,npscal
502  k1=k+1
503  ntotk = lx1*ly1*lz1*nelfld(k+2)
504  call add2s2(tp(1,k1,i),tp(1,k1,j),scale,ntotk)
505  do l=1,lorder-1
506  call add2s2(tlagp(1,l,k1,i),tlagp(1,l,k1,j),scale,ntotk)
507  enddo
508  call add2s2(vgradt1p(1,k1,i),vgradt1p(1,k1,j),scale,ntotk)
509  call add2s2(vgradt2p(1,k1,i),vgradt2p(1,k1,j),scale,ntotk)
510  enddo
511  endif
512 
513  return
514  end
515 c-----------------------------------------------------------------------
516  function pert_inner_prod(i,j) ! weighted inner product vi^T vj
517  include 'SIZE'
518  include 'TOTAL'
519 
520  common/normset/pran, ray, rayc
521 
522  ntotv=lx1*ly1*lz1*nelv
523  ntott=lx1*ly1*lz1*nelt
524 
525  s1 = rayc*glsc3(vxp(1,i),bm1,vxp(1,j),ntotv)
526  s2 = rayc*glsc3(vyp(1,i),bm1,vyp(1,j),ntotv)
527  s3 = 0
528  if (if3d) s3 = rayc*glsc3(vzp(1,i),bm1,vzp(1,j),ntotv)
529 
530  t1 = 0
531  if (ifheat) t1=pran*ray*ray*glsc3(tp(1,1,i),bm1,tp(1,1,j),ntott)
532 
533  pert_inner_prod = (s1+s2+s3+t1)/volvm1
534 
535  return
536  end
537 c-----------------------------------------------------------------------
538  subroutine pert_ortho_norm ! orthogonalize and rescale pert. arrays
539  include 'SIZE'
540  include 'TOTAL'
541 
542  do k=1,npert
543  call pert_ortho_norm1(k)
544  enddo
545 
546  return
547  end
548 c-----------------------------------------------------------------------
549  subroutine pert_ortho_norm1 (k) ! orthogonalize k against 1...k-1
550  include 'SIZE'
551  include 'TOTAL'
552 
553  do j=1,k-1
554  scale = -pert_inner_prod(j,k)
555  call pert_add2s2(k,j,scale) ! xi = xi + scale * xj
556  enddo
557  scale = pert_inner_prod(k,k)
558  if (scale.gt.0) scale = 1./scale
559  call rescalepert(pertnorm,scale,k)
560 
561  return
562  end
563 c-----------------------------------------------------------------------
void exitt()
Definition: comm_mpi.f:604
subroutine bcast(buf, len)
Definition: comm_mpi.f:431
subroutine scale(xyzl, nl)
Definition: connect2.f:602
subroutine opzero(ux, uy, uz)
Definition: induct.f:406
subroutine opnorm(unorm, ux, uy, uz, type3)
Definition: induct.f:419
function glsc3(a, b, mult, n)
Definition: math.f:776
subroutine add2s2(a, b, c1, n)
Definition: math.f:690
subroutine blank(A, N)
Definition: math.f:19
function ltrunc(string, l)
Definition: math.f:494
subroutine cmult(a, const, n)
Definition: math.f:315
subroutine chcopy(a, b, n)
Definition: math.f:281
subroutine rzero(a, n)
Definition: math.f:208
function opnorm2(v1, v2, v3)
Definition: pertsupport.f:36
subroutine pert_ortho_norm1(k)
Definition: pertsupport.f:550
function tnorm(temp)
Definition: pertsupport.f:58
real function opnormold(v1, v2, v3, weight)
Definition: pertsupport.f:14
subroutine computelyap1(vxq, vyq, vzq, tq, jpp)
Definition: pertsupport.f:151
subroutine initialize
Definition: pertsupport.f:267
real function dmnorm(v1, v2, v3, temp)
Definition: pertsupport.f:70
subroutine opscalev(v1, v2, v3, alpha)
Definition: pertsupport.f:120
subroutine flushbuffer(k)
Definition: pertsupport.f:4
subroutine computelyap
Definition: pertsupport.f:138
subroutine rescalepert(pertnorm, pertinvnorm, jpp)
Definition: pertsupport.f:236
subroutine out_pert
Definition: pertsupport.f:454
function pert_inner_prod(i, j)
Definition: pertsupport.f:517
subroutine pert_add2s2(i, j, scale)
Definition: pertsupport.f:473
subroutine get_useric
Definition: pertsupport.f:422
subroutine initialize1(jpp)
Definition: pertsupport.f:278
subroutine opscale(v1, v2, v3, temp, alpha)
Definition: pertsupport.f:100
subroutine pert_ortho_norm
Definition: pertsupport.f:539
subroutine outpost2(v1, v2, v3, vp, vt, nfldt, name3)
Definition: prepost.f:1394