Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
prepost.F90
Go to the documentation of this file.
1 !-----------------------------------------------------------------------
5 subroutine prepost(ifdoin,prefin)
6  use kinds, only : dp
7  use size_m, only : lx1, ly1, lz1, lelv, nid
8  use ctimer, only : nprep, dnekclock, tprep, icalld
9  use input, only : schfle, ifschclob, ifpsco
10  use tstep, only : iostep, timeio, istep, nsteps, lastep, time, ntdump
11  implicit none
12 
13  logical :: ifdoin
14  character(3) :: prefin
15 
16  real(DP) :: tdmp(4)
17  real(DP) :: etime
18 
19  character(3) :: prefix
20 
21  logical, save :: ifdoit = .FALSE.
22 
23  real(DP), allocatable :: pm1(:,:,:,:)
24 
25  logical :: ifhis
26 
27  integer, save :: maxstep = 999999999
28  integer :: ierr, iiidmp, idummy
29  real(DP) :: timdump
30 
31  if (iostep < 0 .OR. timeio < 0) return
32 
33  nprep=nprep + 1
34 
35 #ifndef NOTIMER
36  etime=dnekclock()
37 #endif
38 
39 ! Trigger history output only if prefix = 'his' pff 8/18/05
40  ifhis = .false.
41  prefix = prefin
42  if (prefin == 'his') ifhis = .true.
43  if (prefix == 'his') prefix = ' '
44 
45  if(icalld == 1) then
46  ierr = 0
47  if (nid == 0) then
48  write(6,*) 'schfile:',schfle
49  if (ifschclob) then
50  open(unit=26,file=schfle,err=44,form='formatted')
51  else
52  open(unit=26,file=schfle,err=44,form='formatted', &
53  status='new')
54  endif
55  goto 45
56  44 ierr = 1
57  endif
58  45 continue
59  call err_chk(ierr,'.sch file already exists. Use IFSCHCLOB=F to &
60  & disable this check BUT BEWARE!!!!!!$')
61  endif
62 
63  allocate(pm1(lx1,ly1,lz1,lelv))
64  call prepost_map(0, pm1) ! map pr and axisymm. arrays
65 
66  if(istep >= nsteps) lastep=1
67 
68  timdump=0
69  if(timeio /= 0.0)then
70  if(time >= (ntdump + 1) * timeio) then
71  timdump=1.
72  ntdump=ntdump+1
73  endif
74  endif
75 
76  if (istep > 0 .AND. iostep > 0) then
77  if(mod(istep,iostep) == 0) ifdoit= .true.
78  endif
79 
80 
81 ! check for io request in file 'ioinfo'
82  iiidmp=0
83  if (nid == 0 .AND. (mod(istep,10) == 0 .OR. istep < 200)) then
84  open(unit=87,file='ioinfo',status='old',err=88)
85  read(87,*,end=87,err=87) idummy
86  if (iiidmp == 0) iiidmp=idummy
87  if (idummy /= 0) then ! overwrite last i/o request
88  rewind(87)
89  write(87,86)
90  86 format(' 0')
91  endif
92  87 continue
93  close(unit=87)
94  88 continue
95  if (iiidmp /= 0) write(6,*) 'Output:',iiidmp
96  endif
97 
98  tdmp(1)=iiidmp
99  call gop(tdmp,tdmp(3),'+ ',1)
100  iiidmp= int(tdmp(1))
101  if (iiidmp < 0) maxstep=abs(iiidmp)
102  if (istep >= maxstep .OR. iiidmp == -2) lastep=1
103  if (iiidmp == -2) return
104  if (iiidmp < 0) iiidmp = 0
105 
106  if (ifdoin) ifdoit= .true.
107  if (iiidmp /= 0 .OR. lastep == 1 .OR. timdump == 1.) ifdoit= .true.
108 
109 
110  if (ifdoit .AND. nid == 0)write(6,*)'call outfld: ifpsco:',ifpsco(1)
111  if (ifdoit) call outfld(prefix, pm1)
112 
113  call outhis(ifhis, pm1)
114 
115  call prepost_map(1, pm1) ! map back axisymm. arrays
116 
117  if (lastep == 1 .AND. nid == 0) close(unit=26)
118 
119 #ifndef NOTIMER
120  tprep=tprep+(dnekclock()-etime)
121 #endif
122 
123  ifdoit= .false.
124  return
125 
126 end subroutine prepost
127 
128 !-----------------------------------------------------------------------
130 subroutine prepost_map(isave, pm1) ! isave=0-->fwd, isave=1-->bkwd
131  use kinds, only : dp
132  use size_m, only : lx1, ly1, lz1, lelv, ly2, lz2
133  use size_m, only : nx1, ny1, nz1, nelv, nx2, ny2, nz2
134  use input, only : ifaxis, ifsplit
135  use ixyz, only : ixm21, iytm21, iztm21
136  use soln, only : pr
137  use tstep, only : if_full_pres
138  implicit none
139 
140  integer, intent(in) :: isave
141  real(DP), intent(out) :: pm1 (lx1,ly1,lz1,lelv)
142 
143 ! Work arrays and temporary arrays
144  real(DP) :: pa(lx1,ly2,lz2),pb(lx1,ly1,lz2)
145  integer :: e
146  integer :: ntot1, nyz2, nxy1, nxyz, nxyz2, iz
147 
148  if (isave == 0) then ! map to GLL grid
149 
150  if (ifaxis) then
151  write(*,*) "Oops: ifaxis"
152 #if 0
153  ntotm1 = nx1*ny1*nelt
154  call copy(yax,ym1,ntotm1)
155  do 5 e=1,nelt
156  if (ifrzer(e)) then
157  call mxm(ym1(1,1,1,e),nx1,iatjl1,ny1,pb,ny1)
158  call copy(ym1(1,1,1,e),pb,nx1*ny1)
159  endif
160  5 END DO
161  if (ifflow) then
162  ntotm1 = nx1*ny1*nelv
163  ntotm2 = nx2*ny2*nelv
164  call copy(vxax,vx,ntotm1)
165  call copy(vyax,vy,ntotm1)
166  call copy(prax,pr,ntotm2)
167  do 10 e=1,nelv
168  if (ifrzer(e)) then
169  call mxm(vx(1,1,1,e),nx1,iatjl1,ny1,pb,ny1)
170  call copy(vx(1,1,1,e),pb,nx1*ny1)
171  call mxm(vy(1,1,1,e),nx1,iatjl1,ny1,pb,ny1)
172  call copy(vy(1,1,1,e),pb,nx1*ny1)
173  call mxm(pr(1,1,1,e),nx2,iatjl2,ny2,pb,ny2)
174  call copy(pr(1,1,1,e),pb,nx2*ny2)
175  endif
176  10 END DO
177  endif
178  if (ifheat) then
179  ntotm1 = nx1*ny1*nelt
180  do 15 ifldt=1,npscal+1
181  call copy(tax(1,1,1,ifldt),t(1,1,1,1,ifldt),ntotm1)
182  15 END DO
183  do 30 e=1,nelt
184  if (ifrzer(e)) then
185  do 25 ifldt=1,npscal+1
186  call mxm(t(1,1,1,e,ifldt),nx1,iatjl1,ny1, &
187  pb,ny1)
188  call copy(t(1,1,1,e,ifldt),pb,nx1*ny1)
189  25 END DO
190  endif
191  30 END DO
192  endif
193 #endif
194  endif
195  ! Map the pressure onto the velocity mesh
196 
197  ntot1 = nx1*ny1*nz1*nelv
198  nyz2 = ny2*nz2
199  nxy1 = nx1*ny1
200  nxyz = nx1*ny1*nz1
201  nxyz2 = nx2*ny2*nz2
202 
203  if (ifsplit) then
204  call copy(pm1,pr,ntot1)
205  elseif (if_full_pres) then
206  pm1 = 0._dp
207  do e=1,nelv
208  call copy(pm1(1,1,1,e),pr(1,1,1,e),nxyz2)
209  enddo
210  else
211  do 1000 e=1,nelv
212  call mxm(ixm21,nx1,pr(1,1,1,e),nx2,pa(1,1,1),nyz2)
213  do 100 iz=1,nz2
214  call mxm(pa(1,1,iz),nx1,iytm21,ny2,pb(1,1,iz),ny1)
215  100 END DO
216  call mxm(pb(1,1,1),nxy1,iztm21,nz2,pm1(1,1,1,e),nz1)
217  1000 END DO
218  endif
219 
220  else ! map back
221  if (ifaxis) then
222  write(*,*) "Oops: ifaxis"
223 #if 0
224  ntot1 = nx1*ny1*nelt
225  call copy(ym1,yax,ntot1)
226  if (ifflow) then
227  ntot1 = nx1*ny1*nelv
228  ntot2 = nx2*ny2*nelv
229  call copy(vx,vxax,ntot1)
230  call copy(vy,vyax,ntot1)
231  call copy(pr,prax,ntot2)
232  endif
233  if (ifheat) then
234  ntot1 = nx1*ny1*nelt
235  do 3000 ifldt=1,npscal+1
236  call copy(t(1,1,1,1,ifldt),tax(1,1,1,ifldt),ntot1)
237  3000 END DO
238  endif
239 #endif
240  endif
241 
242  endif
243  return
244 end subroutine prepost_map
245 
246 !-----------------------------------------------------------------------
248 subroutine outfld(prefix, pm1)
249  use kinds, only : dp
250  use size_m, only : lx1, ly1, lz1, lelv, nid
251  use input, only : param
252  use tstep, only : istep, time
253  implicit none
254 
255 ! Work arrays and temporary arrays
256 
257  character(3), intent(in) :: prefix
258 
259  real(DP), intent(in) :: pm1 (lx1,ly1,lz1,lelv)
260 
261  real(DP) :: p66
262 
263  if(nid == 0) then
264  WRITE(6,1001) istep,time
265  1001 FORMAT(/,i9,1pe12.4,' Write checkpoint:')
266  endif
267  call nekgsync()
268 
269  p66 = abs(param(66))
270  if (p66 == 6) then
271  call mfo_outfld(prefix, pm1)
272  call nekgsync ! avoid race condition w/ outfld
273  return
274  endif
275 
276  write(*,*) "Oops: p66 /= 6"
277 #if 0
278  ifxyo_s = ifxyo ! Save ifxyo
279 
280  iprefix = i_find_prefix(prefix,99)
281 
282  ierr = 0
283  if (nid == 0) then
284 
285  ! Open new file for each dump on /cfs
286  nopen(iprefix)=nopen(iprefix)+1
287 
288  if (prefix == ' ' .AND. nopen(iprefix) == 1) ifxyo = .true. ! 1st file
289 
290  if (prefix == 'rst' .AND. max_rst > 0) &
291  nopen(iprefix) = mod1(nopen(iprefix),max_rst) ! restart
292 
293  call file2(nopen(iprefix),prefix)
294  if (p66 < 1.0) then
295  open(unit=24,file=fldfle,form='formatted',status='unknown')
296  else
297  fldfilei = 0
298  len = ltrunc(fldfle,131)
299  call chcopy(fldfile2,fldfle,len)
300  call byte_open(fldfile2,ierr)
301  ! write header as character string
302  call blank(fhdfle,132)
303  endif
304  endif
305  call bcast(ifxyo,lsize)
306  if(p66 >= 1.0) &
307  call err_chk(ierr,'Error opening file in outfld. Abort. $')
308 
309 ! Figure out what goes in EXCODE
310  CALL blank(excode,30)
311  ndumps=ndumps+1
312  i=1
313  if (mod(p66,1.0) == 0.0) then !old header format
314  IF(ifxyo) then
315  excode(1)='X'
316  excode(2)=' '
317  excode(3)='Y'
318  excode(4)=' '
319  i = 5
320  IF(if3d) THEN
321  excode(i) ='Z'
322  excode(i+1)=' '
323  i = i + 2
324  ENDIF
325  ENDIF
326  IF(ifvo) then
327  excode(i) ='U'
328  excode(i+1)=' '
329  i = i + 2
330  ENDIF
331  IF(ifpo) THEN
332  excode(i)='P'
333  excode(i+1)=' '
334  i = i + 2
335  ENDIF
336  IF(ifto) THEN
337  excode(i)='T '
338  excode(i+1)=' '
339  i = i + 1
340  ENDIF
341  do iip=1,ldimt1
342  if (ifpsco(iip)) then
343  write(excode(iip+i) ,'(i1)') iip
344  write(excode(iip+i+1),'(a1)') ' '
345  i = i + 1
346  endif
347  enddo
348  else
349  ! ew header format
350  IF (ifxyo) THEN
351  excode(i)='X'
352  i = i + 1
353  ENDIF
354  IF (ifvo) THEN
355  excode(i)='U'
356  i = i + 1
357  ENDIF
358  IF (ifpo) THEN
359  excode(i)='P'
360  i = i + 1
361  ENDIF
362  IF (ifto) THEN
363  excode(i)='T'
364  i = i + 1
365  ENDIF
366  IF (ldimt > 1) THEN
367  npscalo = 0
368  do k = 1,ldimt-1
369  if(ifpsco(k)) npscalo = npscalo + 1
370  enddo
371  IF (npscalo > 0) THEN
372  excode(i) = 'S'
373  WRITE(excode(i+1),'(I1)') npscalo/10
374  WRITE(excode(i+2),'(I1)') npscalo-(npscalo/10)*10
375  ENDIF
376  ENDIF
377  endif
378 
379 
380 ! Dump header
381  ierr = 0
382  if (nid == 0) call dump_header(excode,p66,ierr)
383  call err_chk(ierr,'Error dumping header in outfld. Abort. $')
384 
385  call get_id(id)
386 
387  nxyz = nx1*ny1*nz1
388 
389  ierr = 0
390  do ieg=1,nelgt
391 
392  jnid = gllnid(ieg)
393  ie = gllel(ieg)
394 
395  if (nid == 0) then
396  if (jnid == 0) then
397  call fill_tmp(tdump,id,ie)
398  else
399  mtype=2000+ieg
400  len=4*id*nxyz
401  dum1=0.
402  call csend(mtype,dum1,wdsize,jnid,nullpid)
403  call crecv(mtype,tdump,len)
404  endif
405  if(ierr == 0) call out_tmp(id,p66,ierr)
406  elseif (nid == jnid) then
407  call fill_tmp(tdump,id,ie)
408  dum1=0.
409 
410  mtype=2000+ieg
411  len=4*id*nxyz
412  call crecv(mtype,dum1,wdsize)
413  call csend(mtype,tdump,len,node0,nullpid)
414  endif
415  enddo
416  call err_chk(ierr,'Error writing file in outfld. Abort. $')
417 
418  ifxyo = ifxyo_s ! restore ifxyo
419 
420  if (nid == 0) call close_fld(p66,ierr)
421  call err_chk(ierr,'Error closing file in outfld. Abort. $')
422 #endif
423 
424  return
425 end subroutine outfld
426 
427 !-----------------------------------------------------------------------
429 subroutine outhis(ifhis, pm1)
430  use kinds, only : dp
431  use size_m, only : lx1, ly1, lz1, lelv
432  use size_m, only : nx1, ny1, nz1, nelv, nid
433  use geom, only : xm1, ym1, zm1
434  use input, only : param, nhis, hcode, lochis, if3d, qinteg
435  use parallel, only : gllnid, gllel, np, wdsize, node0, nullpid
436  use soln, only : jp, vx, vy, vz, t
437  use tstep, only : istep, dt, time
438  implicit none
439 
440  real(DP) :: pm1 (lx1,ly1,lz1,lelv)
441 
442  real(DP) :: hdump(25)
443  real(DP) :: xpart(10),ypart(10),zpart(10)
444  logical :: ifhis
445 
446  integer, save :: icalld = 0
447  integer :: iohis, nvar, ih, ii, ihisps, mtype, len, iobj, isk, iq
448  integer :: ipart, i, iel, k, j, ip, kp, ielp, ix, iy, iz, ieg, jnid, ie
449  real(DP) :: rmin, x, y, z, r, one
450  real(DP), external :: glmax
451 
452  iohis=1
453  if (param(52) >= 1) iohis = int(param(52))
454  if (mod(istep,iohis) == 0 .AND. ifhis) then
455  if (nhis > 0) then
456  ipart=0
457  DO 2100 i=1,nhis
458  IF(hcode(10,i) == 'P')then ! Do particle paths
459  if (ipart <= 10) ipart=ipart+1
460  if (istep == 0) then ! Particle has original coordinates
461  ! Restarts?
462  xpart(ipart)= &
463  xm1(lochis(1,i),lochis(2,i),lochis(3,i),lochis(4,i))
464  ypart(ipart)= &
465  ym1(lochis(1,i),lochis(2,i),lochis(3,i),lochis(4,i))
466  zpart(ipart)= &
467  zm1(lochis(1,i),lochis(2,i),lochis(3,i),lochis(4,i))
468  ELSE
469  ! Kludge: Find Closest point
470  rmin=1.0e7
471  ip = 1; jp = 1; kp = 1; ielp = 1
472  DO iel=1,nelv
473  DO k=1,nz1
474  DO j=1,ny1
475  DO ii=1,nx1
476  x = xm1(ii,j,k,iel)
477  y = ym1(ii,j,k,iel)
478  z = zm1(ii,j,k,iel)
479  r=sqrt( (x-xpart(ipart))**2 + (y-ypart(ipart))**2 &
480  + (z-zpart(ipart))**2 )
481  IF(r < rmin) then
482  rmin=r
483  ip=ii
484  jp=j
485  kp=k
486  ielp=iel
487  ENDIF
488  enddo
489  enddo
490  enddo
491  END DO
492  xpart(ipart) = xpart(ipart) + dt * vx(ip,jp,kp,ielp)
493  ypart(ipart) = ypart(ipart) + dt * vy(ip,jp,kp,ielp)
494  zpart(ipart) = zpart(ipart) + dt * vz(ip,jp,kp,ielp)
495  ENDIF
496  ! Dump particle data for history point first
497  ! Particle data is Time, x,y,z.
498  WRITE(26,'(4G14.6,A10)')time,xpart(ipart),ypart(ipart) &
499  ,zpart(ipart),' Particle'
500  ENDIF
501  ! Figure out which fields to dump
502  nvar=0
503  IF(hcode(10,i) == 'H')then
504  ! Do histories
505 
506 
507  ix =lochis(1,i)
508  iy =lochis(2,i)
509  iz =lochis(3,i)
510  ieg=lochis(4,i)
511  jnid=gllnid(ieg)
512  ie =gllel(ieg)
513 
514  !------------------------------------------------------------------------
515  ! On first call, write out XYZ location of history points
516 
517  if (icalld == 0) then
518  one = glmax((/one/),1) ! Force synch. pff 04/16/04
519  IF (nid == jnid) then
520  IF (np > 1 .AND. .NOT. if3d) &
521  WRITE(6,22) nid,i,ix,iy,ie,ieg &
522  ,xm1(ix,iy,iz,ie),ym1(ix,iy,iz,ie)
523  IF (np > 1 .AND. if3d) &
524  WRITE(6,23) nid,i,ix,iy,iz,ie,ieg,xm1(ix,iy,iz,ie) &
525  ,ym1(ix,iy,iz,ie),zm1(ix,iy,iz,ie)
526  IF (np == 1 .AND. .NOT. if3d) &
527  WRITE(6,32) i,ix,iy,ie,ieg &
528  ,xm1(ix,iy,iz,ie),ym1(ix,iy,iz,ie)
529  IF (np == 1 .AND. if3d) &
530  WRITE(6,33) i,ix,iy,iz,ie,ieg,xm1(ix,iy,iz,ie) &
531  ,ym1(ix,iy,iz,ie),zm1(ix,iy,iz,ie)
532  22 FORMAT(i6,' History point:',i3,' at (',2(i2,','), &
533  & 2(i4,','),'); X,Y,Z = (',g12.4,',',g12.4,',',g12.4,').')
534  23 FORMAT(i6,' History point:',i3,' at (',3(i2,','), &
535  & 2(i4,','),'); X,Y,Z = (',g12.4,',',g12.4,',',g12.4,').')
536  32 FORMAT(2x,' History point:',i3,' at (',2(i2,','), &
537  & 2(i4,','),'); X,Y,Z = (',g12.4,',',g12.4,',',g12.4,').')
538  33 FORMAT(2x,' History point:',i3,' at (',3(i2,','), &
539  & 2(i4,','),'); X,Y,Z = (',g12.4,',',g12.4,',',g12.4,').')
540  ENDIF
541  ENDIF
542  !------------------------------------------------------------------------
543 
544  IF(hcode(1,i) == 'U')then
545  nvar=nvar+1
546  hdump(nvar)=vx(ix,iy,iz,ie)
547  elseif(hcode(1,i) == 'X')then
548  nvar=nvar+1
549  hdump(nvar)=xm1(ix,iy,iz,ie)
550  ENDIF
551  IF(hcode(2,i) == 'V')then
552  nvar=nvar+1
553  hdump(nvar)=vy(ix,iy,iz,ie)
554  elseif(hcode(2,i) == 'Y')then
555  nvar=nvar+1
556  hdump(nvar)=ym1(ix,iy,iz,ie)
557  ENDIF
558  IF(hcode(3,i) == 'W')then
559  nvar=nvar+1
560  hdump(nvar)=vz(ix,iy,iz,ie)
561  elseif(hcode(3,i) == 'Z')then
562  nvar=nvar+1
563  hdump(nvar)=zm1(ix,iy,iz,ie)
564  ENDIF
565  IF(hcode(4,i) == 'P')then
566  nvar=nvar+1
567  hdump(nvar)=pm1(ix,iy,iz,ie)
568  ENDIF
569  IF(hcode(5,i) == 'T')then
570  nvar=nvar+1
571  hdump(nvar)=t(ix,iy,iz,ie,1)
572  ENDIF
573  IF(hcode(6,i) /= ' ' .AND. hcode(6,i) /= '0') then
574  READ(hcode(6,i),'(I1)',err=13)ihisps
575  13 CONTINUE
576  ! Passive scalar data here
577  nvar=nvar+1
578  hdump(nvar)=t(ix,iy,iz,ie,ihisps+1)
579  ENDIF
580 
581  !--------------------------------------------------------------
582  ! Dump out the NVAR values for this history point
583  !--------------------------------------------------------------
584  mtype=2200+i
585  len=wdsize*nvar
586 
587  ! If point on this processor, send data to node 0
588  IF (nvar > 0 .AND. nid /= 0 .AND. jnid == nid) &
589  call csend(mtype,hdump,len,node0,nullpid)
590 
591  ! If processor 0, recv data (unless point resides on node0).
592  IF (nvar > 0 .AND. nid == 0 .AND. jnid /= nid) &
593  call crecv(mtype,hdump,len)
594 
595  IF (nvar > 0 .AND. nid == 0) &
596  WRITE(26,'(1p6e16.8)')time,(hdump(ii),ii=1,nvar)
597 
598  !--------------------------------------------------------------
599  ! End of history points
600  !--------------------------------------------------------------
601  ENDIF
602  2100 END DO
603  ! Now do Integrated quantities (Drag, Lift, Flux, etc.)
604  ! Find out which groups are to be dumped
605 !max IF (IFINTQ) CALL INTGLQ
606  DO 2200 ih=1,nhis
607  IF(hcode(10,ih) == 'I') then
608  iobj=lochis(1,ih)
609  isk=0
610  DO 2205 iq=1,3
611  IF (hcode(iq,ih) /= ' ') isk=isk + 1
612  2205 END DO
613  DO 2207 iq=5,6
614  IF (hcode(iq,ih) /= ' ') isk=isk + 1
615  2207 END DO
616  IF (nid == 0) &
617  WRITE(26,'(1p6e16.8)')time,(qinteg(ii,iobj),ii=1,isk)
618  ENDIF
619  2200 END DO
620  ENDIF
621 
622  endif
623 
624  icalld = icalld+1
625 
626  return
627 end subroutine outhis
628 
629 !=======================================================================
630 subroutine copyx4(a,b,n)
631  use kinds, only : dp, r4
632  implicit none
633  integer, intent(in) :: n
634  REAL(r4), intent(out) :: A(n)
635  REAL(DP), intent(in) :: B(n)
636  integer :: i
637  DO 100 i = 1, n
638  a(i) = real(B(I), kind=r4)
639  100 END DO
640  return
641 end subroutine copyx4
642 
643 !=======================================================================
644 subroutine copy4r(a,b,n)
645  use kinds, only : dp, r4
646  implicit none
647  real(DP) :: a(*)
648  real(r4) :: b(*)
649  integer :: n, i
650  do i = 1, n
651  a(i) = b(i)
652  enddo
653  return
654 end subroutine copy4r
655 
656 !=======================================================================
657 integer function i_find_prefix(prefix,imax)
658  implicit none
659 
660  character(3) :: prefix
661  integer :: imax
662 
663  character(3), save :: prefixes(99)
664  data prefixes /99*'...'/
665  integer, save :: nprefix = 0
666  integer :: i
667 
668 ! Scan existing list of prefixes for a match to "prefix"
669  do i=1,nprefix
670  if (prefix == prefixes(i)) then
671  i_find_prefix = i
672  return
673  endif
674  enddo
675 
676 ! If we're here, we didn't find a match.. bump list and return
677 
678  nprefix = nprefix + 1
679  prefixes(nprefix) = prefix
680  i_find_prefix = nprefix
681 
682 ! Array bounds check on prefix list
683 
684  if (nprefix > 99 .OR. nprefix > imax) then
685  write(6,*) 'Hey! nprefix too big! ABORT in i_find_prefix' &
686  ,nprefix,imax
687  call exitt
688  endif
689 
690  return
691 end function i_find_prefix
692 
693 !-----------------------------------------------------------------------
695 subroutine mfo_outfld(prefix, pm1)
696  use kinds, only : dp, i8
697  use ctimer, only : dnekclock_sync
698  use size_m, only : lx1, ly1, lz1, lelv, ldimt, lxo
699  use size_m, only : nx1, ny1, nz1, nelt, nid, ndim
700  use restart, only : nxo, nyo, nzo, nrg, iheadersize, pid0, nelb, wdsizo
701  use restart, only : ifh_mbyte, nfileo
702  use geom, only : xm1, ym1, zm1
703  use input, only : ifxyo, ifxyo_, ifreguo, if3d, ifvo, ifpo, ifto, ifpsco
704  use parallel, only : isize, nelgt, lsize
705  use soln, only : vx, vy, vz, t
706  use tstep, only : istep, time
707  implicit none
708 
709  character(3), intent(in) :: prefix
710 
711  real(DP), intent(in) :: pm1 (lx1,ly1,lz1,lelv) ! mapped pressure
712 
713  integer(i8) :: offs0,offs,stride,strideB,nxyzo8
714  logical :: ifxyo_s
715 
716  real(DP) :: tiostart, dnbyte, tio
717  real(DP), external :: glsum
718  integer :: nout, ierr, ioflds, k
719 
720  tiostart=dnekclock_sync()
721 
722  ifxyo_s = ifxyo
723  ifxyo_ = ifxyo
724  nout = nelt
725  nxo = nx1
726  nyo = ny1
727  nzo = nz1
728  if (ifreguo) then ! dump on regular (uniform) mesh
729  if (nrg > lxo) then
730  if (nid == 0) write(6,*) &
731  'WARNING: nrg too large, reset to lxo!'
732  nrg = lxo
733  endif
734  nxo = nrg
735  nyo = nrg
736  nzo = 1
737  if(if3d) nzo = nrg
738  endif
739  offs0 = iheadersize + 4 + isize*nelgt
740 
741  ierr=0
742  if (nid == pid0) then
743  call mfo_open_files(prefix,ierr) ! open files on i/o nodes
744  endif
745  call err_chk(ierr,'Error opening file in mfo_open_files. $')
746  call bcast(ifxyo_,lsize)
747  ifxyo = ifxyo_
748  call mfo_write_hdr ! create element mapping +
749 
750 ! call exitti('this is wdsizo A:$',wdsizo)
751 ! write hdr
752  nxyzo8 = nxo*nyo*nzo
753  strideb = nelb * nxyzo8*wdsizo
754  stride = nelgt* nxyzo8*wdsizo
755 
756  ioflds = 0
757 ! dump all fields based on the t-mesh to avoid different
758 ! topologies in the post-processor
759  if (ifxyo) then
760  offs = offs0 + ndim*strideb
761  call byte_set_view(offs,ifh_mbyte)
762  if (ifreguo) then
763  write(*,*) "Oops: ifreguo"
764 #if 0
765  call map2reg(ur1,nrg,xm1,nout)
766  call map2reg(ur2,nrg,ym1,nout)
767  if (if3d) call map2reg(ur3,nrg,zm1,nout)
768  call mfo_outv(ur1,ur2,ur3,nout,nxo,nyo,nzo)
769 #endif
770  else
771  call mfo_outv(xm1,ym1,zm1,nout,nxo,nyo,nzo)
772  endif
773  ioflds = ioflds + ndim
774  endif
775  if (ifvo ) then
776  offs = offs0 + ioflds*stride + ndim*strideb
777  call byte_set_view(offs,ifh_mbyte)
778  if (ifreguo) then
779  write(*,*) "Oops: ifreguo"
780 #if 0
781  call map2reg(ur1,nrg,vx,nout)
782  call map2reg(ur2,nrg,vy,nout)
783  if (if3d) call map2reg(ur3,nrg,vz,nout)
784  call mfo_outv(ur1,ur2,ur3,nout,nxo,nyo,nzo)
785 #endif
786  else
787  call mfo_outv(vx,vy,vz,nout,nxo,nyo,nzo) ! B-field handled thru outpost
788  endif
789  ioflds = ioflds + ndim
790  endif
791  if (ifpo ) then
792  offs = offs0 + ioflds*stride + strideb
793  call byte_set_view(offs,ifh_mbyte)
794  if (ifreguo) then
795  write(*,*) "Oops: ifreguo"
796 #if 0
797  call map2reg(ur1,nrg,pm1,nout)
798  call mfo_outs(ur1,nout,nxo,nyo,nzo)
799 #endif
800  else
801  call mfo_outs(pm1,nout,nxo,nyo,nzo)
802  endif
803  ioflds = ioflds + 1
804  endif
805  if (ifto ) then
806  offs = offs0 + ioflds*stride + strideb
807  call byte_set_view(offs,ifh_mbyte)
808  if (ifreguo) then
809  write(*,*) "Oops: ifreguo"
810 #if 0
811  call map2reg(ur1,nrg,t,nout)
812  call mfo_outs(ur1,nout,nxo,nyo,nzo)
813 #endif
814  else
815  call mfo_outs(t,nout,nxo,nyo,nzo)
816  endif
817  ioflds = ioflds + 1
818  endif
819  do k=1,ldimt-1
820  if(ifpsco(k)) then
821  offs = offs0 + ioflds*stride + strideb
822  call byte_set_view(offs,ifh_mbyte)
823  if (ifreguo) then
824  write(*,*) "Oops: ifreguo"
825 #if 0
826  call map2reg(ur1,nrg,t(1,1,1,1,k+1),nout)
827  call mfo_outs(ur1,nout,nxo,nyo,nzo)
828 #endif
829  else
830  call mfo_outs(t(1,1,1,1,k+1),nout,nxo,nyo,nzo)
831  endif
832  ioflds = ioflds + 1
833  endif
834  enddo
835  dnbyte = 1.*ioflds*nout*wdsizo*nxo*nyo*nzo
836 
837  if (if3d) then
838  offs0 = offs0 + ioflds*stride
839  strideb = nelb *2*4 ! min/max single precision
840  stride = nelgt*2*4
841  ioflds = 0
842  ! add meta data to the end of the file
843  if (ifxyo) then
844  offs = offs0 + ndim*strideb
845  call byte_set_view(offs,ifh_mbyte)
846  call mfo_mdatav(xm1,ym1,zm1,nout)
847  ioflds = ioflds + ndim
848  endif
849  if (ifvo ) then
850  offs = offs0 + ioflds*stride + ndim*strideb
851  call byte_set_view(offs,ifh_mbyte)
852  call mfo_mdatav(vx,vy,vz,nout)
853  ioflds = ioflds + ndim
854  endif
855  if (ifpo ) then
856  offs = offs0 + ioflds*stride + strideb
857  call byte_set_view(offs,ifh_mbyte)
858  call mfo_mdatas(pm1,nout)
859  ioflds = ioflds + 1
860  endif
861  if (ifto ) then
862  offs = offs0 + ioflds*stride + strideb
863  call byte_set_view(offs,ifh_mbyte)
864  call mfo_mdatas(t,nout)
865  ioflds = ioflds + 1
866  endif
867  do k=1,ldimt-1
868  offs = offs0 + ioflds*stride + strideb
869  call byte_set_view(offs,ifh_mbyte)
870  if(ifpsco(k)) call mfo_mdatas(t(1,1,1,1,k+1),nout)
871  ioflds = ioflds + 1
872  enddo
873  dnbyte = dnbyte + 2.*ioflds*nout*wdsizo
874  endif
875 
876  ierr = 0
877  if (nid == pid0) then
878 #ifdef MPIIO
879  call byte_close_mpi(ifh_mbyte,ierr)
880 #else
881  call byte_close(ierr)
882 #endif
883  endif
884  call err_chk(ierr,'Error closing file in mfo_outfld. Abort. $')
885 
886  tio = dnekclock_sync()-tiostart
887  dnbyte = glsum(dnbyte,1)
888  dnbyte = dnbyte + iheadersize + 4. + isize*nelgt
889  dnbyte = dnbyte/1024/1024
890  if(nid == 0) write(6,7) istep,time,dnbyte,dnbyte/tio, &
891  nfileo
892  7 format(/,i9,1pe12.4,' done :: Write checkpoint',/, &
893  & 30x,'file size = ',3pg14.2,'MB',/, &
894  & 30x,'avg data-throughput = ',0pf14.1,'MB/s',/, &
895  & 30x,'io-nodes = ',i5,/)
896 
897  ifxyo = ifxyo_s ! restore old value
898 
899  return
900 end subroutine mfo_outfld
901 
902 !-----------------------------------------------------------------------
903 subroutine io_init ! determine which nodes will output
904  use kinds, only : dp
905  use size_m, only : nid, lxo, nelt
906  use input, only : param, ifreguo
907  use parallel, only : np, wdsize
908  use restart, only : ifdiro, nfileo, nproc_o
909  use restart, only : fid0, pid0, pid1, wdsizo, nrg, nelb, pid00
910  implicit none
911 
912  integer :: nn
913  integer, external :: igl_running_sum
914  real(DP), external :: glmin
915 
916  ifdiro = .false.
917 
918 #ifdef MPIIO
919 
920 #ifdef MPIIO_NOCOL
921  nfileo = abs(param(65))
922  if(nfileo == 0) nfileo = 1
923  if(np < nfileo) nfileo=np
924  nproc_o = np / nfileo ! # processors pointing to pid0
925  fid0 = nid/nproc_o ! file id
926  pid0 = nproc_o*fid0 ! my parent i/o node
927  pid1 = min(np-1,pid0+nproc_o-1) ! range of sending procs
928  fid0 = 0
929 #else
930  nfileo = np
931  nproc_o = 1
932  fid0 = 0
933  pid0 = nid
934  pid1 = 0
935 #endif
936 
937 #else
938  if(param(65) < 0) ifdiro = .true. ! p65 < 0 --> multi subdirectories
939  nfileo = int(abs(param(65)))
940  if(nfileo == 0) nfileo = 1
941  if(np < nfileo) nfileo=np
942  nproc_o = np / nfileo ! # processors pointing to pid0
943  fid0 = nid/nproc_o ! file id
944  pid0 = nproc_o*fid0 ! my parent i/o node
945  pid1 = min(np-1,pid0+nproc_o-1) ! range of sending procs
946 #endif
947 
948  call nek_comm_io(nfileo)
949 
950  wdsizo = 4 ! every proc needs this
951  if (param(63) > 0) wdsizo = 8 ! 64-bit .fld file
952  if (wdsizo > wdsize) then
953  if(nid == 0) write(6,*) 'ABORT: wdsizo > wdsize!'
954  call exitt
955  endif
956 
957  ifreguo = .false. ! by default we dump the data based on the GLL mesh
958  nrg = lxo
959 
960 ! how many elements are present up to rank nid
961  nn = nelt
962  nelb = igl_running_sum(nn)
963  nelb = nelb - nelt
964 
965  pid00 = int(glmin((/real(pid0)/),1))
966 
967  return
968 end subroutine io_init
969 
970 !-----------------------------------------------------------------------
971 subroutine mfo_open_files(prefix,ierr) ! open files
972  use kinds, only : dp
973  use input, only : ifreguo, ifxyo_, series, param
974  use restart, only : max_rst, nfileo, ifdiro, fid0
975  use string, only : ltrunc
976  implicit none
977 
978  character(3) :: prefix
979  integer :: ierr
980 
981  character(132) :: fname
982  character(1) :: fnam1(132)
983  equivalence(fnam1,fname)
984 
985  character(6), save :: six = "??????"
986  character(6) :: str
987 
988  character(1), save :: slash = '/', dot = '.'
989 
990  logical, save :: init = .false.
991  integer, save :: nopen(99,2) = 0
992 
993  integer :: iprefix, nfld, k, len, ndigit
994  integer, external :: i_find_prefix, mod1
995  real(DP) :: rfileo
996 
997  if (.not. init) then
998  nopen = int(param(69))
999  init = .true.
1000  endif
1001 
1002  call blank(fname,132) ! zero out for byte_open()
1003 
1004  iprefix = i_find_prefix(prefix,99)
1005  if (ifreguo) then
1006  nopen(iprefix,2) = nopen(iprefix,2)+1
1007  nfld = nopen(iprefix,2)
1008  else
1009  nopen(iprefix,1) = nopen(iprefix,1)+1
1010  nfld = nopen(iprefix,1)
1011  endif
1012 
1013  ! check for full-restart request
1014  if (prefix == 'rst' .AND. max_rst > 0) nfld = mod1(nfld,max_rst)
1015 
1016  call restart_nfld( nfld, prefix ) ! Check for Restart option.
1017  if (prefix == ' ' .AND. nfld == 1) ifxyo_ = .true. ! 1st file
1018 
1019 #ifdef MPIIO
1020  rfileo = 1
1021 #else
1022  rfileo = nfileo
1023 #endif
1024  ndigit = int(log10(rfileo) + 1)
1025 
1026  k = 1
1027  if (ifdiro) then ! Add directory
1028  call chcopy(fnam1(1),'A',1)
1029  call chcopy(fnam1(2),six,ndigit) ! put ???? in string
1030  k = 2 + ndigit
1031  call chcopy(fnam1(k),slash,1)
1032  k = k+1
1033  endif
1034 
1035  if (prefix(1:1) /= ' ' .AND. prefix(2:2) /= ' ' .AND. & ! Add prefix
1036  prefix(3:3) /= ' ') then
1037  call chcopy(fnam1(k),prefix,3)
1038  k = k+3
1039  endif
1040 
1041  len=ltrunc(series,132) ! Add SESSION
1042  call chcopy(fnam1(k),series,len)
1043  k = k+len
1044 
1045  if (ifreguo) then
1046  len=4
1047  call chcopy(fnam1(k),'_reg',len)
1048  k = k+len
1049  endif
1050 
1051  call chcopy(fnam1(k),six,ndigit) ! Add file-id holder
1052  k = k + ndigit
1053 
1054  call chcopy(fnam1(k ),dot,1) ! Add .f appendix
1055  call chcopy(fnam1(k+1),'f',1)
1056  k = k + 2
1057 
1058  write(str,4) nfld ! Add nfld number
1059  4 format(i5.5)
1060  call chcopy(fnam1(k),str,5)
1061  k = k + 5
1062 
1063  call mbyte_open(fname,fid0,ierr) ! Open blah000.fnnnn
1064 ! write(6,*) nid,fid0,' FILE:',fname
1065 
1066  return
1067 end subroutine mfo_open_files
1068 
1069 !-----------------------------------------------------------------------
1125 subroutine restart_nfld( nfld, prefix )
1126  use string, only : ltrunc, indx1
1127  implicit none
1128  character(3) :: prefix
1129  character(16), save :: kst = '0123456789abcdef'
1130  character(1) :: ks1(0:15),kin
1131  equivalence(ks1,kst)
1132 
1133  integer :: kfld, nfld, nfln
1134  integer, external :: mod1
1135 
1136  if (indx1(prefix,'rs',2) == 1) then
1137  read(prefix,3) kin
1138  3 format(2x,a1)
1139  do kfld=1,15
1140  if (ks1(kfld) == kin) goto 10
1141  enddo
1142  10 if (kfld == 16) kfld=4 ! std. default
1143  nfln = mod1(nfld,kfld) ! Restart A (1,2) and B (3,4)
1144  write(6,*) nfln,nfld,kfld,' kfld'
1145  nfld = nfln
1146  endif
1147 
1148  return
1149 end subroutine restart_nfld
1150 
1151 !-----------------------------------------------------------------------
1152 subroutine outpost(v1,v2,v3,vp,vt,name3)
1153  use kinds, only : dp
1154  use input, only : ifto
1155  implicit none
1156 
1157  real(DP) :: v1(*),v2(*),v3(*),vp(*),vt(*)
1158  character(3) :: name3
1159 
1160  integer :: itmp
1161  itmp=0
1162  if (ifto) itmp=1
1163  call outpost2(v1,v2,v3,vp,vt,itmp,name3)
1164 
1165  return
1166 end subroutine outpost
1167 
1168 !-----------------------------------------------------------------------
1169 subroutine outpost2(v1,v2,v3,vp,vt,nfldt,name3)
1170  use kinds, only : dp
1171  use size_m, only : lx1, ly1, lz1, lelt, lelv, ldimt
1172  use size_m, only : lx2, ly2, lz2
1173  use size_m, only : nx1, ny1, nz1, nx2, ny2, nz2, nelv, nelt
1174  use ctimer, only : tprep, dnekclock
1175  use input, only : ifto, ifpsco
1176  use soln, only : vx, vy, vz, pr, t
1177  implicit none
1178 
1179  integer, parameter :: ltot1=lx1*ly1*lz1*lelt
1180  integer, parameter :: ltot2=lx2*ly2*lz2*lelv
1181  real(DP), allocatable :: w1(:), w2(:), w3(:), wp(:), wt(:,:)
1182  real(DP) :: v1(1),v2(1),v3(1),vp(1),vt(ltot1,1)
1183  character(3) :: name3
1184  logical :: if_save(ldimt)
1185  real(DP) :: etime
1186 
1187  integer :: ntot1, ntot1t, ntot2, nfldt, i
1188  allocate(w1(ltot1),w2(ltot1),w3(ltot1),wp(ltot2),wt(ltot1,ldimt))
1189 
1190  etime = dnekclock()
1191 
1192  ntot1 = nx1*ny1*nz1*nelv
1193  ntot1t = nx1*ny1*nz1*nelt
1194  ntot2 = nx2*ny2*nz2*nelv
1195 
1196  if(nfldt > ldimt) then
1197  write(6,*) 'ABORT: outpost data too large (nfldt>ldimt)!'
1198  call exitt
1199  endif
1200 
1201 ! store solution
1202  call copy(w1,vx,ntot1)
1203  call copy(w2,vy,ntot1)
1204  call copy(w3,vz,ntot1)
1205  call copy(wp,pr,ntot2)
1206  do i = 1,nfldt
1207  call copy(wt(1,i),t(1,1,1,1,i),ntot1t)
1208  enddo
1209 
1210 ! swap with data to dump
1211  call copy(vx,v1,ntot1)
1212  call copy(vy,v2,ntot1)
1213  call copy(vz,v3,ntot1)
1214  call copy(pr,vp,ntot2)
1215  do i = 1,nfldt
1216  call copy(t(1,1,1,1,i),vt(1,i),ntot1t)
1217  enddo
1218 
1219 ! dump data
1220  if_save(1) = ifto
1221  ifto = .false.
1222  if(nfldt > 0) ifto = .true.
1223  do i = 1,ldimt-1
1224  if_save(i+1) = ifpsco(i)
1225  ifpsco(i) = .false.
1226  if(i+1 <= nfldt) ifpsco(i) = .true.
1227  enddo
1228 
1229  etime = etime - dnekclock()
1230  call prepost( .true. ,name3)
1231  etime = etime + dnekclock()
1232 
1233  ifto = if_save(1)
1234  do i = 1,ldimt-1
1235  ifpsco(i) = if_save(i+1)
1236  enddo
1237 
1238 ! restore solution data
1239  call copy(vx,w1,ntot1)
1240  call copy(vy,w2,ntot1)
1241  call copy(vz,w3,ntot1)
1242  call copy(pr,wp,ntot2)
1243  do i = 1,nfldt
1244  call copy(t(1,1,1,1,i),wt(1,i),ntot1t)
1245  enddo
1246 
1247  tprep = tprep + (dnekclock() - etime)
1248 
1249  return
1250 end subroutine outpost2
1251 
1252 !-----------------------------------------------------------------------
1253 subroutine mfo_mdatav(u,v,w,nel)
1254  use kinds, only : dp, r4
1255  use size_m, only : lx1, ly1, lz1, nx1, ny1, nz1, ndim, nelt, nid, lelt
1256  use input, only : if3d
1257  use restart, only : pid0, pid1
1258  implicit none
1259 
1260  real(DP), intent(in) :: u(lx1*ly1*lz1,*),v(lx1*ly1*lz1,*),w(lx1*ly1*lz1,*)
1261  integer, intent(in) :: nel
1262 
1263  real(r4) :: buffer(1+6*lelt)
1264 
1265  integer :: e, inelp, mtype, k, idum, nout, j, ierr, leo, len, nxyz, n
1266 
1267  call nekgsync() ! clear outstanding message queues.
1268 
1269  nxyz = nx1*ny1*nz1
1270  n = 2*ndim
1271  len = 4 + 4*(n*lelt) ! recv buffer size
1272  leo = 4 + 4*(n*nelt)
1273  ierr = 0
1274 
1275 ! Am I an I/O node?
1276  if (nid == pid0) then
1277  j = 1
1278  do e=1,nel
1279  buffer(j+0) = real(minval(u(:,e)), kind=r4)
1280  buffer(j+1) = real(maxval(u(:,e)), kind=r4)
1281  buffer(j+2) = real(minval(v(:,e)), kind=r4)
1282  buffer(j+3) = real(maxval(v(:,e)), kind=r4)
1283  j = j + 4
1284  if(if3d) then
1285  buffer(j+0) = real(minval(w(:,e)), kind=r4)
1286  buffer(j+1) = real(maxval(w(:,e)), kind=r4)
1287  j = j + 2
1288  endif
1289  enddo
1290 
1291  ! write out my data
1292  nout = n*nel
1293  if(ierr == 0) then
1294 #ifdef MPIIO
1295  call byte_write_mpi(buffer,nout,-1,ifh_mbyte,ierr)
1296 #else
1297  call byte_write(buffer,nout,ierr)
1298 #endif
1299  endif
1300 
1301  ! write out the data of my childs
1302  idum = 1
1303  do k=pid0+1,pid1
1304  mtype = k
1305  call csend(mtype,idum,4,k,0) ! handshake
1306  call crecv(mtype,buffer,len)
1307  inelp = int(buffer(1))
1308  nout = n*inelp
1309  if(ierr == 0) then
1310 #ifdef MPIIO
1311  call byte_write_mpi(buffer(2),nout,-1,ifh_mbyte,ierr)
1312 #else
1313  call byte_write(buffer(2),nout,ierr)
1314 #endif
1315  endif
1316  enddo
1317  else
1318  j = 1
1319  buffer(j) = nel
1320  j = j + 1
1321  do e=1,nel
1322  buffer(j+0) = real(minval(u(:,e)), kind=r4)
1323  buffer(j+1) = real(maxval(u(:,e)), kind=r4)
1324  buffer(j+2) = real(minval(v(:,e)), kind=r4)
1325  buffer(j+3) = real(maxval(v(:,e)), kind=r4)
1326  j = j + 4
1327  if(n == 6) then
1328  buffer(j+0) = real(minval(w(:,e)), kind=r4)
1329  buffer(j+1) = real(maxval(w(:,e)), kind=r4)
1330  j = j + 2
1331  endif
1332  enddo
1333 
1334  ! send my data to my pararent I/O node
1335  mtype = nid
1336  call crecv(mtype,idum,4) ! hand-shake
1337  call csend(mtype,buffer,leo,pid0,0) ! u4 :=: u8
1338  endif
1339 
1340  call err_chk(ierr,'Error writing data to .f00 in mfo_mdatav. $')
1341 
1342  return
1343 end subroutine mfo_mdatav
1344 
1345 !-----------------------------------------------------------------------
1346 subroutine mfo_mdatas(u,nel)
1347  use kinds, only : dp, r4
1348  use size_m, only : lx1, ly1, lz1, lelt, nx1, ny1, nz1, nelt, nid
1349  use restart, only : pid0, pid1
1350  implicit none
1351 
1352  real(DP), intent(in) :: u(lx1*ly1*lz1,*)
1353  integer, intent(in) :: nel
1354 
1355  real(r4) :: buffer(1+2*lelt)
1356 
1357  integer :: e, inelp, mtype, k, idum, nout, j, ierr, leo, len, n, nxyz
1358 
1359  call nekgsync() ! clear outstanding message queues.
1360 
1361  nxyz = nx1*ny1*nz1
1362  n = 2
1363  len = 4 + 4*(n*lelt) ! recv buffer size
1364  leo = 4 + 4*(n*nelt)
1365  ierr = 0
1366 
1367 ! Am I an I/O node?
1368  if (nid == pid0) then
1369  j = 1
1370  do e=1,nel
1371  buffer(j+0) = real(minval(u(:,e)), kind=r4)
1372  buffer(j+1) = real(maxval(u(:,e)), kind=r4)
1373  j = j + 2
1374  enddo
1375 
1376  ! write out my data
1377  nout = n*nel
1378  if(ierr == 0) then
1379 #ifdef MPIIO
1380  call byte_write_mpi(buffer,nout,-1,ifh_mbyte,ierr)
1381 #else
1382  call byte_write(buffer,nout,ierr)
1383 #endif
1384  endif
1385  ! write out the data of my childs
1386  idum = 1
1387  do k=pid0+1,pid1
1388  mtype = k
1389  call csend(mtype,idum,4,k,0) ! handshake
1390  call crecv(mtype,buffer,len)
1391  inelp = int(buffer(1))
1392  nout = n*inelp
1393  if(ierr == 0) then
1394 #ifdef MPIIO
1395  call byte_write_mpi(buffer(2),nout,-1,ifh_mbyte,ierr)
1396 #else
1397  call byte_write(buffer(2),nout,ierr)
1398 #endif
1399  endif
1400  enddo
1401  else
1402  j = 1
1403  buffer(j) = nel
1404  j = j + 1
1405  do e=1,nel
1406  buffer(j+0) = real(minval(u(:,e)), kind=r4)
1407  buffer(j+1) = real(maxval(u(:,e)), kind=r4)
1408  j = j + 2
1409  enddo
1410 
1411  ! send my data to my pararent I/O node
1412  mtype = nid
1413  call crecv(mtype,idum,4) ! hand-shake
1414  call csend(mtype,buffer,leo,pid0,0) ! u4 :=: u8
1415  endif
1416 
1417  call err_chk(ierr,'Error writing data to .f00 in mfo_mdatas. $')
1418 
1419  return
1420 end subroutine mfo_mdatas
1421 
1422 !-----------------------------------------------------------------------
1424 subroutine mfo_outs(u,nel,mx,my,mz)
1425  use kinds, only : dp, r4
1426  use size_m, only : nid, lelt, lxo
1427  use restart, only : wdsizo, pid0, pid1
1428  implicit none
1429 
1430  integer, intent(in) :: nel, mx, my, mz
1431  real(DP), intent(in) :: u(mx,my,mz,1)
1432 
1433  real(r4), allocatable :: u4(:)
1434  real(DP), allocatable :: u8(:)
1435 
1436  integer :: nxyz, len, leo, ntot, idum, ierr, nout, k, mtype
1437 
1438  call nekgsync() ! clear outstanding message queues.
1439  if(mx > lxo .OR. my > lxo .OR. mz > lxo) then
1440  if(nid == 0) write(6,*) 'ABORT: lxo too small'
1441  call exitt
1442  endif
1443 
1444  nxyz = mx*my*mz
1445  len = 8 + 8*(lelt*nxyz) ! recv buffer size
1446  leo = 8 + wdsizo*(nel*nxyz)
1447  ntot = nxyz*nel
1448 
1449  idum = 1
1450  ierr = 0
1451 
1452  if (wdsizo == 4) then
1453  allocate(u4(2+lxo*lxo*lxo*2*lelt))
1454  else
1455  allocate(u8(1+lxo*lxo*lxo*1*lelt))
1456  endif
1457 
1458  if (nid == pid0) then
1459 
1460  if (wdsizo == 4) then ! 32-bit output
1461  call copyx4(u4,u,ntot)
1462  !u4(1:ntot) = real(reshape(u(1:mx,1:my,1:mz,1:nel), (/ntot/)), kind=r4)
1463  else
1464  call copy(u8,u,ntot)
1465  !u8(1:ntot) = reshape(u(1:mx,1:my,1:mz,1:nel), (/ntot/))
1466  endif
1467 
1468  if(wdsizo == 4 .and. ierr == 0) then
1469  nout = wdsizo/4 * ntot
1470  call byte_write(u4,nout,ierr) ! u4 :=: u8
1471  elseif(ierr == 0) then
1472  nout = wdsizo/4 * ntot
1473  call byte_write(u8,nout,ierr) ! u4 :=: u8
1474  endif
1475 
1476  ! write out the data of my childs
1477  idum = 1
1478  do k=pid0+1,pid1
1479  mtype = k
1480  call csend(mtype,idum,4,k,0) ! handshake
1481 
1482  if (wdsizo == 4 .AND. ierr == 0) then
1483  call crecv(mtype,u4,len)
1484  nout = wdsizo/4 * nxyz * int(u4(1))
1485  call byte_write(u4(3),nout,ierr)
1486  elseif(ierr == 0) then
1487  call crecv(mtype,u8,len)
1488  nout = wdsizo/4 * nxyz * int(u8(1))
1489  call byte_write(u8(2),nout,ierr)
1490  endif
1491 
1492  enddo
1493 
1494  else
1495 
1496  if (wdsizo == 4) then ! 32-bit output
1497  u4(1)= nel
1498  call copyx4(u4(3),u,ntot)
1499  mtype = nid
1500  call crecv(mtype,idum,4) ! hand-shake
1501  call csend(mtype,u4,leo,pid0,0) ! u4 :=: u8
1502  else
1503  u8(1)= nel
1504  call copy(u8(2),u,ntot)
1505  mtype = nid
1506  call crecv(mtype,idum,4) ! hand-shake
1507  call csend(mtype,u8,leo,pid0,0) ! u4 :=: u8
1508  endif
1509 
1510  endif
1511 
1512  call err_chk(ierr,'Error writing data to .f00 in mfo_outs. $')
1513 
1514  return
1515 end subroutine mfo_outs
1516 
1517 !-----------------------------------------------------------------------
1519 subroutine mfo_outv(u,v,w,nel,mx,my,mz)
1520  use kinds, only : dp, r4
1521  use size_m, only : nid, ndim, lxo, lelt
1522  use input, only : if3d
1523  use restart, only : wdsizo, pid0, pid1
1524  implicit none
1525 
1526  integer, intent(in) :: mx, my, mz
1527  real(DP), intent(in) :: u(mx*my*mz,*),v(mx*my*mz,*),w(mx*my*mz,*)
1528 
1529  real(r4), allocatable :: u4(:)
1530  real(DP), allocatable :: u8(:)
1531 
1532  integer :: nxyz, len, leo, nel, idum, ierr
1533  integer :: j, iel, nout, k, mtype
1534 
1535  call nekgsync() ! clear outstanding message queues.
1536  if(mx > lxo .OR. my > lxo .OR. mz > lxo) then
1537  if(nid == 0) write(6,*) 'ABORT: lxo too small'
1538  call exitt
1539  endif
1540 
1541  nxyz = mx*my*mz
1542  len = 8 + 8*(lelt*nxyz*ndim) ! recv buffer size (u4)
1543  leo = 8 + wdsizo*(nel*nxyz*ndim)
1544  idum = 1
1545  ierr = 0
1546 
1547  if (wdsizo == 4) then
1548  allocate(u4(2+lxo*lxo*lxo*6*lelt))
1549  else
1550  allocate(u8(1+lxo*lxo*lxo*3*lelt))
1551  endif
1552 
1553  if (nid == pid0) then
1554  j = 0
1555  if (wdsizo == 4) then ! 32-bit output
1556  do iel = 1,nel
1557  call copyx4(u4(j+1),u(1,iel),nxyz)
1558  j = j + nxyz
1559  call copyx4(u4(j+1),v(1,iel),nxyz)
1560  j = j + nxyz
1561  if(if3d) then
1562  call copyx4(u4(j+1),w(1,iel),nxyz)
1563  j = j + nxyz
1564  endif
1565  enddo
1566  else
1567  do iel = 1,nel
1568  call copy(u8(j+1),u(1,iel),nxyz)
1569  j = j + nxyz
1570  call copy(u8(j+1),v(1,iel),nxyz)
1571  j = j + nxyz
1572  if(if3d) then
1573  call copy(u8(j+1),w(1,iel),nxyz)
1574  j = j + nxyz
1575  endif
1576  enddo
1577  endif
1578  nout = wdsizo/4 * ndim*nel * nxyz
1579  if (wdsizo == 4 .and. ierr == 0) then
1580  call byte_write(u4,nout,ierr) ! u4 :=: u8
1581  elseif (ierr == 0) then
1582  call byte_write(u8,nout,ierr) ! u4 :=: u8
1583  endif
1584  ! write out the data of my childs
1585  do k=pid0+1,pid1
1586  mtype = k
1587  call csend(mtype,idum,4,k,0) ! handshake
1588 
1589  if (wdsizo == 4 .AND. ierr == 0) then
1590  call crecv(mtype,u4,len)
1591  nout = wdsizo/4 * ndim*nxyz * int(u4(1))
1592  call byte_write(u4(3),nout,ierr)
1593  elseif(ierr == 0) then
1594  call crecv(mtype,u8,len)
1595  nout = wdsizo/4 * ndim*nxyz * int(u8(1))
1596  call byte_write(u8(2),nout,ierr)
1597  endif
1598  enddo
1599  else
1600 
1601  if (wdsizo == 4) then ! 32-bit output
1602  u4(1) = nel
1603  j = 2
1604  do iel = 1,nel
1605  call copyx4(u4(j+1),u(1,iel),nxyz)
1606  j = j + nxyz
1607  call copyx4(u4(j+1),v(1,iel),nxyz)
1608  j = j + nxyz
1609  if(if3d) then
1610  call copyx4(u4(j+1),w(1,iel),nxyz)
1611  j = j + nxyz
1612  endif
1613  enddo
1614  mtype = nid
1615  call crecv(mtype,idum,4) ! hand-shake
1616  call csend(mtype,u4,leo,pid0,0) ! u4 :=: u8
1617  else
1618  u8(1) = nel
1619  j = 1
1620  do iel = 1,nel
1621  call copy(u8(j+1),u(1,iel),nxyz)
1622  j = j + nxyz
1623  call copy(u8(j+1),v(1,iel),nxyz)
1624  j = j + nxyz
1625  if(if3d) then
1626  call copy(u8(j+1),w(1,iel),nxyz)
1627  j = j + nxyz
1628  endif
1629  enddo
1630  mtype = nid
1631  call crecv(mtype,idum,4) ! hand-shake
1632  call csend(mtype,u8,leo,pid0,0) ! u4 :=: u8
1633  endif
1634  endif
1635 
1636  call err_chk(ierr,'Error writing data to .f00 in mfo_outv. $')
1637  return
1638 end subroutine mfo_outv
1639 
1640 !-----------------------------------------------------------------------
1642 subroutine mfo_write_hdr
1643  use kinds, only : r4
1644  use size_m, only : nid, nelt, lelt, ldimt
1645  use input, only : ifxyo, ifvo, ifpo, ifto, ifpsco, param
1646  use parallel, only : nelgt, lglel
1647  use restart, only : nfileo, pid0, pid1, rdcode1, wdsizo, nxo, nyo, nzo
1648  use restart, only : fid0, iheadersize
1649  use tstep, only : istep, time
1650  implicit none
1651 
1652  real(r4) :: test_pattern
1653  real(r4), allocatable :: padding(:)
1654  integer :: lglist(0:lelt)
1655 
1656  character(132) :: hdr
1657  character(4) :: tag
1658 
1659  integer :: idum, nfileoo, nelo, j, mtype, inelp, ierr, i, npscalo, k
1660  integer :: ibsw_out, len
1661  integer :: pad_size
1662 
1663  call nekgsync()
1664  idum = 1
1665 
1666  if (param(61) < 1) then
1667  tag = '#std'
1668  else
1669  tag = '#max'
1670  endif
1671 
1672 #ifdef MPIIO
1673  nfileoo = 1 ! all data into one file
1674  nelo = nelgt
1675 #else
1676  nfileoo = nfileo
1677  if(nid == pid0) then ! how many elements to dump
1678  nelo = nelt
1679  do j = pid0+1,pid1
1680  mtype = j
1681  call csend(mtype,idum,4,j,0) ! handshake
1682  call crecv(mtype,inelp,4)
1683  nelo = nelo + inelp
1684  enddo
1685  else
1686  mtype = nid
1687  call crecv(mtype,idum,4) ! hand-shake
1688  call csend(mtype,nelt,4,pid0,0) ! u4 :=: u8
1689  endif
1690 #endif
1691 
1692  ierr = 0
1693  if(nid == pid0) then
1694 
1695  call blank(hdr,132) ! write header
1696  call blank(rdcode1,10)
1697  i = 1
1698  IF (ifxyo) THEN
1699  rdcode1(i)='X'
1700  i = i + 1
1701  ENDIF
1702  IF (ifvo) THEN
1703  rdcode1(i)='U'
1704  i = i + 1
1705  ENDIF
1706  IF (ifpo) THEN
1707  rdcode1(i)='P'
1708  i = i + 1
1709  ENDIF
1710  IF (ifto) THEN
1711  rdcode1(i)='T'
1712  i = i + 1
1713  ENDIF
1714  IF (ldimt > 1) THEN
1715  npscalo = 0
1716  do k = 1,ldimt-1
1717  if(ifpsco(k)) npscalo = npscalo + 1
1718  enddo
1719  IF (npscalo > 0) THEN
1720  rdcode1(i) = 'S'
1721  WRITE(rdcode1(i+1),'(I1)') npscalo/10
1722  WRITE(rdcode1(i+2),'(I1)') npscalo-(npscalo/10)*10
1723  ENDIF
1724  ENDIF
1725 
1726  write(hdr,1) tag, wdsizo,nxo,nyo,nzo,nelo,nelgt,time,istep,fid0,nfileoo &
1727  , (rdcode1(i),i=1,10) ! 74+20=94
1728  1 format(a4,1x,i1,1x,i2,1x,i2,1x,i2,1x,i10,1x,i10,1x,e20.13, &
1729  & 1x,i9,1x,i6,1x,i6,1x,10a)
1730 
1731  ! if we want to switch the bytes for output
1732  ! switch it again because the hdr is in ASCII
1733  call get_bytesw_write(ibsw_out)
1734  ! if (ibsw_out.ne.0) call set_bytesw_write(ibsw_out)
1735  if (ibsw_out /= 0) call set_bytesw_write(0)
1736 
1737  test_pattern = 6.54321_r4 ! write test pattern for byte swap
1738 
1739  pad_size = modulo(-(iheadersize + 4),int(2**param(61))) / 4
1740  allocate(padding(pad_size)); padding = 0.
1741 #ifdef MPIIO
1742  ! only rank0 (pid00) will write hdr + test_pattern
1743  call byte_write_mpi(hdr,iheadersize/4,pid00,ifh_mbyte,ierr)
1744  call byte_write_mpi(test_pattern,1,pid00,ifh_mbyte,ierr)
1745  call byte_write_mpi(padding, pad_size, pid00, ifh_mbyte, ierr)
1746 #else
1747  call byte_write(hdr,iheadersize/4,ierr)
1748  call byte_write(test_pattern,1,ierr)
1749  ! pad up to 8MB
1750  call byte_write(padding, pad_size, ierr)
1751 #endif
1752  deallocate(padding)
1753 
1754  endif
1755 
1756  call err_chk(ierr,'Error writing header in mfo_write_hdr. $')
1757 
1758 ! write global element numbering for this group
1759  if(nid == pid0) then
1760  do j = 1, nelt
1761  lglist(j) = lglel(j)
1762  enddo
1763 #ifdef MPIIO
1764  ioff = iheadersize + 4 + 4*pad_size + nelb*isize
1765  call byte_set_view(ioff,ifh_mbyte)
1766  call byte_write_mpi(lglist,nelt,-1,ifh_mbyte,ierr)
1767 #else
1768  call byte_write(lglist,nelt,ierr)
1769 #endif
1770  pad_size = -nelt
1771  do j = pid0+1,pid1
1772  mtype = j
1773  call csend(mtype,idum,4,j,0) ! handshake
1774  len = 4*(lelt+1)
1775  call crecv(mtype,lglist,len)
1776  if(ierr == 0) then
1777 #ifdef MPIIO
1778  call byte_write_mpi(lglist(1),lglist(0),-1,ifh_mbyte,ierr)
1779 #else
1780  call byte_write(lglist(1),lglist(0),ierr)
1781 #endif
1782  pad_size = pad_size - lglist(0)
1783  endif
1784  enddo
1785 
1786  ! pad up to 8MB
1787  pad_size = modulo(pad_size*4,int(2**param(61))) / 4
1788  allocate(padding(pad_size)); padding = 0.
1789 #ifdef MPIIO
1790  call byte_write_mpi(padding, pad_size, pid00, ifh_mbyte, ierr)
1791 #else
1792  call byte_write(padding, pad_size, ierr)
1793 #endif
1794  deallocate(padding)
1795 
1796  else
1797  mtype = nid
1798  call crecv(mtype,idum,4) ! hand-shake
1799 
1800  lglist(0) = nelt
1801  do j = 1, nelt
1802  lglist(j) = lglel(j)
1803  enddo
1804 
1805  len = 4*(nelt+1)
1806  call csend(mtype,lglist,len,pid0,0)
1807  endif
1808 
1809 
1810 
1811  call err_chk(ierr,'Error writing global nums in mfo_write_hdr$')
1812  return
1813 end subroutine mfo_write_hdr
1814 
1815 !-----------------------------------------------------------------------
integer function gllel(ieg)
subroutine mfo_write_hdr
write hdr, byte key, els.
Definition: prepost.F90:1642
#define get_bytesw_write
Definition: byte.c:42
subroutine prepost_map(isave, pm1)
Store results for later postprocessing.
Definition: prepost.F90:130
subroutine bcast(buf, len)
Definition: comm_mpi.F90:289
#define byte_close
Definition: byte.c:36
subroutine byte_set_view(ioff_in, mpi_fh)
Definition: byte_mpi.F90:142
integer function mod1(i, n)
Yields MOD(I,N) with the exception that if I=K*N, result is N.
Definition: math.F90:116
cleaned
Definition: tstep_mod.F90:2
subroutine outpost2(v1, v2, v3, vp, vt, nfldt, name3)
Definition: prepost.F90:1169
Input parameters from preprocessors.
Definition: input_mod.F90:11
Definition: soln_mod.F90:1
subroutine mxm(a, n1, b, n2, c, n3)
Compute matrix-matrix product C = A*B.
Definition: mxm_wrapper.F90:7
subroutine mfo_outv(u, v, w, nel, mx, my, mz)
output a vector field
Definition: prepost.F90:1519
subroutine mfo_mdatas(u, nel)
Definition: prepost.F90:1346
subroutine outhis(ifhis, pm1)
output time history info.
Definition: prepost.F90:429
subroutine mbyte_open(hname, fid, ierr)
open blah000.fldnn
Definition: ic.F90:1592
subroutine io_init
Definition: prepost.F90:903
subroutine crecv(mtype, buf, lenm)
Definition: comm_mpi.F90:223
subroutine restart_nfld(nfld, prefix)
Check for Restart option and return proper nfld value. Also, convenient spot to explain restart strat...
Definition: prepost.F90:1125
real(dp) function dnekclock_sync()
Definition: ctimer_mod.F90:113
void exitt()
Definition: comm_mpi.F90:411
integer function indx1(S1, S2, L2)
Definition: string_mod.F90:43
#define byte_open
Definition: byte.c:35
real(dp) function dnekclock()
Definition: ctimer_mod.F90:103
integer function lglel(iel)
subroutine copy(a, b, n)
Definition: math.F90:52
subroutine prepost(ifdoin, prefin)
Store results for later postprocessing. Recent updates: p65 now indicates the number of parallel i/o ...
Definition: prepost.F90:5
integer function gllnid(ieg)
subroutine byte_close_mpi(mpi_fh, ierr)
Definition: byte_mpi.F90:117
subroutine mfo_outs(u, nel, mx, my, mz)
output a scalar field
Definition: prepost.F90:1424
subroutine mfo_outfld(prefix, pm1)
mult-file output
Definition: prepost.F90:695
subroutine copyx4(a, b, n)
Definition: prepost.F90:630
subroutine nek_comm_io(nn)
Definition: byte_mpi.F90:171
subroutine outpost(v1, v2, v3, vp, vt, name3)
Definition: prepost.F90:1152
subroutine mfo_mdatav(u, v, w, nel)
Definition: prepost.F90:1253
#define set_bytesw_write
Definition: byte.c:40
subroutine outfld(prefix, pm1)
output .fld file
Definition: prepost.F90:248
cleaned
Definition: parallel_mod.F90:2
cleaned
Definition: restart_mod.F90:2
#define byte_write
Definition: byte.c:39
for i
Definition: xxt_test.m:74
subroutine blank(A, N)
blank a string
Definition: math.F90:38
subroutine mfo_open_files(prefix, ierr)
Definition: prepost.F90:971
subroutine nekgsync()
Definition: comm_mpi.F90:318
subroutine copy4r(a, b, n)
Definition: prepost.F90:644
Geometry arrays.
Definition: geom_mod.F90:2
static uint id
Definition: findpts_test.c:63
subroutine gop(x, w, op, n)
Global vector commutative operation.
Definition: comm_mpi.F90:104
subroutine chcopy(a, b, n)
Definition: math.F90:63
subroutine err_chk(ierr, istring)
Definition: comm_mpi.F90:356
static uint np
Definition: findpts_test.c:63
integer function ltrunc(string, l)
Definition: string_mod.F90:260
integer function i_find_prefix(prefix, imax)
Definition: prepost.F90:657
subroutine csend(mtype, buf, len, jnid, jpid)
Definition: comm_mpi.F90:209
Definition: ixyz_mod.F90:2
subroutine byte_write_mpi(buf, icount, iorank, mpi_fh, ierr)
Definition: byte_mpi.F90:81