source: CIVL/examples/fortran/nek5000/core/pertsupport.f

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100755
File size: 15.8 KB
Line 
1c Various support routines for perturbation related calculuations.
2c------------------------------------------------------------------------
3 subroutine flushBuffer(k)
4 integer k
5
6c 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
11c------------------------------------------------------------------------
12
13 function opnormOld(v1,v2,v3,weight)
14 include 'SIZE'
15 include 'INPUT'
16c
17 real v1(1),v2(1),v3(1),weight(1)
18 real normsq1,normsq2,normsq3,opnormOld,opnorm
19c
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
33c-----------------------------------------------------------------------
34
35 function opnorm2(v1,v2,v3)
36 include 'SIZE'
37 include 'TOTAL'
38c
39 real v1(1) , v2(1), v3(1)
40 real normsq1,normsq2,normsq3,opnorm
41c
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
55c-----------------------------------------------------------------------
56
57 function Tnorm(temp)
58 include 'SIZE'
59 include 'TOTAL'
60
61 real temp(*)
62c
63 ntotv = lx1*ly1*lz1*nelv
64 Tnorm = sqrt( glsc3(temp,BM1,temp,ntotv) /voltm1)
65c
66 return
67 end
68c--------------------------------------------
69 function dmnorm(v1,v2,v3,temp)
70c 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
98c---------------------------------------------------------------
99 subroutine opscale(v1,v2,v3,temp,alpha)
100c 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
118c---------------------------------------------------------------
119 subroutine opscaleV(v1,v2,v3,alpha)
120c 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)
132c
133 return
134 end
135
136c-----------------------------------------------------------------------
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
148c-----------------------------------------------------------------------
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
175c
176c For a fresh simulation, then we wait 5 vertical diffusion
177c times before we start measuring, so in this case just rescale
178c
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)
197c
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
233c-----------------------------------------------------------------------
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
265c-----------------------------------------------------------------------
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
276c----------------------------------------------------------------------
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
352c
353 ifdebug=.false.
354
355c 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
3885757 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,' reporting! timestart.gt.time! time=',time
413 call exitt
414 endif
415 endif
416
417 return
418 end
419c------------------------------------------------------------------------
420
421 subroutine get_useric
422c
423 include 'SIZE'
424 include 'TOTAL'
425 include 'NEKUSE'
426c
427 integer e,eg
428c
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
437c 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
449c
450 return
451 end
452c-----------------------------------------------------------------------
453 subroutine out_pert ! dump perturbation .fld files
454c
455 include 'SIZE'
456 include 'TOTAL'
457 include 'NEKUSE'
458c
459 character*3 s3
460c
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
468c
469 return
470 end
471c-----------------------------------------------------------------------
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
515c-----------------------------------------------------------------------
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
537c-----------------------------------------------------------------------
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
548c-----------------------------------------------------------------------
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
563c-----------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.