MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_convert_files.t
Go to the documentation of this file.
2 use mod_comm_lib, only: mpistop
3
4 implicit none
5 public
6
7contains
8
14 use mod_convert, only: convert_all
18
19 character(len=std_len) :: convert_type_elem
20 integer :: i
21
22 select case(convert_type)
23 case('tecplot','tecplotCC','tecline')
25 case('tecplotmpi','tecplotCCmpi','teclinempi')
27 case('vtu','vtuCC')
29 case('vtumpi','vtuCCmpi')
31 case('vtuB','vtuBCC','vtuBmpi','vtuBCCmpi')
33 case('vtuB64','vtuBCC64','vtuBmpi64','vtuBCCmpi64')
35 {^iftwod
36 case('vtuB23','vtuBCC23')
38 case('vtuBsym23','vtuBCCsym23')
40 }
41 case('pvtumpi','pvtuCCmpi')
43 case('pvtuBmpi','pvtuBCCmpi')
45 case('vtimpi','vtiCCmpi')
47 case('onegrid','onegridmpi')
49 case('oneblock','oneblockB')
51 case('EIvtiCCmpi','ESvtiCCmpi','SIvtiCCmpi','WIvtiCCmpi','EIvtuCCmpi','ESvtuCCmpi','SIvtuCCmpi','WIvtuCCmpi')
52 ! output synthetic euv emission
53 if (ndim==3 .and. associated(phys_te_images)) then
55 endif
56 case('dat_generic_mpi')
57 call convert_all()
58 case('magnetic_helicity')
59 call mh_run_task()
60 case('magnetic_topology')
62 case('user','usermpi')
63 if (.not. associated(usr_special_convert)) then
64 call mpistop("usr_special_convert not defined")
65 else
67 end if
68 case default
69 call mpistop("Error in generate_plotfile: Unknown convert_type")
70 end select
71
72 end subroutine generate_plotfile
73
74 subroutine oneblock(qunit)
75 ! this is for turning an AMR run into a single block
76 ! the data will be all on selected level level_io
77 ! this version should work for any dimension
78 ! only writes w_write selected 1:nw variables, also nwauxio
79 ! may use saveprim to switch to primitives
80 ! this version can not work on multiple CPUs
81 ! does not renormalize variables
82 ! header info differs from onegrid below
83 ! ASCII or binary output
84
88 use mod_physics
91 integer, intent(in) :: qunit
92
93 double precision:: normconv(0:nw+nwauxio)
94 integer :: Morton_no,igrid,ix^D,ig^D,level
95 integer, pointer :: ig_to_igrid(:^D&,:)
96 integer :: filenr,ncells^D,ncellx^D,jg^D,jig^D
97 integer :: iw,iiw,writenw,iwrite(1:nw+nwauxio),iigrid,idim
98 logical :: fileopen,writeblk(max_blocks)
99 logical :: patchw(ixG^T)
100 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
101 character(len=1024) :: outfilehead
102 character(len=80) :: filename
103
104 if(level_io<1)then
105 call mpistop('please specify level_io>0 for usage with oneblock')
106 end if
107
108 if(autoconvert)then
109 call mpistop('Set autoconvert=F and convert oneblock data manually')
110 end if
111
112 if(npe>1)then
113 if(mype==0) print *,'ONEBLOCK as yet to be parallelized'
114 call mpistop('npe>1, oneblock')
115 end if
116
117 ! only variables selected by w_write will be written out
118 normconv(0:nw+nwauxio)=one
119 normconv(0) = length_convert_factor
120 normconv(1:nw) = w_convert_factor
121 writenw=count(w_write(1:nw))+nwauxio
122 iiw=0
123 do iw =1,nw
124 if (.not.w_write(iw))cycle
125 iiw=iiw+1
126 iwrite(iiw)=iw
127 end do
128 if(nwauxio>0)then
129 do iw =nw+1,nw+nwauxio
130 iiw=iiw+1
131 iwrite(iiw)=iw
132 end do
133 end if
134
135 allocate(ig_to_igrid(ng^d(level_io),0:npe-1))
136 ig_to_igrid=-1
137 writeblk=.false.
138 do morton_no=morton_start(mype),morton_stop(mype)
139 igrid=sfc_to_igrid(morton_no)
140 level=node(plevel_,igrid)
141 ig^d=igrid_to_node(igrid,mype)%node%ig^d;
142 ig_to_igrid(ig^d,mype)=igrid
143 if(({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
144 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
145 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
146 writeblk(igrid)=.true.
147 end if
148 end do
149
150 call getheadernames(wnamei,xandwnamei,outfilehead)
151 ncells^d=0;
152 ncellx^d=ixmhi^d-ixmlo^d+1\
153 {do ig^d=1,ng^d(level_io)\}
154 igrid=ig_to_igrid(ig^d,mype)
155 if(writeblk(igrid)) go to 20
156 {end do\}
157 20 continue
158 jg^d=ig^d;
159 {
160 jig^dd=jg^dd;
161 do ig^d=1,ng^d(level_io)
162 jig^d=ig^d
163 igrid=ig_to_igrid(jig^dd,mype)
164 if(writeblk(igrid)) ncells^d=ncells^d+ncellx^d
165 end do
166 \}
167
168 do iigrid=1,igridstail; igrid=igrids(iigrid)
169 if(.not.writeblk(igrid)) cycle
170 block=>ps(igrid)
171 call alloc_state_output(igrid,ps1(igrid),ixg^ll)
172 ps1(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
173 if(nwauxio > 0) then
174 if (.not. associated(usr_aux_output)) then
175 call mpistop("usr_aux_output not defined")
176 else
177 call usr_aux_output(ixg^ll,ixm^ll^ladd1,ps1(igrid)%w,ps(igrid)%x,normconv)
178 end if
179 end if
180 if(saveprim) then
181 call phys_to_primitive(ixg^ll,ixg^ll^lsub2,ps1(igrid)%w,ps(igrid)%x)
182 if(b0field) ps1(igrid)%w(ixg^t,iw_mag(:))=ps1(igrid)%w(ixg^t,iw_mag(:))+ps(igrid)%B0(ixg^t,:,0)
183 else
184 if(b0field) then
185 ! add background magnetic field B0 to B
186 if(phys_total_energy) then
187 ps1(igrid)%w(ixg^t,iw_e)=ps1(igrid)%w(ixg^t,iw_e)+0.5d0*sum(ps(igrid)%B0(ixg^t,:,0)**2,dim=ndim+1) &
188 + sum(ps1(igrid)%w(ixg^t,iw_mag(:))*ps(igrid)%B0(ixg^t,:,0),dim=ndim+1)
189 end if
190 ps1(igrid)%w(ixg^t,iw_mag(:))=ps1(igrid)%w(ixg^t,iw_mag(:))+ps(igrid)%B0(ixg^t,:,0)
191 end if
192 end if
193 end do
194
195 master_cpu_open : if (mype == 0) then
196 inquire(qunit,opened=fileopen)
197 if (.not.fileopen) then
198 ! generate filename
199 filenr=snapshotini
200 if (autoconvert) filenr=snapshotnext
201 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".blk"
202 select case(convert_type)
203 case("oneblock")
204 open(qunit,file=filename,status='unknown')
205 write(qunit,*) trim(outfilehead)
206 write(qunit,*) ncells^d
207 write(qunit,*) real(global_time*time_convert_factor)
208 case("oneblockB")
209 open(qunit,file=filename,form='unformatted',status='unknown')
210 write(qunit) outfilehead
211 write(qunit) ncells^d
212 write(qunit) real(global_time*time_convert_factor)
213 end select
214 end if
215 end if master_cpu_open
216
217 {^ifthreed
218 do ig3=1,ng3(level_io)
219 do ix3=ixmlo3,ixmhi3}
220
221 {^nooned
222 do ig2=1,ng2(level_io)
223 do ix2=ixmlo2,ixmhi2}
224
225 do ig1=1,ng1(level_io)
226 igrid=ig_to_igrid(ig^d,mype)
227 if(.not.writeblk(igrid)) cycle
228 do ix1=ixmlo1,ixmhi1
229 master_write : if(mype==0) then
230 select case(convert_type)
231 case("oneblock")
232 write(qunit,fmt="(100(e14.6))") &
233 ps(igrid)%x(ix^d,1:ndim)*normconv(0),&
234 (ps1(igrid)%w(ix^d,iwrite(iw))*normconv(iwrite(iw)),iw=1,writenw)
235 case("oneblockB")
236 write(qunit) real(ps(igrid)%x(ix^d,1:ndim)*normconv(0)),&
237 (real(ps1(igrid)%w(ix^d,iwrite(iw))*normconv(iwrite(iw))),iw=1,writenw)
238 end select
239 end if master_write
240 end do
241 end do
242 {^nooned
243 end do
244 end do}
245 {^ifthreed
246 end do
247 end do}
248
249 close(qunit)
250
251 end subroutine oneblock
252
253 subroutine onegrid(qunit)
254 ! this is for turning an AMR run into a single grid
255 ! this version should work for any dimension, can be in parallel
256 ! in 1D, should behave much like oneblock, except for header info
257
258 ! only writes all 1:nw variables, no nwauxio
259 ! may use saveprim to switch to primitives
260 ! this version can work on multiple CPUs
261 ! does not renormalize variables
262 ! ASCII output
263
266 use mod_physics
268 integer, intent(in) :: qunit
269
270 double precision :: w_recv(ixG^T,1:nw),x_recv(ixG^T,1:ndim)
271 integer :: itag,Morton_no,igrid,ix^D,iw
272 integer :: filenr
273 !.. MPI variables ..
274 integer :: igrid_recv,ipe
275 integer, allocatable :: intstatus(:,:)
276 logical :: fileopen
277 character(len=80) :: filename
278 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
279 character(len=1024) :: outfilehead
280
281
282 if(nwauxio>0)then
283 if(mype==0) print *,'ONEGRID to be used without nwauxio'
284 call mpistop('nwauxio>0, onegrid')
285 end if
286
287 if(saveprim)then
288 if(mype==0.and.nwaux>0) print *,'warning: ONEGRID used with saveprim, check auxiliaries'
289 end if
290
291 master_cpu_open : if (mype == 0) then
292 call getheadernames(wnamei,xandwnamei,outfilehead)
293 write(outfilehead,'(a)') "#"//" "//trim(outfilehead)
294 inquire(qunit,opened=fileopen)
295 if (.not.fileopen) then
296 ! generate filename
297 filenr=snapshotini
298 if (autoconvert) filenr=snapshotnext
299 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".blk"
300 open(qunit,file=filename,status='unknown')
301 end if
302 write(qunit,"(a)")outfilehead
303 write(qunit,"(i7)") ( {^d&(ixmhi^d-ixmlo^d+1)*} )*(morton_stop(npe-1)-morton_start(0)+1)
304 end if master_cpu_open
305
306 do morton_no=morton_start(mype),morton_stop(mype)
307 igrid=sfc_to_igrid(morton_no)
308 if(saveprim) call phys_to_primitive(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x)
309 if(mype/=0)then
310 itag=morton_no
311 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
312 call mpi_send(ps(igrid)%x,1,type_block_xcc_io, 0,itag,icomm,ierrmpi)
313 itag=igrid
314 call mpi_send(ps(igrid)%w,1,type_block_io, 0,itag,icomm,ierrmpi)
315 else
316 {do ix^db=ixmlo^db,ixmhi^db\}
317 do iw=1,nw
318 if( dabs(ps(igrid)%w(ix^d,iw)) < 1.0d-32 ) ps(igrid)%w(ix^d,iw) = zero
319 end do
320 write(qunit,fmt="(100(e14.6))") ps(igrid)%x(ix^d,1:ndim),ps(igrid)%w(ix^d,1:nw)
321 {end do\}
322 end if
323 end do
324
325 if(mype==0.and.npe>1) allocate(intstatus(mpi_status_size,1))
326
327 manycpu : if (npe>1) then
328 if (mype==0) then
329 loop_cpu : do ipe =1, npe-1
330 loop_morton : do morton_no=morton_start(ipe),morton_stop(ipe)
331 itag=morton_no
332 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
333 call mpi_recv(x_recv,1,type_block_xcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
334 itag=igrid_recv
335 call mpi_recv(w_recv,1,type_block_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
336 {do ix^db=ixmlo^db,ixmhi^db\}
337 do iw=1,nw
338 if( dabs(ps(igrid)%w(ix^d,iw)) < smalldouble ) ps(igrid)%w(ix^d,iw) = zero
339 end do
340 write(qunit,fmt="(100(e14.6))") x_recv(ix^d,1:ndim),w_recv(ix^d,1:nw)
341 {end do\}
342 end do loop_morton
343 end do loop_cpu
344 end if
345 end if manycpu
346
347 if (npe>1) then
348 call mpi_barrier(icomm,ierrmpi)
349 if(mype==0)deallocate(intstatus)
350 end if
351
352 if(mype==0) close(qunit)
353 end subroutine onegrid
354
355 subroutine tecplot(qunit)
356
357 ! output for tecplot (ASCII format)
358 ! not parallel, uses calc_grid to compute nwauxio variables
359 ! allows renormalizing using convert factors
360
363
364 integer, intent(in) :: qunit
365
366 double precision :: x_TEC(ndim), w_TEC(nw+nwauxio)
367 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
368 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
369 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
370 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
371 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP
372 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
373 double precision, dimension(0:nw+nwauxio) :: normconv
374 integer:: igrid,iigrid,level,igonlevel,iw,idim,ix^D
375 integer:: NumGridsOnLevel(1:nlevelshi)
376 integer :: nx^D,nxC^D,nodesonlevel,elemsonlevel,ixC^L,ixCC^L
377 integer :: nodes, elems
378 integer :: filenr
379 logical :: fileopen,first
380 character(len=80) :: filename
381 !!! possible length conflict
382 character(len=1024) :: tecplothead
383 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
384 character(len=1024) :: outfilehead
385
386 if(npe>1)then
387 if(mype==0) print *,'tecplot not parallel, use tecplotmpi'
388 call mpistop('npe>1, tecplot')
389 end if
390
391 if(nw/=count(w_write(1:nw)))then
392 if(mype==0) print *,'tecplot does not use w_write=F'
393 call mpistop('w_write, tecplot')
394 end if
395
396 if(nocartesian)then
397 if(mype==0) print *,'tecplot with nocartesian'
398 end if
399
400 inquire(qunit,opened=fileopen)
401 if(.not.fileopen) then
402 ! generate filename
403 filenr=snapshotini
404 if (autoconvert) filenr=snapshotnext
405 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".plt"
406 open(qunit,file=filename,status='unknown')
407 end if
408
409 call getheadernames(wnamei,xandwnamei,outfilehead)
410
411 write(tecplothead,'(a)') "VARIABLES = "//trim(outfilehead)
412 write(qunit,'(a)') tecplothead(1:len_trim(tecplothead))
413
414 numgridsonlevel(1:nlevelshi)=0
415 do level=levmin,levmax
416 numgridsonlevel(level)=0
417 do iigrid=1,igridstail; igrid=igrids(iigrid);
418 if (node(plevel_,igrid)/=level) cycle
419 numgridsonlevel(level)=numgridsonlevel(level)+1
420 end do
421 end do
422
423 nx^d=ixmhi^d-ixmlo^d+1;
424 nxc^d=nx^d+1;
425
426 {^ifoned
427 if(convert_type=='tecline') then
428 nodes=0
429 elems=0
430 do level=levmin,levmax
431 nodes=nodes + numgridsonlevel(level)*{nxc^d*}
432 elems=elems + numgridsonlevel(level)*{nx^d*}
433 end do
434
435 write(qunit,"(a,i7,a,1pe12.5,a)") &
436 'ZONE T="all levels", I=',elems, &
437 ', SOLUTIONTIME=',global_time*time_convert_factor,', F=POINT'
438
439 igonlevel=0
440 do iigrid=1,igridstail; igrid=igrids(iigrid);
441 block=>ps(igrid)
442 call calc_x(igrid,xc,xcc)
443 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,ixc^l,ixcc^l,.true.)
444 {do ix^db=ixccmin^db,ixccmax^db\}
445 x_tec(1:ndim)=xcc_tmp(ix^d,1:ndim)*normconv(0)
446 w_tec(1:nw+nwauxio)=wcc_tmp(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
447 write(qunit,fmt="(100(e24.16))") x_tec, w_tec
448 {end do\}
449 end do
450 close(qunit)
451 else
452 }
453 do level=levmin,levmax
454 nodesonlevel=numgridsonlevel(level)*{nxc^d*}
455 elemsonlevel=numgridsonlevel(level)*{nx^d*}
456 ! for all tecplot variants coded up here, we let the TECPLOT ZONES coincide
457 ! with the AMR grid LEVEL. Other options would be
458 ! let each grid define a zone: inefficient for TECPLOT internal workings
459 ! hence not implemented
460 ! let entire octree define 1 zone: no difference in interpolation
461 ! properties across TECPLOT zones detected as yet, hence not done
462 select case(convert_type)
463 case('tecplot')
464 ! in this option, we store the corner coordinates, as well as the corner
465 ! values of all variables (obtained by averaging). This allows POINT packaging,
466 ! and thus we can save full grid info by using one call to calc_grid
467 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,a)") &
468 'ZONE T="',level,'"',', N=',nodesonlevel,', E=',elemsonlevel, &
469 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=POINT, ZONETYPE=', &
470 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
471 do iigrid=1,igridstail; igrid=igrids(iigrid);
472 if (node(plevel_,igrid)/=level) cycle
473 block=>ps(igrid)
474 call calc_x(igrid,xc,xcc)
475 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
476 ixc^l,ixcc^l,.true.)
477 {do ix^db=ixcmin^db,ixcmax^db\}
478 x_tec(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0)
479 w_tec(1:nw+nwauxio)=wc_tmp(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
480 write(qunit,fmt="(100(e14.6))") x_tec, w_tec
481 {end do\}
482 end do
483 case('tecplotCC')
484 ! in this option, we store the corner coordinates, and the cell center
485 ! values of all variables. Due to this mix of corner/cell center, we must
486 ! use BLOCK packaging, and thus we have enormous overhead by using
487 ! calc_grid repeatedly to merely fill values of cell corner coordinates
488 ! and cell center values per dimension, per variable
489 if(ndim+nw+nwauxio>99) call mpistop("adjust format specification in writeout")
490 if(nw+nwauxio==1)then
491 ! to make tecplot happy: avoid [ndim+1-ndim+1] in varlocation varset
492 ! and just set [ndim+1]
493 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,a)") &
494 'ZONE T="',level,'"',', N=',nodesonlevel,', E=',elemsonlevel, &
495 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
496 ndim+1,']=CELLCENTERED), ZONETYPE=', &
497 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
498 else
499 if(ndim+nw+nwauxio<10) then
500 ! difference only in length of integer format specification for ndim+nw+nwauxio
501 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i1,a,a)") &
502 'ZONE T="',level,'"',', N=',nodesonlevel,', E=',elemsonlevel, &
503 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
504 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
505 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
506 else
507 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i2,a,a)") &
508 'ZONE T="',level,'"',', N=',nodesonlevel,', E=',elemsonlevel, &
509 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
510 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
511 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
512 end if
513 end if
514 do idim=1,ndim
515 first=(idim==1)
516 do iigrid=1,igridstail; igrid=igrids(iigrid);
517 if (node(plevel_,igrid)/=level) cycle
518 block=>ps(igrid)
519 call calc_x(igrid,xc,xcc)
520 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
521 ixc^l,ixcc^l,first)
522 write(qunit,fmt="(100(e14.6))") xc_tmp(ixc^s,idim)*normconv(0)
523 end do
524 end do
525 do iw=1,nw+nwauxio
526 do iigrid=1,igridstail; igrid=igrids(iigrid);
527 if (node(plevel_,igrid)/=level) cycle
528 block=>ps(igrid)
529 call calc_x(igrid,xc,xcc)
530 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
531 ixc^l,ixcc^l,.true.)
532 write(qunit,fmt="(100(e14.6))") wcc_tmp(ixcc^s,iw)*normconv(iw)
533 enddo
534 enddo
535 case default
536 call mpistop('no such tecplot type')
537 end select
538 igonlevel=0
539 do iigrid=1,igridstail; igrid=igrids(iigrid);
540 if (node(plevel_,igrid)/=level) cycle
541 block=>ps(igrid)
542 igonlevel=igonlevel+1
543 call save_conntec(qunit,igrid,igonlevel)
544 end do
545 end do
546 {^ifoned endif}
547
548 close(qunit)
549
550 end subroutine tecplot
551
552 subroutine save_conntec(qunit,igrid,igonlevel)
553
554 ! this saves the basic line, quad and brick connectivity,
555 ! as used by TECPLOT file outputs for unstructured grid
557
558 integer, intent(in) :: qunit, igrid, igonlevel
559
560 integer :: nx^D, nxC^D, ix^D
561
562 nx^d=ixmhi^d-ixmlo^d+1;
563 nxc^d=nx^d+1;
564
565 ! connectivity list
566 {do ix^db=1,nx^db\}
567 {^ifthreed
568 ! basic brick connectivity
569 write(qunit,'(8(i7,1x))') &
570 nodenumbertec3d(ix1, ix2-1,ix3-1,nxc1,nxc2,nxc3,igonlevel,igrid),&
571 nodenumbertec3d(ix1+1,ix2-1,ix3-1,nxc1,nxc2,nxc3,igonlevel,igrid),&
572 nodenumbertec3d(ix1+1,ix2 ,ix3-1,nxc1,nxc2,nxc3,igonlevel,igrid),&
573 nodenumbertec3d(ix1 ,ix2 ,ix3-1,nxc1,nxc2,nxc3,igonlevel,igrid),&
574 nodenumbertec3d(ix1 ,ix2-1,ix3 ,nxc1,nxc2,nxc3,igonlevel,igrid),&
575 nodenumbertec3d(ix1+1,ix2-1,ix3 ,nxc1,nxc2,nxc3,igonlevel,igrid),&
576 nodenumbertec3d(ix1+1,ix2 ,ix3 ,nxc1,nxc2,nxc3,igonlevel,igrid),&
577 nodenumbertec3d(ix1 ,ix2 ,ix3 ,nxc1,nxc2,nxc3,igonlevel,igrid)
578 }
579 {^iftwod
580 ! basic quadrilateral connectivity
581 write(qunit,'(4(i7,1x))') &
582 nodenumbertec2d(ix1, ix2-1,nxc1,nxc2,igonlevel,igrid),&
583 nodenumbertec2d(ix1+1,ix2-1,nxc1,nxc2,igonlevel,igrid),&
584 nodenumbertec2d(ix1+1,ix2 ,nxc1,nxc2,igonlevel,igrid),&
585 nodenumbertec2d(ix1 ,ix2 ,nxc1,nxc2,igonlevel,igrid)
586 }
587 {^ifoned
588 ! basic line connectivity
589 write(qunit,'(2(i7,1x))') nodenumbertec1d(ix1,nxc1,igonlevel,igrid),&
590 nodenumbertec1d(ix1+1,nxc1,igonlevel,igrid)
591 }
592 {end do\}
593
594 end subroutine save_conntec
595
596 integer function nodenumbertec1d(i1,nx1,ig,igrid)
597 use mod_comm_lib, only: mpistop
598 integer, intent(in):: i1,nx1,ig,igrid
599
600 nodenumbertec1d=i1+(ig-1)*nx1
601 if(nodenumbertec1d>9999999)call mpistop("too large nodenumber")
602
603 end function nodenumbertec1d
604
605 integer function nodenumbertec2d(i1,i2,nx1,nx2,ig,igrid)
606
607 integer, intent(in):: i1,i2,nx1,nx2,ig,igrid
608
609 nodenumbertec2d=i1+i2*nx1+(ig-1)*nx1*nx2
610 if(nodenumbertec2d>9999999)call mpistop("too large nodenumber")
611
612 end function nodenumbertec2d
613
614 integer function nodenumbertec3d(i1,i2,i3,nx1,nx2,nx3,ig,igrid)
615
616 integer, intent(in):: i1,i2,i3,nx1,nx2,nx3,ig,igrid
617
618 nodenumbertec3d=i1+i2*nx1+i3*nx1*nx2+(ig-1)*nx1*nx2*nx3
619 if(nodenumbertec3d>9999999)call mpistop("too large nodenumber")
620
621 end function nodenumbertec3d
622
623 subroutine unstructuredvtk(qunit)
624
625 ! output for vtu format to paraview
626 ! not parallel, uses calc_grid to compute nwauxio variables
627 ! allows renormalizing using convert factors
630
631 integer, intent(in) :: qunit
632
633 double precision :: x_VTK(1:3)
634 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
635 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
636 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
637 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
638 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP
639 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
640 double precision, dimension(0:nw+nwauxio) :: normconv
641 integer:: igrid,iigrid,level,igonlevel,icel,ixC^L,ixCC^L,iw
642 integer:: NumGridsOnLevel(1:nlevelshi)
643 integer :: nx^D,nxC^D,nodesonlevel,elemsonlevel,nc,np,VTK_type,ix^D
644 integer :: filenr
645 character(len=80):: filename
646 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
647 character(len=1024) :: outfilehead
648 logical :: fileopen
649
650 if(npe>1)then
651 if(mype==0) print *,'unstructuredvtk not parallel, use vtumpi'
652 call mpistop('npe>1, unstructuredvtk')
653 end if
654
655 inquire(qunit,opened=fileopen)
656 if(.not.fileopen)then
657 ! generate filename
658 filenr=snapshotini
659 if (autoconvert) filenr=snapshotnext
660 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".vtu"
661 ! Open the file for the header part
662 open(qunit,file=filename,status='unknown')
663 end if
664
665 call getheadernames(wnamei,xandwnamei,outfilehead)
666
667 ! generate xml header
668 write(qunit,'(a)')'<?xml version="1.0"?>'
669 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
670 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
671 write(qunit,'(a)')'<UnstructuredGrid>'
672 write(qunit,'(a)')'<FieldData>'
673 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
674 'NumberOfTuples="1" format="ascii">'
675 write(qunit,*) dble(dble(global_time)*time_convert_factor)
676 write(qunit,'(a)')'</DataArray>'
677 write(qunit,'(a)')'</FieldData>'
678
679 ! number of cells, number of corner points, per grid.
680 nx^d=ixmhi^d-ixmlo^d+1;
681 nxc^d=nx^d+1;
682 nc={nx^d*}
683 np={nxc^d*}
684
685 ! Note: using the w_write, writelevel, writespshift
686 ! we can clip parts of the grid away, select variables, levels etc.
687 do level=levmin,levmax
688 if (writelevel(level)) then
689 do iigrid=1,igridstail; igrid=igrids(iigrid);
690 if (node(plevel_,igrid)/=level) cycle
691 block=>ps(igrid)
692 ! only output a grid when fully within clipped region selected
693 ! by writespshift array
694 if(({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
695 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
696 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
697 call calc_x(igrid,xc,xcc)
698 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
699 ixc^l,ixcc^l,.true.)
700 select case(convert_type)
701 case('vtu')
702 ! we write out every grid as one VTK PIECE
703 write(qunit,'(a,i7,a,i7,a)') &
704 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
705 write(qunit,'(a)')'<PointData>'
706 do iw=1,nw+nwauxio
707 if(iw<=nw) then
708 if(.not.w_write(iw)) cycle
709 end if
710 write(qunit,'(a,a,a)')&
711 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
712 write(qunit,'(200(1pe14.6))') {(|}wc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixcmin^d,ixcmax^d)}
713 write(qunit,'(a)')'</DataArray>'
714 end do
715 write(qunit,'(a)')'</PointData>'
716 write(qunit,'(a)')'<Points>'
717 write(qunit,'(a)')'<DataArray type="Float32" NumberOfComponents="3" format="ascii">'
718 ! write cell corner coordinates in a backward dimensional loop, always 3D output
719 {do ix^db=ixcmin^db,ixcmax^db \}
720 x_vtk(1:3)=zero;
721 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
722 write(qunit,'(3(1pe14.6))') x_vtk
723 {end do \}
724 write(qunit,'(a)')'</DataArray>'
725 write(qunit,'(a)')'</Points>'
726 case('vtuCC')
727 ! we write out every grid as one VTK PIECE
728 write(qunit,'(a,i7,a,i7,a)') &
729 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
730 write(qunit,'(a)')'<CellData>'
731 do iw=1,nw+nwauxio
732 if(iw<=nw) then
733 if(.not.w_write(iw)) cycle
734 end if
735 write(qunit,'(a,a,a)')&
736 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
737 write(qunit,'(200(1pe14.6))') {(|}wcc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixccmin^d,ixccmax^d)}
738 write(qunit,'(a)')'</DataArray>'
739 end do
740 write(qunit,'(a)')'</CellData>'
741 write(qunit,'(a)')'<Points>'
742 write(qunit,'(a)')'<DataArray type="Float32" NumberOfComponents="3" format="ascii">'
743 ! write cell corner coordinates in a backward dimensional loop, always 3D output
744 {do ix^db=ixcmin^db,ixcmax^db \}
745 x_vtk(1:3)=zero;
746 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
747 write(qunit,'(3(1pe14.6))') x_vtk
748 {end do \}
749 write(qunit,'(a)')'</DataArray>'
750 write(qunit,'(a)')'</Points>'
751 end select
752
753 write(qunit,'(a)')'<Cells>'
754 ! connectivity part
755 write(qunit,'(a)')'<DataArray type="Int32" Name="connectivity" format="ascii">'
756 call save_connvtk(qunit,igrid)
757 write(qunit,'(a)')'</DataArray>'
758
759 ! offsets data array
760 write(qunit,'(a)')'<DataArray type="Int32" Name="offsets" format="ascii">'
761 do icel=1,nc
762 write(qunit,'(i7)') icel*(2**^nd)
763 end do
764 write(qunit,'(a)')'</DataArray>'
765
766 ! VTK cell type data array
767 write(qunit,'(a)')'<DataArray type="Int32" Name="types" format="ascii">'
768 vtk_type=vtk_cell_type()
769 do icel=1,nc
770 write(qunit,'(i2)') vtk_type
771 end do
772 write(qunit,'(a)')'</DataArray>'
773
774 write(qunit,'(a)')'</Cells>'
775
776 write(qunit,'(a)')'</Piece>'
777 end if
778 end do
779 end if
780 end do
781
782 write(qunit,'(a)')'</UnstructuredGrid>'
783 write(qunit,'(a)')'</VTKFile>'
784 close(qunit)
785
786 end subroutine unstructuredvtk
787
788 subroutine unstructuredvtkb(qunit)
789
790 ! output for vtu format to paraview, binary version output
791 ! not parallel, uses calc_grid to compute nwauxio variables
792 ! allows renormalizing using convert factors
796
797 integer, intent(in) :: qunit
798
799 double precision :: x_VTK(1:3)
800 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
801 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
802 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
803 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
804 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio):: wC_TMP
805 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
806 double precision :: normconv(0:nw+nwauxio)
807 integer, allocatable :: intstatus(:,:)
808 integer*8 :: offset
809 integer :: itag,ipe,igrid,level,icel,ixC^L,ixCC^L,Morton_no,Morton_length
810 integer :: nx^D,nxC^D,nc,np,VTK_type,ix^D,filenr
811 integer:: k,iw
812 integer:: length,lengthcc,length_coords,length_conn,length_offsets
813 character:: buf
814 character(len=80):: filename
815 character(len=19):: offset_char
816 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
817 character(len=1024) :: outfilehead
818 logical :: fileopen,cell_corner=.false.
819 logical, allocatable :: Morton_aim(:),Morton_aim_p(:)
820
821 normconv=one
822 morton_length=morton_stop(npe-1)-morton_start(0)+1
823 allocate(morton_aim(morton_start(0):morton_stop(npe-1)))
824 allocate(morton_aim_p(morton_start(0):morton_stop(npe-1)))
825 morton_aim=.false.
826 morton_aim_p=.false.
827 do morton_no=morton_start(mype),morton_stop(mype)
828 igrid=sfc_to_igrid(morton_no)
829 level=node(plevel_,igrid)
830 ! we can clip parts of the grid away, select variables, levels etc.
831 if(writelevel(level)) then
832 ! only output a grid when fully within clipped region selected
833 ! by writespshift array
834 if(({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
835 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
836 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
837 morton_aim_p(morton_no)=.true.
838 end if
839 end if
840 end do
841 call mpi_allreduce(morton_aim_p,morton_aim,morton_length,mpi_logical,mpi_lor,&
843 select case(convert_type)
844 case('vtuB','vtuBmpi')
845 cell_corner=.true.
846 case('vtuBCC','vtuBCCmpi')
847 cell_corner=.false.
848 end select
849 if (mype /= 0) then
850 do morton_no=morton_start(mype),morton_stop(mype)
851 if(.not. morton_aim(morton_no)) cycle
852 igrid=sfc_to_igrid(morton_no)
853 call calc_x(igrid,xc,xcc)
854 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
855 ixc^l,ixcc^l,.true.)
856 itag=morton_no
857 call mpi_send(xc_tmp,1,type_block_xc_io, 0,itag,icomm,ierrmpi)
858 if(cell_corner) then
859 call mpi_send(wc_tmp,1,type_block_wc_io, 0,itag,icomm,ierrmpi)
860 else
861 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
862 end if
863 end do
864
865 else
866 ! mype==0
867 offset=0
868 inquire(qunit,opened=fileopen)
869 if(.not.fileopen)then
870 ! generate filename
871 filenr=snapshotini
872 if (autoconvert) filenr=snapshotnext
873 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".vtu"
874 ! Open the file for the header part
875 open(qunit,file=filename,status='replace')
876 end if
877 call getheadernames(wnamei,xandwnamei,outfilehead)
878 ! generate xml header
879 write(qunit,'(a)')'<?xml version="1.0"?>'
880 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
881 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
882 write(qunit,'(a)')'<UnstructuredGrid>'
883 write(qunit,'(a)')'<FieldData>'
884 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
885 'NumberOfTuples="1" format="ascii">'
886 write(qunit,*) real(global_time*time_convert_factor)
887 write(qunit,'(a)')'</DataArray>'
888 write(qunit,'(a)')'</FieldData>'
889
890 ! number of cells, number of corner points, per grid.
891 nx^d=ixmhi^d-ixmlo^d+1;
892 nxc^d=nx^d+1;
893 nc={nx^d*}
894 np={nxc^d*}
895 length=np*size_real
896 lengthcc=nc*size_real
897 length_coords=3*length
898 length_conn=2**^nd*size_int*nc
899 length_offsets=nc*size_int
900
901 ! Note: using the w_write, writelevel, writespshift
902 do morton_no=morton_start(0),morton_stop(0)
903 if(.not. morton_aim(morton_no)) cycle
904 if(cell_corner) then
905 ! we write out every grid as one VTK PIECE
906 write(qunit,'(a,i7,a,i7,a)') &
907 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
908 write(qunit,'(a)')'<PointData>'
909 do iw=1,nw+nwauxio
910 if(iw<=nw) then
911 if(.not.w_write(iw)) cycle
912 endif
913 write(offset_char,'(i19)') offset
914 write(qunit,'(a,a,a,a,a)')&
915 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
916 '" format="appended" offset="',trim(adjustl(offset_char)),'">'
917 write(qunit,'(a)')'</DataArray>'
918 offset=offset+length+size_int
919 end do
920 write(qunit,'(a)')'</PointData>'
921 write(qunit,'(a)')'<Points>'
922 write(offset_char,'(i19)') offset
923 write(qunit,'(a,a,a)') &
924 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
925 ! write cell corner coordinates in a backward dimensional loop, always 3D output
926 offset=offset+length_coords+size_int
927 write(qunit,'(a)')'</Points>'
928 else
929 ! we write out every grid as one VTK PIECE
930 write(qunit,'(a,i7,a,i7,a)') &
931 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
932 write(qunit,'(a)')'<CellData>'
933 do iw=1,nw+nwauxio
934 if(iw<=nw) then
935 if(.not.w_write(iw)) cycle
936 end if
937 write(offset_char,'(i19)') offset
938 write(qunit,'(a,a,a,a,a)')&
939 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
940 '" format="appended" offset="',trim(adjustl(offset_char)),'">'
941 write(qunit,'(a)')'</DataArray>'
942 offset=offset+lengthcc+size_int
943 end do
944 write(qunit,'(a)')'</CellData>'
945 write(qunit,'(a)')'<Points>'
946 write(offset_char,'(i19)') offset
947 write(qunit,'(a,a,a)') &
948 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
949 ! write cell corner coordinates in a backward dimensional loop, always 3D output
950 offset=offset+length_coords+size_int
951 write(qunit,'(a)')'</Points>'
952 end if
953 write(qunit,'(a)')'<Cells>'
954 ! connectivity part
955 write(offset_char,'(i19)') offset
956 write(qunit,'(a,a,a)')&
957 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
958 offset=offset+length_conn+size_int
959 ! offsets data array
960 write(offset_char,'(i19)') offset
961 write(qunit,'(a,a,a)') &
962 '<DataArray type="Int32" Name="offsets" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
963 offset=offset+length_offsets+size_int
964 ! VTK cell type data array
965 write(offset_char,'(i19)') offset
966 write(qunit,'(a,a,a)') &
967 '<DataArray type="Int32" Name="types" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
968 offset=offset+size_int+nc*size_int
969 write(qunit,'(a)')'</Cells>'
970 write(qunit,'(a)')'</Piece>'
971 end do
972 ! write metadata communicated from other processors
973 if(npe>1)then
974 do ipe=1, npe-1
975 do morton_no=morton_start(ipe),morton_stop(ipe)
976 if(.not. morton_aim(morton_no)) cycle
977 if(cell_corner) then
978 ! we write out every grid as one VTK PIECE
979 write(qunit,'(a,i7,a,i7,a)') &
980 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
981 write(qunit,'(a)')'<PointData>'
982 do iw=1,nw+nwauxio
983 if(iw<=nw) then
984 if(.not.w_write(iw)) cycle
985 end if
986 write(offset_char,'(i19)') offset
987 write(qunit,'(a,a,a,a,a)')&
988 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
989 '" format="appended" offset="',trim(adjustl(offset_char)),'">'
990 write(qunit,'(a)')'</DataArray>'
991 offset=offset+length+size_int
992 end do
993 write(qunit,'(a)')'</PointData>'
994 write(qunit,'(a)')'<Points>'
995 write(offset_char,'(i19)') offset
996 write(qunit,'(a,a,a)') &
997 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
998 ! write cell corner coordinates in a backward dimensional loop, always 3D output
999 offset=offset+length_coords+size_int
1000 write(qunit,'(a)')'</Points>'
1001 else
1002 ! we write out every grid as one VTK PIECE
1003 write(qunit,'(a,i7,a,i7,a)') &
1004 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
1005 write(qunit,'(a)')'<CellData>'
1006 do iw=1,nw+nwauxio
1007 if(iw<=nw) then
1008 if(.not.w_write(iw)) cycle
1009 end if
1010 write(offset_char,'(i19)') offset
1011 write(qunit,'(a,a,a,a,a)')&
1012 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
1013 '" format="appended" offset="',trim(adjustl(offset_char)),'">'
1014 write(qunit,'(a)')'</DataArray>'
1015 offset=offset+lengthcc+size_int
1016 end do
1017 write(qunit,'(a)')'</CellData>'
1018 write(qunit,'(a)')'<Points>'
1019 write(offset_char,'(i19)') offset
1020 write(qunit,'(a,a,a)') &
1021 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
1022 ! write cell corner coordinates in a backward dimensional loop, always 3D output
1023 offset=offset+length_coords+size_int
1024 write(qunit,'(a)')'</Points>'
1025 end if
1026 write(qunit,'(a)')'<Cells>'
1027 ! connectivity part
1028 write(offset_char,'(i19)') offset
1029 write(qunit,'(a,a,a)')&
1030 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
1031 offset=offset+length_conn+size_int
1032 ! offsets data array
1033 write(offset_char,'(i19)') offset
1034 write(qunit,'(a,a,a)') &
1035 '<DataArray type="Int32" Name="offsets" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
1036 offset=offset+length_offsets+size_int
1037 ! VTK cell type data array
1038 write(offset_char,'(i19)') offset
1039 write(qunit,'(a,a,a)') &
1040 '<DataArray type="Int32" Name="types" format="appended" offset="',trim(adjustl(offset_char)),'"/>'
1041 offset=offset+size_int+nc*size_int
1042 write(qunit,'(a)')'</Cells>'
1043 write(qunit,'(a)')'</Piece>'
1044 end do
1045 end do
1046 end if
1047
1048 write(qunit,'(a)')'</UnstructuredGrid>'
1049 write(qunit,'(a)')'<AppendedData encoding="raw">'
1050 close(qunit)
1051 open(qunit,file=filename,access='stream',form='unformatted',position='append')
1052 buf='_'
1053 write(qunit) trim(buf)
1054
1055 do morton_no=morton_start(0),morton_stop(0)
1056 if(.not. morton_aim(morton_no)) cycle
1057 igrid=sfc_to_igrid(morton_no)
1058 call calc_x(igrid,xc,xcc)
1059 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1060 ixc^l,ixcc^l,.true.)
1061 do iw=1,nw+nwauxio
1062 if(iw<=nw) then
1063 if(.not.w_write(iw)) cycle
1064 end if
1065 if(cell_corner) then
1066 write(qunit) length
1067 write(qunit) {(|}real(wc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixcmin^d,ixcmax^d)}
1068 else
1069 write(qunit) lengthcc
1070 write(qunit) {(|}real(wcc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixccmin^d,ixccmax^d)}
1071 end if
1072 end do
1073
1074 write(qunit) length_coords
1075 {do ix^db=ixcmin^db,ixcmax^db \}
1076 x_vtk(1:3)=zero;
1077 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
1078 do k=1,3
1079 write(qunit) real(x_vtk(k))
1080 end do
1081 {end do \}
1082
1083 write(qunit) length_conn
1084 call write_connvtk_binary(qunit)
1085
1086 write(qunit) length_offsets
1087 do icel=1,nc
1088 write(qunit) icel*(2**^nd)
1089 end do
1090
1091 vtk_type=vtk_cell_type()
1092 write(qunit) size_int*nc
1093 do icel=1,nc
1094 write(qunit) vtk_type
1095 end do
1096 end do
1097 allocate(intstatus(mpi_status_size,1))
1098 if(npe>1)then
1099 ixccmin^d=ixmlo^d; ixccmax^d=ixmhi^d;
1100 ixcmin^d=ixmlo^d-1; ixcmax^d=ixmhi^d;
1101 do ipe=1, npe-1
1102 do morton_no=morton_start(ipe),morton_stop(ipe)
1103 if(.not. morton_aim(morton_no)) cycle
1104 itag=morton_no
1105 call mpi_recv(xc_tmp,1,type_block_xc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1106 if(cell_corner) then
1107 call mpi_recv(wc_tmp,1,type_block_wc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1108 else
1109 call mpi_recv(wcc_tmp,1,type_block_wcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1110 end if
1111 do iw=1,nw+nwauxio
1112 if(iw<=nw) then
1113 if(.not.w_write(iw)) cycle
1114 end if
1115 if(cell_corner) then
1116 write(qunit) length
1117 write(qunit) {(|}real(wc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixcmin^d,ixcmax^d)}
1118 else
1119 write(qunit) lengthcc
1120 write(qunit) {(|}real(wcc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixccmin^d,ixccmax^d)}
1121 end if
1122 end do
1123 write(qunit) length_coords
1124 {do ix^db=ixcmin^db,ixcmax^db \}
1125 x_vtk(1:3)=zero;
1126 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
1127 do k=1,3
1128 write(qunit) real(x_vtk(k))
1129 end do
1130 {end do \}
1131 write(qunit) length_conn
1132 call write_connvtk_binary(qunit)
1133 write(qunit) length_offsets
1134 do icel=1,nc
1135 write(qunit) icel*(2**^nd)
1136 end do
1137 vtk_type=vtk_cell_type()
1138 write(qunit) size_int*nc
1139 do icel=1,nc
1140 write(qunit) vtk_type
1141 end do
1142 end do
1143 end do
1144 end if
1145 close(qunit)
1146 open(qunit,file=filename,status='unknown',form='formatted',position='append')
1147 write(qunit,'(a)')'</AppendedData>'
1148 write(qunit,'(a)')'</VTKFile>'
1149 close(qunit)
1150 deallocate(intstatus)
1151 end if
1152
1153 deallocate(morton_aim,morton_aim_p)
1154 if (npe>1) then
1155 call mpi_barrier(icomm,ierrmpi)
1156 end if
1157
1158 end subroutine unstructuredvtkb
1159
1160 subroutine unstructuredvtkb64(qunit)
1161 ! output for vtu format to paraview, binary version output
1162 ! not parallel, uses calc_grid to compute nwauxio variables
1163 ! allows renormalizing using convert factors
1167
1168 integer, intent(in) :: qunit
1169
1170 double precision :: x_VTK(1:3)
1171 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
1172 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
1173 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
1174 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
1175 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio):: wC_TMP
1176 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
1177 double precision :: normconv(0:nw+nwauxio)
1178 integer, allocatable :: intstatus(:,:)
1179 integer*8 :: offset
1180 integer :: itag,ipe,igrid,level,icel,ixC^L,ixCC^L,Morton_no,Morton_length
1181 integer :: nx^D,nxC^D,nc,np,VTK_type,ix^D,filenr
1182 integer:: k,iw
1183 integer:: length,lengthcc,length_coords,length_conn,length_offsets
1184 character:: buf
1185 character(len=80):: filename
1186 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
1187 character(len=1024) :: outfilehead
1188 logical :: fileopen,cell_corner=.false.
1189 logical, allocatable :: Morton_aim(:),Morton_aim_p(:)
1190
1191 normconv=one
1192 morton_length=morton_stop(npe-1)-morton_start(0)+1
1193 allocate(morton_aim(morton_start(0):morton_stop(npe-1)))
1194 allocate(morton_aim_p(morton_start(0):morton_stop(npe-1)))
1195 morton_aim=.false.
1196 morton_aim_p=.false.
1197 do morton_no=morton_start(mype),morton_stop(mype)
1198 igrid=sfc_to_igrid(morton_no)
1199 level=node(plevel_,igrid)
1200 ! we can clip parts of the grid away, select variables, levels etc.
1201 if(writelevel(level)) then
1202 ! only output a grid when fully within clipped region selected
1203 ! by writespshift array
1204 if(({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
1205 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
1206 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
1207 morton_aim_p(morton_no)=.true.
1208 end if
1209 end if
1210 end do
1211 call mpi_allreduce(morton_aim_p,morton_aim,morton_length,mpi_logical,mpi_lor,&
1212 icomm,ierrmpi)
1213 select case(convert_type)
1214 case('vtuB64','vtuBmpi64')
1215 cell_corner=.true.
1216 case('vtuBCC64','vtuBCCmpi64')
1217 cell_corner=.false.
1218 end select
1219 if (mype /= 0) then
1220 do morton_no=morton_start(mype),morton_stop(mype)
1221 if(.not. morton_aim(morton_no)) cycle
1222 igrid=sfc_to_igrid(morton_no)
1223 call calc_x(igrid,xc,xcc)
1224 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1225 ixc^l,ixcc^l,.true.)
1226 itag=morton_no
1227 call mpi_send(xc_tmp,1,type_block_xc_io, 0,itag,icomm,ierrmpi)
1228 if(cell_corner) then
1229 call mpi_send(wc_tmp,1,type_block_wc_io, 0,itag,icomm,ierrmpi)
1230 else
1231 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
1232 end if
1233 end do
1234 else
1235 ! mype==0
1236 offset=0
1237 inquire(qunit,opened=fileopen)
1238 if(.not.fileopen)then
1239 ! generate filename
1240 filenr=snapshotini
1241 if (autoconvert) filenr=snapshotnext
1242 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".vtu"
1243 ! Open the file for the header part
1244 open(qunit,file=filename,status='replace')
1245 end if
1246 call getheadernames(wnamei,xandwnamei,outfilehead)
1247 ! generate xml header
1248 write(qunit,'(a)')'<?xml version="1.0"?>'
1249 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
1250 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
1251 write(qunit,'(a)')'<UnstructuredGrid>'
1252 write(qunit,'(a)')'<FieldData>'
1253 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
1254 'NumberOfTuples="1" format="ascii">'
1255 write(qunit,*) real(global_time*time_convert_factor)
1256 write(qunit,'(a)')'</DataArray>'
1257 write(qunit,'(a)')'</FieldData>'
1258 ! number of cells, number of corner points, per grid.
1259 nx^d=ixmhi^d-ixmlo^d+1;
1260 nxc^d=nx^d+1;
1261 nc={nx^d*}
1262 np={nxc^d*}
1263 length=np*size_double
1264 lengthcc=nc*size_double
1265 length_coords=3*length
1266 length_conn=2**^nd*size_int*nc
1267 length_offsets=nc*size_int
1268 ! Note: using the w_write, writelevel, writespshift
1269 do morton_no=morton_start(0),morton_stop(0)
1270 if(.not. morton_aim(morton_no)) cycle
1271 if(cell_corner) then
1272 ! we write out every grid as one VTK PIECE
1273 write(qunit,'(a,i7,a,i7,a)') &
1274 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
1275 write(qunit,'(a)')'<PointData>'
1276 do iw=1,nw+nwauxio
1277 if(iw<=nw) then
1278 if(.not.w_write(iw)) cycle
1279 end if
1280 write(qunit,'(a,a,a,i16,a)')&
1281 '<DataArray type="Float64" Name="',trim(wnamei(iw)), &
1282 '" format="appended" offset="',offset,'">'
1283 write(qunit,'(a)')'</DataArray>'
1284 offset=offset+length+size_int
1285 end do
1286 write(qunit,'(a)')'</PointData>'
1287 write(qunit,'(a)')'<Points>'
1288 write(qunit,'(a,i16,a)') &
1289 '<DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
1290 ! write cell corner coordinates in a backward dimensional loop, always 3D output
1291 offset=offset+length_coords+size_int
1292 write(qunit,'(a)')'</Points>'
1293 else
1294 ! we write out every grid as one VTK PIECE
1295 write(qunit,'(a,i7,a,i7,a)') &
1296 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
1297 write(qunit,'(a)')'<CellData>'
1298 do iw=1,nw+nwauxio
1299 if(iw<=nw) then
1300 if(.not.w_write(iw)) cycle
1301 end if
1302 write(qunit,'(a,a,a,i16,a)')&
1303 '<DataArray type="Float64" Name="',trim(wnamei(iw)), &
1304 '" format="appended" offset="',offset,'">'
1305 write(qunit,'(a)')'</DataArray>'
1306 offset=offset+lengthcc+size_int
1307 end do
1308 write(qunit,'(a)')'</CellData>'
1309 write(qunit,'(a)')'<Points>'
1310 write(qunit,'(a,i16,a)') &
1311 '<DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
1312 ! write cell corner coordinates in a backward dimensional loop, always 3D output
1313 offset=offset+length_coords+size_int
1314 write(qunit,'(a)')'</Points>'
1315 end if
1316 write(qunit,'(a)')'<Cells>'
1317 ! connectivity part
1318 write(qunit,'(a,i16,a)')&
1319 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',offset,'"/>'
1320 offset=offset+length_conn+size_int
1321 ! offsets data array
1322 write(qunit,'(a,i16,a)') &
1323 '<DataArray type="Int32" Name="offsets" format="appended" offset="',offset,'"/>'
1324 offset=offset+length_offsets+size_int
1325 ! VTK cell type data array
1326 write(qunit,'(a,i16,a)') &
1327 '<DataArray type="Int32" Name="types" format="appended" offset="',offset,'"/>'
1328 offset=offset+size_int+nc*size_int
1329 write(qunit,'(a)')'</Cells>'
1330 write(qunit,'(a)')'</Piece>'
1331 end do
1332 ! write metadata communicated from other processors
1333 if(npe>1)then
1334 do ipe=1, npe-1
1335 do morton_no=morton_start(ipe),morton_stop(ipe)
1336 if(.not. morton_aim(morton_no)) cycle
1337 if(cell_corner) then
1338 ! we write out every grid as one VTK PIECE
1339 write(qunit,'(a,i7,a,i7,a)') &
1340 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
1341 write(qunit,'(a)')'<PointData>'
1342 do iw=1,nw+nwauxio
1343 if(iw<=nw) then
1344 if(.not.w_write(iw)) cycle
1345 end if
1346 write(qunit,'(a,a,a,i16,a)')&
1347 '<DataArray type="Float64" Name="',trim(wnamei(iw)), &
1348 '" format="appended" offset="',offset,'">'
1349 write(qunit,'(a)')'</DataArray>'
1350 offset=offset+length+size_int
1351 end do
1352 write(qunit,'(a)')'</PointData>'
1353 write(qunit,'(a)')'<Points>'
1354 write(qunit,'(a,i16,a)') &
1355 '<DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
1356 ! write cell corner coordinates in a backward dimensional loop, always 3D output
1357 offset=offset+length_coords+size_int
1358 write(qunit,'(a)')'</Points>'
1359 else
1360 ! we write out every grid as one VTK PIECE
1361 write(qunit,'(a,i7,a,i7,a)') &
1362 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
1363 write(qunit,'(a)')'<CellData>'
1364 do iw=1,nw+nwauxio
1365 if(iw<=nw) then
1366 if(.not.w_write(iw)) cycle
1367 end if
1368 write(qunit,'(a,a,a,i16,a)')&
1369 '<DataArray type="Float64" Name="',trim(wnamei(iw)), &
1370 '" format="appended" offset="',offset,'">'
1371 write(qunit,'(a)')'</DataArray>'
1372 offset=offset+lengthcc+size_int
1373 end do
1374 write(qunit,'(a)')'</CellData>'
1375 write(qunit,'(a)')'<Points>'
1376 write(qunit,'(a,i16,a)') &
1377 '<DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
1378 ! write cell corner coordinates in a backward dimensional loop, always 3D output
1379 offset=offset+length_coords+size_int
1380 write(qunit,'(a)')'</Points>'
1381 end if
1382 write(qunit,'(a)')'<Cells>'
1383 ! connectivity part
1384 write(qunit,'(a,i16,a)')&
1385 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',offset,'"/>'
1386 offset=offset+length_conn+size_int
1387 ! offsets data array
1388 write(qunit,'(a,i16,a)') &
1389 '<DataArray type="Int32" Name="offsets" format="appended" offset="',offset,'"/>'
1390 offset=offset+length_offsets+size_int
1391 ! VTK cell type data array
1392 write(qunit,'(a,i16,a)') &
1393 '<DataArray type="Int32" Name="types" format="appended" offset="',offset,'"/>'
1394 offset=offset+size_int+nc*size_int
1395 write(qunit,'(a)')'</Cells>'
1396 write(qunit,'(a)')'</Piece>'
1397 end do
1398 end do
1399 end if
1400 write(qunit,'(a)')'</UnstructuredGrid>'
1401 write(qunit,'(a)')'<AppendedData encoding="raw">'
1402 close(qunit)
1403 open(qunit,file=filename,access='stream',form='unformatted',position='append')
1404 buf='_'
1405 write(qunit) trim(buf)
1406 do morton_no=morton_start(0),morton_stop(0)
1407 if(.not. morton_aim(morton_no)) cycle
1408 igrid=sfc_to_igrid(morton_no)
1409 call calc_x(igrid,xc,xcc)
1410 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1411 ixc^l,ixcc^l,.true.)
1412 do iw=1,nw+nwauxio
1413 if(iw<=nw) then
1414 if(.not.w_write(iw)) cycle
1415 end if
1416 if(cell_corner) then
1417 write(qunit) length
1418 write(qunit) {(|}wc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixcmin^d,ixcmax^d)}
1419 else
1420 write(qunit) lengthcc
1421 write(qunit) {(|}wcc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixccmin^d,ixccmax^d)}
1422 end if
1423 end do
1424 write(qunit) length_coords
1425 {do ix^db=ixcmin^db,ixcmax^db \}
1426 x_vtk(1:3)=zero;
1427 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
1428 do k=1,3
1429 write(qunit) x_vtk(k)
1430 end do
1431 {end do \}
1432 write(qunit) length_conn
1433 call write_connvtk_binary(qunit)
1434 write(qunit) length_offsets
1435 do icel=1,nc
1436 write(qunit) icel*(2**^nd)
1437 end do
1438 vtk_type=vtk_cell_type()
1439 write(qunit) size_int*nc
1440 do icel=1,nc
1441 write(qunit) vtk_type
1442 end do
1443 end do
1444 allocate(intstatus(mpi_status_size,1))
1445 if(npe>1)then
1446 ixccmin^d=ixmlo^d; ixccmax^d=ixmhi^d;
1447 ixcmin^d=ixmlo^d-1; ixcmax^d=ixmhi^d;
1448 do ipe=1, npe-1
1449 do morton_no=morton_start(ipe),morton_stop(ipe)
1450 if(.not. morton_aim(morton_no)) cycle
1451 itag=morton_no
1452 call mpi_recv(xc_tmp,1,type_block_xc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1453 if(cell_corner) then
1454 call mpi_recv(wc_tmp,1,type_block_wc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1455 else
1456 call mpi_recv(wcc_tmp,1,type_block_wcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1457 end if
1458 do iw=1,nw+nwauxio
1459 if(iw<=nw) then
1460 if(.not.w_write(iw)) cycle
1461 end if
1462 if(cell_corner) then
1463 write(qunit) length
1464 write(qunit) {(|}wc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixcmin^d,ixcmax^d)}
1465 else
1466 write(qunit) lengthcc
1467 write(qunit) {(|}wcc_tmp(ix^d,iw)*normconv(iw),{ix^d=ixccmin^d,ixccmax^d)}
1468 end if
1469 end do
1470 write(qunit) length_coords
1471 {do ix^db=ixcmin^db,ixcmax^db \}
1472 x_vtk(1:3)=zero;
1473 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
1474 do k=1,3
1475 write(qunit) x_vtk(k)
1476 end do
1477 {end do \}
1478 write(qunit) length_conn
1479 call write_connvtk_binary(qunit)
1480 write(qunit) length_offsets
1481 do icel=1,nc
1482 write(qunit) icel*(2**^nd)
1483 end do
1484 vtk_type=vtk_cell_type()
1485 write(qunit) size_int*nc
1486 do icel=1,nc
1487 write(qunit) vtk_type
1488 end do
1489 end do
1490 end do
1491 end if
1492 close(qunit)
1493 open(qunit,file=filename,status='unknown',form='formatted',position='append')
1494 write(qunit,'(a)')'</AppendedData>'
1495 write(qunit,'(a)')'</VTKFile>'
1496 close(qunit)
1497 deallocate(intstatus)
1498 end if
1499 deallocate(morton_aim,morton_aim_p)
1500 if (npe>1) then
1501 call mpi_barrier(icomm,ierrmpi)
1502 end if
1503
1504 end subroutine unstructuredvtkb64
1505
1506 subroutine save_connvtk(qunit,igrid)
1507 ! this saves the basic line, pixel and voxel connectivity,
1508 ! as used by VTK file outputs for unstructured grid
1511
1512 integer, intent(in) :: qunit, igrid
1513
1514 integer :: nx^D, nxC^D, ix^D
1515 logical :: transformed_coordinates
1516
1517 nx^d=ixmhi^d-ixmlo^d+1;
1518 nxc^d=nx^d+1;
1519 transformed_coordinates=vtk_coordinates_transformed()
1520 {do ix^db=1,nx^db\}
1521 {^ifoned write(qunit,'(2(i7,1x))')ix1-1,ix1 \}
1522 {^iftwod
1523 if(transformed_coordinates) then
1524 write(qunit,'(4(i7,1x))')(ix2-1)*nxc1+ix1-1, &
1525 (ix2-1)*nxc1+ix1,ix2*nxc1+ix1,ix2*nxc1+ix1-1
1526 else
1527 write(qunit,'(4(i7,1x))')(ix2-1)*nxc1+ix1-1, &
1528 (ix2-1)*nxc1+ix1,ix2*nxc1+ix1-1,ix2*nxc1+ix1
1529 end if
1530 \}
1531 {^ifthreed
1532 if(transformed_coordinates) then
1533 write(qunit,'(8(i7,1x))')&
1534 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
1535 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1536 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
1537 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1538 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
1539 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1540 ix3*nxc2*nxc1+ ix2*nxc1+ix1,&
1541 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1
1542 else
1543 write(qunit,'(8(i7,1x))')&
1544 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
1545 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1546 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1547 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
1548 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
1549 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1550 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1551 ix3*nxc2*nxc1+ ix2*nxc1+ix1
1552 end if
1553 \}
1554 {end do\}
1555
1556 end subroutine save_connvtk
1557
1558 integer function vtk_cell_type()
1559 logical :: transformed_coordinates
1560
1561 transformed_coordinates=vtk_coordinates_transformed()
1562 {^ifoned vtk_cell_type=3 \} !VTK_LINE
1563 {^iftwod
1564 if(transformed_coordinates) then
1565 vtk_cell_type=9 !VTK_QUAD
1566 else
1567 vtk_cell_type=8 !VTK_PIXEL
1568 end if
1569 \}
1570 {^ifthreed
1571 if(transformed_coordinates) then
1572 vtk_cell_type=12 !VTK_HEXAHEDRON
1573 else
1574 vtk_cell_type=11 !VTK_VOXEL
1575 end if
1576 \}
1577 end function vtk_cell_type
1578
1583
1585 if (nocartesian) return
1586
1587 select case(coordinate)
1588 case(cylindrical)
1589 vtk_coordinates_transformed=(ndim==3) .or. (ndim==2 .and. phi_==2)
1590 case(spherical)
1594 end select
1595 end function vtk_coordinates_transformed
1596
1597 subroutine write_connvtk_binary(qunit)
1600
1601 integer, intent(in) :: qunit
1602 integer :: nx^D, nxC^D, ix^D
1603 logical :: transformed_coordinates
1604
1605 nx^d=ixmhi^d-ixmlo^d+1;
1606 nxc^d=nx^d+1;
1607 transformed_coordinates=vtk_coordinates_transformed()
1608 {do ix^db=1,nx^db\}
1609 {^ifoned write(qunit)ix1-1,ix1 \}
1610 {^iftwod
1611 if(transformed_coordinates) then
1612 write(qunit)(ix2-1)*nxc1+ix1-1, &
1613 (ix2-1)*nxc1+ix1,ix2*nxc1+ix1,ix2*nxc1+ix1-1
1614 else
1615 write(qunit)(ix2-1)*nxc1+ix1-1, &
1616 (ix2-1)*nxc1+ix1,ix2*nxc1+ix1-1,ix2*nxc1+ix1
1617 end if
1618 \}
1619 {^ifthreed
1620 if(transformed_coordinates) then
1621 write(qunit)&
1622 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
1623 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1624 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
1625 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1626 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
1627 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1628 ix3*nxc2*nxc1+ ix2*nxc1+ix1,&
1629 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1
1630 else
1631 write(qunit)&
1632 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
1633 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1634 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1635 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
1636 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
1637 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
1638 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
1639 ix3*nxc2*nxc1+ ix2*nxc1+ix1
1640 end if
1641 \}
1642 {end do\}
1643 end subroutine write_connvtk_binary
1644
1645 subroutine imagedatavtk_mpi(qunit)
1646 ! output for vti format to paraview, non-binary version output
1647 ! parallel, uses calc_grid to compute nwauxio variables
1648 ! allows renormalizing using convert factors
1649 ! allows skipping of w_write selected variables
1650 ! implementation such that length of ASCII output is identical when
1651 ! run on 1 versus multiple CPUs (however, the order of the vtu pieces can differ)
1655
1656 integer, intent(in) :: qunit
1657
1658 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP,xC_TMP_recv
1659 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP,xCC_TMP_recv
1660 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
1661 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
1662 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP,wC_TMP_recv
1663 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP,wCC_TMP_recv
1664 double precision, dimension(0:nw+nwauxio) :: normconv
1665 double precision :: origin(1:3), spacing(1:3)
1666 integer :: igrid,iigrid,level,ixC^L,ixCC^L
1667 integer :: NumGridsOnLevel(1:nlevelshi)
1668 integer :: nx^D
1669 integer :: filenr
1670 integer :: itag,ipe,Morton_no,Morton_length
1671 integer :: ixrvC^L, ixrvCC^L, siz_ind, ind_send(5*^ND), ind_recv(5*^ND)
1672 integer :: wholeExtent(1:6), ig^D
1673 integer, allocatable :: intstatus(:,:)
1674 logical, allocatable :: Morton_aim(:),Morton_aim_p(:)
1675 logical :: fileopen
1676 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
1677 character(len=1024) :: outfilehead
1678 character(len=80):: filename
1679 type(tree_node_ptr) :: tree
1680
1681 if(levmin/=levmax) call mpistop('ImageData can only be used when levmin=levmax')
1682 normconv(0) = length_convert_factor
1683 normconv(1:nw) = w_convert_factor
1684 siz_ind=5*^nd
1685 morton_length=morton_stop(npe-1)-morton_start(0)+1
1686 allocate(morton_aim(morton_start(0):morton_stop(npe-1)))
1687 allocate(morton_aim_p(morton_start(0):morton_stop(npe-1)))
1688 morton_aim=.false.
1689 morton_aim_p=.false.
1690 do morton_no=morton_start(mype),morton_stop(mype)
1691 igrid=sfc_to_igrid(morton_no)
1692 level=node(plevel_,igrid)
1693 ! we can clip parts of the grid away, select variables, levels etc.
1694 if(writelevel(level)) then
1695 ! only output a grid when fully within clipped region selected
1696 ! by writespshift array
1697 if(({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
1698 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
1699 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
1700 morton_aim_p(morton_no)=.true.
1701 end if
1702 end if
1703 end do
1704 call mpi_allreduce(morton_aim_p,morton_aim,morton_length,mpi_logical,mpi_lor,&
1705 icomm,ierrmpi)
1706 if(mype /= 0) then
1707 do morton_no=morton_start(mype),morton_stop(mype)
1708 if(.not. morton_aim(morton_no)) cycle
1709 igrid=sfc_to_igrid(morton_no)
1710 call calc_x(igrid,xc,xcc)
1711 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1712 ixc^l,ixcc^l,.true.)
1713 tree%node => igrid_to_node(igrid, mype)%node
1714 {^d& ig^d = tree%node%ig^d; }
1715 itag=morton_no
1716 ind_send=(/ ixc^l,ixcc^l, ig^d /)
1717 call mpi_send(ind_send,siz_ind,mpi_integer, 0,itag,icomm,ierrmpi)
1718 call mpi_send(wc_tmp,1,type_block_wc_io, 0,itag,icomm,ierrmpi)
1719 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
1720 end do
1721 else
1722 inquire(qunit,opened=fileopen)
1723 if(.not.fileopen)then
1724 ! generate filename
1725 filenr=snapshotini
1726 if (autoconvert) filenr=snapshotnext
1727 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".vti"
1728 ! Open the file for the header part
1729 open(qunit,file=filename,status='unknown',form='formatted')
1730 end if
1731 call getheadernames(wnamei,xandwnamei,outfilehead)
1732 ! number of cells per grid.
1733 nx^d=ixmhi^d-ixmlo^d+1;
1734 origin = 0
1735 {^d& origin(^d) = xprobmin^d*normconv(0); }
1736 spacing = zero
1737 {^d&spacing(^d) = dxlevel(^d)*normconv(0); }
1738 wholeextent = 0
1739 ! if we use writespshift, the whole extent has to be calculated:
1740 {^d&wholeextent(^d*2-1) = nx^d * ceiling(((xprobmax^d-xprobmin^d)*writespshift(^d,1)) &
1741 /(nx^d*dxlevel(^d))) \}
1742 {^d&wholeextent(^d*2) = nx^d * floor(((xprobmax^d-xprobmin^d)*(1.0d0-writespshift(^d,2))) &
1743 /(nx^d*dxlevel(^d))) \}
1744
1745 ! generate xml header
1746 write(qunit,'(a)')'<?xml version="1.0"?>'
1747 write(qunit,'(a)',advance='no') '<VTKFile type="ImageData"'
1748 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
1749 write(qunit,'(a,3(1pe14.6),a,6(i10),a,3(1pe14.6),a)')' <ImageData Origin="',&
1750 origin,'" WholeExtent="',wholeextent,'" Spacing="',spacing,'">'
1751 write(qunit,'(a)')'<FieldData>'
1752 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
1753 'NumberOfTuples="1" format="ascii">'
1754 write(qunit,*) real(global_time*time_convert_factor)
1755 write(qunit,'(a)')'</DataArray>'
1756 write(qunit,'(a)')'</FieldData>'
1757
1758 ! write the data from proc 0
1759 do morton_no=morton_start(0),morton_stop(0)
1760 if(.not. morton_aim(morton_no)) cycle
1761 igrid=sfc_to_igrid(morton_no)
1762 tree%node => igrid_to_node(igrid, 0)%node
1763 {^d& ig^d = tree%node%ig^d; }
1764 call calc_x(igrid,xc,xcc)
1765 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1766 ixc^l,ixcc^l,.true.)
1767 call write_vti(qunit,ixg^ll,ixc^l,ixcc^l,ig^d,&
1768 nx^d,normconv,wnamei,wc_tmp,wcc_tmp)
1769 end do
1770
1771 if(npe>1)then
1772 allocate(intstatus(mpi_status_size,1))
1773 do ipe=1, npe-1
1774 do morton_no=morton_start(ipe),morton_stop(ipe)
1775 if(.not. morton_aim(morton_no)) cycle
1776 itag=morton_no
1777 call mpi_recv(ind_recv,siz_ind, mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1778 ixrvcmin^d=ind_recv(^d);ixrvcmax^d=ind_recv(^nd+^d);
1779 ixrvccmin^d=ind_recv(2*^nd+^d);ixrvccmax^d=ind_recv(3*^nd+^d);
1780 ig^d=ind_recv(4*^nd+^d);
1781 call mpi_recv(wc_tmp,1,type_block_wc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1782 call mpi_recv(wcc_tmp,1,type_block_wcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
1783 call write_vti(qunit,ixg^ll,ixrvc^l,ixrvcc^l,ig^d,&
1784 nx^d,normconv,wnamei,wc_tmp,wcc_tmp)
1785 end do
1786 end do
1787 end if
1788 write(qunit,'(a)')'</ImageData>'
1789 write(qunit,'(a)')'</VTKFile>'
1790 close(qunit)
1791 if(npe>1) deallocate(intstatus)
1792 end if
1793
1794 deallocate(morton_aim,morton_aim_p)
1795 if (npe>1) then
1796 call mpi_barrier(icomm,ierrmpi)
1797 endif
1798
1799 end subroutine imagedatavtk_mpi
1800
1801 subroutine punstructuredvtk_mpi(qunit)
1802 ! Write one pvtu and vtu files for each processor
1803 ! Otherwise like unstructuredvtk_mpi
1807
1808 integer, intent(in) :: qunit
1809
1810 double precision, dimension(0:nw+nwauxio) :: normconv
1811 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
1812 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
1813 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
1814 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
1815 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP
1816 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
1817 integer :: nx^D,nxC^D,nc,np, igrid,ixC^L,ixCC^L,level,Morton_no
1818 integer :: filenr
1819 logical :: fileopen,conv_grid
1820 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
1821 character(len=1024) :: outfilehead
1822 character(len=80) :: pfilename
1823
1824 ! Write pvtu-file:
1825 if (mype==0) then
1826 call write_pvtu(qunit)
1827 endif
1828 ! Now write the Source files:
1829 inquire(qunit,opened=fileopen)
1830 if(.not.fileopen)then
1831 ! generate filename
1832 filenr=snapshotini
1833 if (autoconvert) filenr=snapshotnext
1834 ! Open the file for the header part
1835 write(pfilename,'(a,i4.4,a,i4.4,a)') trim(base_filename),filenr,"p",mype,".vtu"
1836 open(qunit,file=pfilename,status='unknown',form='formatted')
1837 end if
1838 ! generate xml header
1839 write(qunit,'(a)')'<?xml version="1.0"?>'
1840 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
1841 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
1842 write(qunit,'(a)')' <UnstructuredGrid>'
1843 write(qunit,'(a)')'<FieldData>'
1844 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
1845 'NumberOfTuples="1" format="ascii">'
1846 write(qunit,*) real(global_time*time_convert_factor)
1847 write(qunit,'(a)')'</DataArray>'
1848 write(qunit,'(a)')'</FieldData>'
1849
1850 call getheadernames(wnamei,xandwnamei,outfilehead)
1851
1852 ! number of cells, number of corner points, per grid.
1853 nx^d=ixmhi^d-ixmlo^d+1;
1854 nxc^d=nx^d+1;
1855 nc={nx^d*}
1856 np={nxc^d*}
1857
1858 ! Note: using the w_write, writelevel, writespshift
1859 ! we can clip parts of the grid away, select variables, levels etc.
1860 do level=levmin,levmax
1861 if (.not.writelevel(level)) cycle
1862 do morton_no=morton_start(mype),morton_stop(mype)
1863 igrid=sfc_to_igrid(morton_no)
1864 if (node(plevel_,igrid)/=level) cycle
1865 ! only output a grid when fully within clipped region selected
1866 ! by writespshift array
1867 conv_grid=({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
1868 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
1869 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})
1870 if (.not.conv_grid) cycle
1871 call calc_x(igrid,xc,xcc)
1872 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1873 ixc^l,ixcc^l,.true.)
1874 call write_vtk(qunit,ixg^ll,ixc^l,ixcc^l,igrid,nc,np,nx^d,nxc^d,&
1875 normconv,wnamei,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp)
1876 end do ! Morton_no loop
1877 end do ! level loop
1878
1879 write(qunit,'(a)')' </UnstructuredGrid>'
1880 write(qunit,'(a)')'</VTKFile>'
1881 close(qunit)
1882
1883 if (npe>1) then
1884 call mpi_barrier(icomm,ierrmpi)
1885 end if
1886
1887 end subroutine punstructuredvtk_mpi
1888
1889 subroutine unstructuredvtk_mpi(qunit)
1890 ! output for vtu format to paraview, non-binary version output
1891 ! parallel, uses calc_grid to compute nwauxio variables
1892 ! allows renormalizing using convert factors
1893 ! allows skipping of w_write selected variables
1894 ! implementation such that length of ASCII output is identical when
1895 ! run on 1 versus multiple CPUs (however, the order of the vtu pieces can differ)
1899
1900 integer, intent(in) :: qunit
1901
1902 double precision :: x_VTK(1:3)
1903 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP,xC_TMP_recv
1904 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP,xCC_TMP_recv
1905 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
1906 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
1907 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP,wC_TMP_recv
1908 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP,wCC_TMP_recv
1909 double precision, dimension(0:nw+nwauxio) :: normconv
1910 integer:: igrid,iigrid,level,ixC^L,ixCC^L
1911 integer:: NumGridsOnLevel(1:nlevelshi)
1912 integer :: nx^D,nxC^D,nodesonlevel,elemsonlevel,nc,np,ix^D
1913 integer :: filenr
1914 integer :: itag,ipe,Morton_no,siz_ind
1915 integer :: ind_send(4*^ND),ind_recv(4*^ND)
1916 integer :: levmin_recv,levmax_recv,level_recv,igrid_recv,ixrvC^L,ixrvCC^L
1917 integer, allocatable :: intstatus(:,:)
1918 logical :: fileopen,conv_grid,cond_grid_recv
1919 character(len=80):: filename
1920 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
1921 character(len=1024) :: outfilehead
1922
1923 if(mype==0) then
1924 inquire(qunit,opened=fileopen)
1925 if(.not.fileopen)then
1926 ! generate filename
1927 filenr=snapshotini
1928 if (autoconvert) filenr=snapshotnext
1929 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".vtu"
1930 ! Open the file for the header part
1931 open(qunit,file=filename,status='unknown',form='formatted')
1932 end if
1933 ! generate xml header
1934 write(qunit,'(a)')'<?xml version="1.0"?>'
1935 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
1936 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
1937 write(qunit,'(a)')'<UnstructuredGrid>'
1938 write(qunit,'(a)')'<FieldData>'
1939 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
1940 'NumberOfTuples="1" format="ascii">'
1941 write(qunit,*) real(global_time*time_convert_factor)
1942 write(qunit,'(a)')'</DataArray>'
1943 write(qunit,'(a)')'</FieldData>'
1944 end if
1945
1946 call getheadernames(wnamei,xandwnamei,outfilehead)
1947 ! number of cells, number of corner points, per grid.
1948 nx^d=ixmhi^d-ixmlo^d+1;
1949 nxc^d=nx^d+1;
1950 nc={nx^d*}
1951 np={nxc^d*}
1952 ! all slave processors send their minmal/maximal levels
1953 if (mype/=0) then
1954 if (morton_stop(mype)==0) call mpistop("nultag")
1955 itag=1000*morton_stop(mype)
1956 !print *,'ype,itag for levmin=',mype,itag,levmin
1957 call mpi_send(levmin,1,mpi_integer, 0,itag,icomm,ierrmpi)
1958 itag=2000*morton_stop(mype)
1959 !print *,'mype,itag for levmax=',mype,itag,levmax
1960 call mpi_send(levmax,1,mpi_integer, 0,itag,icomm,ierrmpi)
1961 end if
1962 ! Note: using the w_write, writelevel, writespshift
1963 ! we can clip parts of the grid away, select variables, levels etc.
1964 do level=levmin,levmax
1965 if (.not.writelevel(level)) cycle
1966 do morton_no=morton_start(mype),morton_stop(mype)
1967 igrid=sfc_to_igrid(morton_no)
1968 if (mype/=0)then
1969 itag=morton_no
1970 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
1971 itag=igrid
1972 call mpi_send(node(plevel_,igrid),1,mpi_integer, 0,itag,icomm,ierrmpi)
1973 end if
1974 if (node(plevel_,igrid)/=level) cycle
1975 ! only output a grid when fully within clipped region selected
1976 ! by writespshift array
1977 conv_grid=({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
1978 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
1979 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})
1980 if (mype/=0)then
1981 call mpi_send(conv_grid,1,mpi_logical,0,itag,icomm,ierrmpi)
1982 end if
1983 if (.not.conv_grid) cycle
1984 call calc_x(igrid,xc,xcc)
1985 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
1986 ixc^l,ixcc^l,.true.)
1987 if(mype/=0) then
1988 itag=morton_no
1989 ind_send=(/ ixc^l,ixcc^l /)
1990 siz_ind=4*^nd
1991 call mpi_send(ind_send,siz_ind,mpi_integer, 0,itag,icomm,ierrmpi)
1992 call mpi_send(normconv,nw+nwauxio+1,mpi_double_precision, 0,itag,icomm,ierrmpi)
1993 call mpi_send(wc_tmp,1,type_block_wc_io, 0,itag,icomm,ierrmpi)
1994 call mpi_send(xc_tmp,1,type_block_xc_io, 0,itag,icomm,ierrmpi)
1995 itag=igrid
1996 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
1997 call mpi_send(xcc_tmp,1,type_block_xcc_io, 0,itag,icomm,ierrmpi)
1998 else
1999 call write_vtk(qunit,ixg^ll,ixc^l,ixcc^l,igrid,nc,np,nx^d,nxc^d,&
2000 normconv,wnamei,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp)
2001 end if
2002 end do ! Morton_no loop
2003 end do ! level loop
2004
2005 if(mype==0) then
2006 allocate(intstatus(mpi_status_size,1))
2007 if(npe>1)then
2008 do ipe=1,npe-1
2009 itag=1000*morton_stop(ipe)
2010 call mpi_recv(levmin_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2011 !!print *,'mype RECEIVES,itag for levmin=',mype,itag,levmin_recv
2012 itag=2000*morton_stop(ipe)
2013 call mpi_recv(levmax_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2014 !!print *,'mype RECEIVES itag for levmax=',mype,itag,levmax_recv
2015 do level=levmin_recv,levmax_recv
2016 if (.not.writelevel(level)) cycle
2017 do morton_no=morton_start(ipe),morton_stop(ipe)
2018 itag=morton_no
2019 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2020 itag=igrid_recv
2021 call mpi_recv(level_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2022 if (level_recv/=level) cycle
2023 call mpi_recv(cond_grid_recv,1,mpi_logical, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2024 if(.not.cond_grid_recv)cycle
2025 itag=morton_no
2026 siz_ind=4*^nd
2027 call mpi_recv(ind_recv,siz_ind, mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2028 ixrvcmin^d=ind_recv(^d);ixrvcmax^d=ind_recv(^nd+^d);
2029 ixrvccmin^d=ind_recv(2*^nd+^d);ixrvccmax^d=ind_recv(3*^nd+^d);
2030 call mpi_recv(normconv,nw+nwauxio+1, mpi_double_precision,ipe,itag&
2031 ,icomm,intstatus(:,1),ierrmpi)
2032 call mpi_recv(wc_tmp_recv,1,type_block_wc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2033 call mpi_recv(xc_tmp_recv,1,type_block_xc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2034 itag=igrid_recv
2035 call mpi_recv(wcc_tmp_recv,1,type_block_wcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2036 call mpi_recv(xcc_tmp_recv,1,type_block_xcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2037 call write_vtk(qunit,ixg^ll,ixrvc^l,ixrvcc^l,igrid_recv,&
2038 nc,np,nx^d,nxc^d,normconv,wnamei,&
2039 xc_tmp_recv,xcc_tmp_recv,wc_tmp_recv,wcc_tmp_recv)
2040 end do ! Morton_no loop
2041 end do ! level loop
2042 end do ! processor loop
2043 end if ! multiple processors
2044 write(qunit,'(a)')'</UnstructuredGrid>'
2045 write(qunit,'(a)')'</VTKFile>'
2046 close(qunit)
2047 end if
2048 if (npe>1) then
2049 call mpi_barrier(icomm,ierrmpi)
2050 if(mype==0)deallocate(intstatus)
2051 end if
2052
2053 end subroutine unstructuredvtk_mpi
2054
2055 subroutine write_vtk(qunit,ixI^L,ixC^L,ixCC^L,igrid,nc,np,nx^D,nxC^D,&
2056 normconv,wnamei,xC,xCC,wC,wCC)
2058
2059 integer, intent(in) :: qunit
2060 integer, intent(in) :: ixI^L,ixC^L,ixCC^L
2061 integer, intent(in) :: igrid,nc,np,nx^D,nxC^D
2062 double precision, intent(in) :: normconv(0:nw+nwauxio)
2063 character(len=name_len), intent(in):: wnamei(1:nw+nwauxio)
2064 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
2065 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
2066 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC
2067 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC
2068
2069 double precision :: x_VTK(1:3)
2070 integer :: iw,ix^D,icel,VTK_type
2071
2072 select case(convert_type)
2073 case('vtumpi','pvtumpi')
2074 ! we write out every grid as one VTK PIECE
2075 write(qunit,'(a,i7,a,i7,a)') &
2076 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
2077 write(qunit,'(a)')'<PointData>'
2078 do iw=1,nw+nwauxio
2079 if(iw<=nw) then
2080 if(.not.w_write(iw)) cycle
2081 end if
2082 write(qunit,'(a,a,a)')&
2083 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
2084 write(qunit,'(200(1pe14.6))') {(|}wc(ix^d,iw)*normconv(iw),{ix^d=ixcmin^d,ixcmax^d)}
2085 write(qunit,'(a)')'</DataArray>'
2086 end do
2087 write(qunit,'(a)')'</PointData>'
2088 write(qunit,'(a)')'<Points>'
2089 write(qunit,'(a)')'<DataArray type="Float32" NumberOfComponents="3" format="ascii">'
2090 ! write cell corner coordinates in a backward dimensional loop, always 3D output
2091 {do ix^db=ixcmin^db,ixcmax^db \}
2092 x_vtk(1:3)=zero;
2093 x_vtk(1:ndim)=xc(ix^d,1:ndim)*normconv(0);
2094 write(qunit,'(3(1pe14.6))') x_vtk
2095 {end do \}
2096 write(qunit,'(a)')'</DataArray>'
2097 write(qunit,'(a)')'</Points>'
2098
2099 case('vtuCCmpi','pvtuCCmpi')
2100 ! we write out every grid as one VTK PIECE
2101 write(qunit,'(a,i7,a,i7,a)') &
2102 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
2103 write(qunit,'(a)')'<CellData>'
2104 do iw=1,nw+nwauxio
2105 if(iw<=nw) then
2106 if(.not.w_write(iw)) cycle
2107 end if
2108 write(qunit,'(a,a,a)')&
2109 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
2110 write(qunit,'(200(1pe14.6))') {(|}wcc(ix^d,iw)*normconv(iw),{ix^d=ixccmin^d,ixccmax^d)}
2111 write(qunit,'(a)')'</DataArray>'
2112 end do
2113 write(qunit,'(a)')'</CellData>'
2114 write(qunit,'(a)')'<Points>'
2115 write(qunit,'(a)')'<DataArray type="Float32" NumberOfComponents="3" format="ascii">'
2116 ! write cell corner coordinates in a backward dimensional loop, always 3D output
2117 {do ix^db=ixcmin^db,ixcmax^db \}
2118 x_vtk(1:3)=zero;
2119 x_vtk(1:ndim)=xc(ix^d,1:ndim)*normconv(0);
2120 write(qunit,'(3(1pe14.6))') x_vtk
2121 {end do \}
2122 write(qunit,'(a)')'</DataArray>'
2123 write(qunit,'(a)')'</Points>'
2124 end select
2125
2126 write(qunit,'(a)')'<Cells>'
2127 ! connectivity part
2128 write(qunit,'(a)')'<DataArray type="Int32" Name="connectivity" format="ascii">'
2129 call save_connvtk(qunit,igrid)
2130 write(qunit,'(a)')'</DataArray>'
2131 ! offsets data array
2132 write(qunit,'(a)')'<DataArray type="Int32" Name="offsets" format="ascii">'
2133 do icel=1,nc
2134 write(qunit,'(i7)') icel*(2**^nd)
2135 end do
2136 write(qunit,'(a)')'</DataArray>'
2137 ! VTK cell type data array
2138 write(qunit,'(a)')'<DataArray type="Int32" Name="types" format="ascii">'
2139 vtk_type=vtk_cell_type()
2140 do icel=1,nc
2141 write(qunit,'(i2)') vtk_type
2142 end do
2143 write(qunit,'(a)')'</DataArray>'
2144 write(qunit,'(a)')'</Cells>'
2145 write(qunit,'(a)')'</Piece>'
2146
2147 end subroutine write_vtk
2148
2149 subroutine write_vti(qunit,ixI^L,ixC^L,ixCC^L,ig^D,nx^D,&
2150 normconv,wnamei,wC,wCC)
2152
2153 integer, intent(in) :: qunit
2154 integer, intent(in) :: ixI^L,ixC^L,ixCC^L
2155 integer, intent(in) :: ig^D,nx^D
2156 double precision, intent(in) :: normconv(0:nw+nwauxio)
2157 character(len=name_len), intent(in):: wnamei(1:nw+nwauxio)
2158 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC
2159 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC
2160
2161 integer :: iw,ix^D
2162 integer :: extent(1:6)
2163
2164 extent = 0
2165 {^d& extent(^d*2-1) = (ig^d-1) * nx^d; }
2166 {^d& extent(^d*2) = (ig^d) * nx^d; }
2167
2168 select case(convert_type)
2169 case('vtimpi','pvtimpi')
2170 ! we write out every grid as one VTK PIECE
2171 write(qunit,'(a,6(i10),a)') &
2172 '<Piece Extent="',extent,'">'
2173 write(qunit,'(a)')'<PointData>'
2174 do iw=1,nw+nwauxio
2175 if(iw<=nw) then
2176 if(.not.w_write(iw)) cycle
2177 end if
2178 write(qunit,'(a,a,a)')&
2179 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
2180 write(qunit,'(200(1pe20.12))') {(|}wc(ix^d,iw)*normconv(iw),{ix^d=ixcmin^d,ixcmax^d)}
2181 write(qunit,'(a)')'</DataArray>'
2182 end do
2183 write(qunit,'(a)')'</PointData>'
2184 case('vtiCCmpi','pvtiCCmpi')
2185 ! we write out every grid as one VTK PIECE
2186 write(qunit,'(a,6(i10),a)') &
2187 '<Piece Extent="',extent,'">'
2188 write(qunit,'(a)')'<CellData>'
2189 do iw=1,nw+nwauxio
2190 if(iw<=nw) then
2191 if(.not.w_write(iw)) cycle
2192 end if
2193 write(qunit,'(a,a,a)')&
2194 '<DataArray type="Float64" Name="',trim(wnamei(iw)),'" format="ascii">'
2195 write(qunit,'(200(1pe20.12))') {(|}wcc(ix^d,iw)*normconv(iw),{ix^d=ixccmin^d,ixccmax^d)}
2196 write(qunit,'(a)')'</DataArray>'
2197 end do
2198 write(qunit,'(a)')'</CellData>'
2199 end select
2200
2201 write(qunit,'(a)')'</Piece>'
2202
2203 end subroutine write_vti
2204
2205 subroutine write_pvtu(qunit)
2208
2209 integer, intent(in) :: qunit
2210
2211 integer :: filenr,iw,ipe,iscalars
2212 logical :: fileopen
2213 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio),outtype
2214 character(len=1024) :: outfilehead
2215 character(len=80) :: filename,pfilename
2216
2217 select case(convert_type)
2218 case('pvtumpi','pvtuBmpi')
2219 outtype="PPointData"
2220 case('pvtuCCmpi','pvtuBCCmpi')
2221 outtype="PCellData"
2222 end select
2223 inquire(qunit,opened=fileopen)
2224 if(.not.fileopen)then
2225 ! generate filename
2226 filenr=snapshotini
2227 if (autoconvert) filenr=snapshotnext
2228 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".pvtu"
2229 ! Open the file
2230 open(qunit,file=filename,status='unknown',form='formatted')
2231 end if
2232
2233 call getheadernames(wnamei,xandwnamei,outfilehead)
2234 ! Get the default selection:
2235 iscalars=1
2236 do iw=nw,1, -1
2237 if (w_write(iw)) iscalars=iw
2238 end do
2239 ! generate xml header
2240 write(qunit,'(a)')'<?xml version="1.0"?>'
2241 write(qunit,'(a)',advance='no') '<VTKFile type="PUnstructuredGrid"'
2242 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
2243 write(qunit,'(a)')' <PUnstructuredGrid GhostLevel="0">'
2244 ! Either celldata or pointdata:
2245 write(qunit,'(a,a,a,a,a)')&
2246 ' <',trim(outtype),' Scalars="',trim(wnamei(iscalars))//'">'
2247 do iw=1,nw
2248 if(.not.w_write(iw))cycle
2249 write(qunit,'(a,a,a)')&
2250 ' <PDataArray type="Float32" Name="',trim(wnamei(iw)),'"/>'
2251 end do
2252 do iw=nw+1,nw+nwauxio
2253 write(qunit,'(a,a,a)')&
2254 ' <PDataArray type="Float32" Name="',trim(wnamei(iw)),'"/>'
2255 end do
2256 write(qunit,'(a,a,a)')' </',trim(outtype),'>'
2257 write(qunit,'(a)')' <PPoints>'
2258 write(qunit,'(a)')' <PDataArray type="Float32" NumberOfComponents="3"/>'
2259 write(qunit,'(a)')' </PPoints>'
2260
2261 do ipe=0,npe-1
2262 write(pfilename,'(a,i4.4,a,i4.4,a)') trim(base_filename(&
2263 index(base_filename, '/', back = .true.)+1:&
2264 len(base_filename))),filenr,"p",&
2265 ipe,".vtu"
2266 write(qunit,'(a,a,a)')' <Piece Source="',trim(pfilename),'"/>'
2267 end do
2268 write(qunit,'(a)')' </PUnstructuredGrid>'
2269 write(qunit,'(a)')'</VTKFile>'
2270 close(qunit)
2271
2272 end subroutine write_pvtu
2273
2274 subroutine tecplot_mpi(qunit)
2275 ! output for tecplot (ASCII format)
2276 ! parallel, uses calc_grid to compute nwauxio variables
2277 ! allows renormalizing using convert factors
2278 ! the current implementation is such that tecplotmpi and tecplotCCmpi will
2279 ! create different length output ASCII files when used on 1 versus multiple CPUs
2280 ! in fact, on 1 CPU, there will be as many zones as there are levels
2281 ! on multiple CPUs, there will be a number of zones up to the number of
2282 ! levels times the number of CPUs (can be less, when some level not on a CPU)
2286
2287 integer, intent(in) :: qunit
2288
2289 double precision :: x_TEC(ndim), w_TEC(nw+nwauxio)
2290 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP,xC_TMP_recv
2291 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP,xCC_TMP_recv
2292 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
2293 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
2294 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP,wC_TMP_recv
2295 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP,wCC_TMP_recv
2296 double precision, dimension(0:nw+nwauxio) :: normconv
2297 integer:: igrid,iigrid,level,igonlevel,iw,idim,ix^D
2298 integer:: NumGridsOnLevel(1:nlevelshi)
2299 integer :: nx^D,nxC^D,nodesonlevel,elemsonlevel,ixC^L,ixCC^L
2300 integer :: nodesonlevelmype,elemsonlevelmype
2301 integer :: nodes, elems
2302 integer, allocatable :: intstatus(:,:)
2303 integer :: itag,Morton_no,ipe,levmin_recv,levmax_recv,igrid_recv,level_recv
2304 integer :: ixrvC^L,ixrvCC^L
2305 integer :: ind_send(2*^ND),ind_recv(2*^ND),siz_ind,igonlevel_recv
2306 integer :: NumGridsOnLevel_mype(1:nlevelshi,0:npe-1)
2307 integer :: filenr
2308 logical :: fileopen,first
2309 character(len=80) :: filename
2310 character(len=1024) :: tecplothead
2311 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
2312 character(len=1024) :: outfilehead
2313
2314 if(nw/=count(w_write(1:nw)))then
2315 if(mype==0) print *,'tecplot_mpi does not use w_write=F'
2316 call mpistop('w_write, tecplot')
2317 end if
2318
2319 if(nocartesian)then
2320 if(mype==0) print *,'tecplot_mpi with nocartesian'
2321 end if
2322
2323 master_cpu_open : if (mype == 0) then
2324 inquire(qunit,opened=fileopen)
2325 if (.not.fileopen) then
2326 ! generate filename
2327 filenr=snapshotini
2328 if (autoconvert) filenr=snapshotnext
2329 write(filename,'(a,i4.4,a)') trim(base_filename),filenr,".plt"
2330 open(qunit,file=filename,status='unknown')
2331 end if
2332 call getheadernames(wnamei,xandwnamei,outfilehead)
2333 write(tecplothead,'(a)') "VARIABLES = "//trim(outfilehead)
2334 write(qunit,'(a)') tecplothead(1:len_trim(tecplothead))
2335 end if master_cpu_open
2336
2337 ! determine overall number of grids per level, and the same info per CPU
2338 numgridsonlevel(1:nlevelshi)=0
2339 do level=levmin,levmax
2340 numgridsonlevel(level)=0
2341 do morton_no=morton_start(mype),morton_stop(mype)
2342 igrid = sfc_to_igrid(morton_no)
2343 if (node(plevel_,igrid)/=level) cycle
2344 numgridsonlevel(level)=numgridsonlevel(level)+1
2345 end do
2346 numgridsonlevel_mype(level,0:npe-1)=0
2347 numgridsonlevel_mype(level,mype) = numgridsonlevel(level)
2348 call mpi_allreduce(mpi_in_place,numgridsonlevel_mype(level,0:npe-1),npe,mpi_integer,&
2349 mpi_max,icomm,ierrmpi)
2350 call mpi_allreduce(mpi_in_place,numgridsonlevel(level),1,mpi_integer,mpi_sum, &
2351 icomm,ierrmpi)
2352 end do
2353
2354 nx^d=ixmhi^d-ixmlo^d+1;
2355 nxc^d=nx^d+1;
2356
2357 if(mype==0.and.npe>1) allocate(intstatus(mpi_status_size,1))
2358
2359 {^ifoned
2360 if(convert_type=='teclinempi') then
2361 nodes=0
2362 elems=0
2363 do level=levmin,levmax
2364 nodes=nodes + numgridsonlevel(level)*{nxc^d*}
2365 elems=elems + numgridsonlevel(level)*{nx^d*}
2366 end do
2367
2368 if (mype==0) write(qunit,"(a,i7,a,1pe12.5,a)") &
2369 'ZONE T="all levels", I=',elems, &
2370 ', SOLUTIONTIME=',global_time*time_convert_factor,', F=POINT'
2371
2372 igonlevel=0
2373 do morton_no=morton_start(mype),morton_stop(mype)
2374 igrid = sfc_to_igrid(morton_no)
2375 call calc_x(igrid,xc,xcc)
2376 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,ixc^l,ixcc^l,.true.)
2377 if (mype==0) then
2378 {do ix^db=ixccmin^db,ixccmax^db\}
2379 x_tec(1:ndim)=xcc_tmp(ix^d,1:ndim)*normconv(0)
2380 w_tec(1:nw+nwauxio)=wcc_tmp(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
2381 write(qunit,fmt="(100(e14.6))") x_tec, w_tec
2382 {end do\}
2383 else if (mype/=0) then
2384 itag=morton_no
2385 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
2386 call mpi_send(normconv,nw+nwauxio+1,mpi_double_precision,0,itag,icomm,ierrmpi)
2387 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
2388 call mpi_send(xcc_tmp,1,type_block_xcc_io, 0,itag,icomm,ierrmpi)
2389 end if
2390 end do
2391 if(mype==0) then
2392 do ipe=1,npe-1
2393 do morton_no=morton_start(ipe),morton_stop(ipe)
2394 itag=morton_no
2395 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2396 call mpi_recv(normconv,nw+nwauxio+1, mpi_double_precision,ipe,&
2397 itag,icomm,intstatus(:,1),ierrmpi)
2398 call mpi_recv(wcc_tmp_recv,1,type_block_wcc_io, ipe,itag,&
2399 icomm,intstatus(:,1),ierrmpi)
2400 call mpi_recv(xcc_tmp_recv,1,type_block_xcc_io, ipe,itag,&
2401 icomm,intstatus(:,1),ierrmpi)
2402 {do ix^db=ixccmin^db,ixccmax^db\}
2403 x_tec(1:ndim)=xcc_tmp_recv(ix^d,1:ndim)*normconv(0)
2404 w_tec(1:nw+nwauxio)=wcc_tmp_recv(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
2405 write(qunit,fmt="(100(e14.6))") x_tec, w_tec
2406 {end do\}
2407 end do
2408 end do
2409 close(qunit)
2410 end if
2411 else
2412 }
2413 if(mype/=0) then
2414 itag=1000*morton_stop(mype)
2415 call mpi_send(levmin,1,mpi_integer, 0,itag,icomm,ierrmpi)
2416 itag=2000*morton_stop(mype)
2417 call mpi_send(levmax,1,mpi_integer, 0,itag,icomm,ierrmpi)
2418 end if
2419
2420 do level=levmin,levmax
2421 nodesonlevelmype=numgridsonlevel_mype(level,mype)*{nxc^d*}
2422 elemsonlevelmype=numgridsonlevel_mype(level,mype)*{nx^d*}
2423 nodesonlevel=numgridsonlevel(level)*{nxc^d*}
2424 elemsonlevel=numgridsonlevel(level)*{nx^d*}
2425 ! for all tecplot variants coded up here, we let the TECPLOT ZONES coincide
2426 ! with the AMR grid LEVEL. Other options would be
2427 ! let each grid define a zone: inefficient for TECPLOT internal workings
2428 ! hence not implemented
2429 ! let entire octree define 1 zone: no difference in interpolation
2430 ! properties across TECPLOT zones detected as yet, hence not done
2431 select case(convert_type)
2432 case('tecplotmpi')
2433 ! in this option, we store the corner coordinates, as well as the corner
2434 ! values of all variables (obtained by averaging). This allows POINT packaging,
2435 ! and thus we can save full grid info by using one call to calc_grid
2436 if (mype==0.and.(nodesonlevelmype>0.and.elemsonlevelmype>0))&
2437 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,a)") &
2438 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2439 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=POINT, ZONETYPE=', &
2440 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2441 do morton_no=morton_start(mype),morton_stop(mype)
2442 igrid = sfc_to_igrid(morton_no)
2443 if (mype/=0)then
2444 itag=morton_no
2445 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
2446 itag=igrid
2447 call mpi_send(node(plevel_,igrid),1,mpi_integer, 0,itag,icomm,ierrmpi)
2448 end if
2449 if (node(plevel_,igrid)/=level) cycle
2450 call calc_x(igrid,xc,xcc)
2451 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
2452 ixc^l,ixcc^l,.true.)
2453 if (mype/=0) then
2454 itag=morton_no
2455 ind_send=(/ ixc^l /)
2456 siz_ind=2*^nd
2457 call mpi_send(ind_send,siz_ind, mpi_integer, 0,itag,icomm,ierrmpi)
2458 call mpi_send(normconv,nw+nwauxio+1,mpi_double_precision, 0,itag,icomm,ierrmpi)
2459
2460 call mpi_send(wc_tmp,1,type_block_wc_io, 0,itag,icomm,ierrmpi)
2461 call mpi_send(xc_tmp,1,type_block_xc_io, 0,itag,icomm,ierrmpi)
2462 else
2463 {do ix^db=ixcmin^db,ixcmax^db\}
2464 x_tec(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0)
2465 w_tec(1:nw+nwauxio)=wc_tmp(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
2466 write(qunit,fmt="(100(e14.6))") x_tec, w_tec
2467 {end do\}
2468 end if
2469 end do
2470 case('tecplotCCmpi')
2471 ! in this option, we store the corner coordinates, and the cell center
2472 ! values of all variables. Due to this mix of corner/cell center, we must
2473 ! use BLOCK packaging, and thus we have enormous overhead by using
2474 ! calc_grid repeatedly to merely fill values of cell corner coordinates
2475 ! and cell center values per dimension, per variable
2476 if(ndim+nw+nwauxio>99) call mpistop("adjust format specification in writeout")
2477 if(nw+nwauxio==1)then
2478 ! to make tecplot happy: avoid [ndim+1-ndim+1] in varlocation varset
2479 ! and just set [ndim+1]
2480 if (mype==0.and.(nodesonlevelmype>0.and.elemsonlevelmype>0))&
2481 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,a)") &
2482 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2483 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2484 ndim+1,']=CELLCENTERED), ZONETYPE=', &
2485 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2486 else
2487 if(ndim+nw+nwauxio<10) then
2488 ! difference only in length of integer format specification for ndim+nw+nwauxio
2489 if (mype==0.and.(nodesonlevelmype>0.and.elemsonlevelmype>0))&
2490 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i1,a,a)") &
2491 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2492 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2493 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
2494 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2495 else
2496 if (mype==0.and.(nodesonlevelmype>0.and.elemsonlevelmype>0))&
2497 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i2,a,a)") &
2498 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2499 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2500 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
2501 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2502 end if
2503 end if
2504
2505 do idim=1,ndim
2506 first=(idim==1)
2507 do morton_no=morton_start(mype),morton_stop(mype)
2508 igrid = sfc_to_igrid(morton_no)
2509 if (mype/=0)then
2510 itag=morton_no*idim
2511 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
2512 itag=igrid*idim
2513 call mpi_send(node(plevel_,igrid),1,mpi_integer, 0,itag,icomm,ierrmpi)
2514 end if
2515 if (node(plevel_,igrid)/=level) cycle
2516 call calc_x(igrid,xc,xcc)
2517 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
2518 ixc^l,ixcc^l,first)
2519 if (mype/=0)then
2520 ind_send=(/ ixc^l /)
2521 siz_ind=2*^nd
2522 itag=igrid*idim
2523 call mpi_send(ind_send,siz_ind, mpi_integer, 0,itag,icomm,ierrmpi)
2524 call mpi_send(normconv,nw+nwauxio+1,mpi_double_precision, 0,itag,icomm,ierrmpi)
2525 call mpi_send(xc_tmp,1,type_block_xc_io, 0,itag,icomm,ierrmpi)
2526 else
2527 write(qunit,fmt="(100(e14.6))") xc_tmp(ixc^s,idim)*normconv(0)
2528 end if
2529 end do
2530 end do
2531 do iw=1,nw+nwauxio
2532 do morton_no=morton_start(mype),morton_stop(mype)
2533 igrid = sfc_to_igrid(morton_no)
2534 if(mype/=0)then
2535 itag=morton_no*(ndim+iw)
2536 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
2537 itag=igrid*(ndim+iw)
2538 call mpi_send(node(plevel_,igrid),1,mpi_integer, 0,itag,icomm,ierrmpi)
2539 end if
2540 if (node(plevel_,igrid)/=level) cycle
2541 call calc_x(igrid,xc,xcc)
2542 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
2543 ixc^l,ixcc^l,.true.)
2544 if(mype/=0)then
2545 ind_send=(/ ixcc^l /)
2546 siz_ind=2*^nd
2547 itag=igrid*(ndim+iw)
2548 call mpi_send(ind_send,siz_ind, mpi_integer, 0,itag,icomm,ierrmpi)
2549 call mpi_send(normconv,nw+nwauxio+1,mpi_double_precision, 0,itag,icomm,ierrmpi)
2550 call mpi_send(wcc_tmp,1,type_block_wcc_io, 0,itag,icomm,ierrmpi)
2551 else
2552 write(qunit,fmt="(100(e14.6))") wcc_tmp(ixcc^s,iw)*normconv(iw)
2553 end if
2554 end do
2555 end do
2556 case default
2557 call mpistop('no such tecplot type')
2558 end select
2559
2560 igonlevel=0
2561 do morton_no=morton_start(mype),morton_stop(mype)
2562 igrid = sfc_to_igrid(morton_no)
2563 if(mype/=0)then
2564 itag=morton_no
2565 call mpi_send(igrid,1,mpi_integer, 0,itag,icomm,ierrmpi)
2566 itag=igrid
2567 call mpi_send(node(plevel_,igrid),1,mpi_integer, 0,itag,icomm,ierrmpi)
2568 end if
2569 if(node(plevel_,igrid)/=level) cycle
2570 igonlevel=igonlevel+1
2571 if(mype/=0)then
2572 itag=igrid
2573 call mpi_send(igonlevel,1,mpi_integer, 0,itag,icomm,ierrmpi)
2574 end if
2575 if(mype==0)then
2576 call save_conntec(qunit,igrid,igonlevel)
2577 end if
2578 end do
2579 end do
2580
2581 if(mype==0 .and.npe>1) then
2582 do ipe=1,npe-1
2583 itag=1000*morton_stop(ipe)
2584 call mpi_recv(levmin_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2585 itag=2000*morton_stop(ipe)
2586 call mpi_recv(levmax_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2587 do level=levmin_recv,levmax_recv
2588 nodesonlevelmype=numgridsonlevel_mype(level,ipe)*{nxc^d*}
2589 elemsonlevelmype=numgridsonlevel_mype(level,ipe)*{nx^d*}
2590 nodesonlevel=numgridsonlevel(level)*{nxc^d*}
2591 elemsonlevel=numgridsonlevel(level)*{nx^d*}
2592 select case(convert_type)
2593 case('tecplotmpi')
2594 ! in this option, we store the corner coordinates, as well as the corner
2595 ! values of all variables (obtained by averaging). This allows POINT packaging,
2596 ! and thus we can save full grid info by using one call to calc_grid
2597 if(nodesonlevelmype>0.and.elemsonlevelmype>0) &
2598 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,a)") &
2599 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2600 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=POINT, ZONETYPE=', &
2601 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2602 do morton_no=morton_start(ipe),morton_stop(ipe)
2603 itag=morton_no
2604 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2605 itag=igrid_recv
2606 call mpi_recv(level_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2607 if (level_recv/=level) cycle
2608 itag=morton_no
2609 siz_ind=2*^nd
2610 call mpi_recv(ind_recv,siz_ind, mpi_integer, ipe,itag,&
2611 icomm,intstatus(:,1),ierrmpi)
2612 ixrvcmin^d=ind_recv(^d);ixrvcmax^d=ind_recv(^nd+^d);
2613 call mpi_recv(normconv,nw+nwauxio+1, mpi_double_precision,ipe,itag&
2614 ,icomm,intstatus(:,1),ierrmpi)
2615 call mpi_recv(wc_tmp_recv,1,type_block_wc_io, ipe,itag,&
2616 icomm,intstatus(:,1),ierrmpi)
2617 call mpi_recv(xc_tmp_recv,1,type_block_xc_io, ipe,itag,&
2618 icomm,intstatus(:,1),ierrmpi)
2619 {do ix^db=ixrvcmin^db,ixrvcmax^db\}
2620 x_tec(1:ndim)=xc_tmp_recv(ix^d,1:ndim)*normconv(0)
2621 w_tec(1:nw+nwauxio)=wc_tmp_recv(ix^d,1:nw+nwauxio)*normconv(1:nw+nwauxio)
2622 write(qunit,fmt="(100(e14.6))") x_tec, w_tec
2623 {end do\}
2624 end do
2625 case('tecplotCCmpi')
2626 ! in this option, we store the corner coordinates, and the cell center
2627 ! values of all variables. Due to this mix of corner/cell center, we must
2628 ! use BLOCK packaging, and thus we have enormous overhead by using
2629 ! calc_grid repeatedly to merely fill values of cell corner coordinates
2630 ! and cell center values per dimension, per variable
2631 if(ndim+nw+nwauxio>99) call mpistop("adjust format specification in writeout")
2632 if(nw+nwauxio==1)then
2633 ! to make tecplot happy: avoid [ndim+1-ndim+1] in varlocation varset
2634 ! and just set [ndim+1]
2635 if(nodesonlevelmype>0.and.elemsonlevelmype>0) &
2636 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,a)") &
2637 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2638 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2639 ndim+1,']=CELLCENTERED), ZONETYPE=', &
2640 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2641 else
2642 if(ndim+nw+nwauxio<10) then
2643 ! difference only in length of integer format specification for ndim+nw+nwauxio
2644 if(nodesonlevelmype>0.and.elemsonlevelmype>0) &
2645 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i1,a,a)") &
2646 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2647 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2648 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
2649 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2650 else
2651 if(nodesonlevelmype>0.and.elemsonlevelmype>0) &
2652 write(qunit,"(a,i7,a,a,i7,a,i7,a,f25.16,a,i1,a,i2,a,a)") &
2653 'ZONE T="',level,'"',', N=',nodesonlevelmype,', E=',elemsonlevelmype, &
2654 ', SOLUTIONTIME=',global_time*time_convert_factor,', DATAPACKING=BLOCK, VARLOCATION=([', &
2655 ndim+1,'-',ndim+nw+nwauxio,']=CELLCENTERED), ZONETYPE=', &
2656 {^ifoned 'FELINESEG'}{^iftwod 'FEQUADRILATERAL'}{^ifthreed 'FEBRICK'}
2657 end if
2658 end if
2659
2660 do idim=1,ndim
2661 do morton_no=morton_start(ipe),morton_stop(ipe)
2662 itag=morton_no*idim
2663 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2664 itag=igrid_recv*idim
2665 call mpi_recv(level_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2666 if (level_recv/=level) cycle
2667 siz_ind=2*^nd
2668 itag=igrid_recv*idim
2669 call mpi_recv(ind_recv,siz_ind, mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2670 ixrvcmin^d=ind_recv(^d);ixrvcmax^d=ind_recv(^nd+^d);
2671 call mpi_recv(normconv,nw+nwauxio+1, mpi_double_precision,ipe,itag&
2672 ,icomm,intstatus(:,1),ierrmpi)
2673 call mpi_recv(xc_tmp_recv,1,type_block_xc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2674 write(qunit,fmt="(100(e14.6))") xc_tmp_recv(ixrvc^s,idim)*normconv(0)
2675 end do
2676 end do
2677 do iw=1,nw+nwauxio
2678 do morton_no=morton_start(ipe),morton_stop(ipe)
2679 itag=morton_no*(ndim+iw)
2680 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2681 itag=igrid_recv*(ndim+iw)
2682 call mpi_recv(level_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2683 if (level_recv/=level) cycle
2684 siz_ind=2*^nd
2685 itag=igrid_recv*(ndim+iw)
2686 call mpi_recv(ind_recv,siz_ind, mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2687 ixrvccmin^d=ind_recv(^d);ixrvccmax^d=ind_recv(^nd+^d);
2688 call mpi_recv(normconv,nw+nwauxio+1, mpi_double_precision,ipe,itag&
2689 ,icomm,intstatus(:,1),ierrmpi)
2690 call mpi_recv(wcc_tmp_recv,1,type_block_wcc_io, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2691 write(qunit,fmt="(100(e14.6))") wcc_tmp_recv(ixrvcc^s,iw)*normconv(iw)
2692 end do
2693 end do
2694 case default
2695 call mpistop('no such tecplot type')
2696 end select
2697
2698 do morton_no=morton_start(ipe),morton_stop(ipe)
2699 itag=morton_no
2700 call mpi_recv(igrid_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2701 itag=igrid_recv
2702 call mpi_recv(level_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2703 if (level_recv/=level) cycle
2704 itag=igrid_recv
2705 call mpi_recv(igonlevel_recv,1,mpi_integer, ipe,itag,icomm,intstatus(:,1),ierrmpi)
2706 call save_conntec(qunit,igrid_recv,igonlevel_recv)
2707 end do ! morton loop
2708 end do ! level loop
2709 end do ! ipe loop
2710 end if ! mype=0 if
2711 {^ifoned endif}
2712
2713 if (npe>1) then
2714 call mpi_barrier(icomm,ierrmpi)
2715 if(mype==0)deallocate(intstatus)
2716 end if
2717
2718 end subroutine tecplot_mpi
2719
2720 subroutine punstructuredvtkb_mpi(qunit)
2721 ! Write one pvtu and vtu files for each processor
2722 ! Otherwise like unstructuredvtk_mpi
2723 ! output for vtu format to paraview, binary version output
2724 ! uses calc_grid to compute nwauxio variables
2725 ! allows renormalizing using convert factors
2729
2730 integer, intent(in) :: qunit
2731
2732 double precision :: x_VTK(1:3)
2733 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC_TMP
2734 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC_TMP
2735 double precision, dimension(ixMlo^D-1:ixMhi^D,ndim) :: xC
2736 double precision, dimension(ixMlo^D:ixMhi^D,ndim) :: xCC
2737 double precision, dimension(ixMlo^D-1:ixMhi^D,nw+nwauxio) :: wC_TMP
2738 double precision, dimension(ixMlo^D:ixMhi^D,nw+nwauxio) :: wCC_TMP
2739 double precision :: normconv(0:nw+nwauxio)
2740 integer*8 :: offset
2741 integer :: igrid,iigrid,level,igonlevel,icel,ixC^L,ixCC^L,Morton_no
2742 integer :: NumGridsOnLevel(1:nlevelshi)
2743 integer :: nx^D,nxC^D,nodesonlevel,elemsonlevel,nc,np,VTK_type,ix^D
2744 integer:: recsep,k,iw,filenr
2745 integer:: length,lengthcc,offset_points,offset_cells, &
2746 length_coords,length_conn,length_offsets
2747 logical :: fileopen
2748 character:: buf
2749 character(len=6):: bufform
2750 character(len=80) :: pfilename
2751 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:ndim+nw+nwauxio)
2752 character(len=1024) :: outfilehead
2753
2754 ! Write pvtu-file:
2755 if (mype==0) then
2756 call write_pvtu(qunit)
2757 end if
2758 ! Now write the Source files:
2759 inquire(qunit,opened=fileopen)
2760 if(.not.fileopen)then
2761 ! generate filename
2762 filenr=snapshotnext-1
2763 if (autoconvert) filenr=snapshotnext
2764 ! Open the file for the header part
2765 write(pfilename,'(a,i4.4,a,i4.4,a)') trim(base_filename),filenr,"p",mype,".vtu"
2766 open(qunit,file=pfilename,status='unknown',form='formatted')
2767 end if
2768 ! generate xml header
2769 write(qunit,'(a)')'<?xml version="1.0"?>'
2770 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
2771 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
2772 write(qunit,'(a)')' <UnstructuredGrid>'
2773 write(qunit,'(a)')'<FieldData>'
2774 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
2775 'NumberOfTuples="1" format="ascii">'
2776 write(qunit,*) real(global_time*time_convert_factor)
2777 write(qunit,'(a)')'</DataArray>'
2778 write(qunit,'(a)')'</FieldData>'
2779 offset=0
2780 recsep=4
2781
2782 call getheadernames(wnamei,xandwnamei,outfilehead)
2783
2784 ! number of cells, number of corner points, per grid.
2785 nx^d=ixmhi^d-ixmlo^d+1;
2786 nxc^d=nx^d+1;
2787 nc={nx^d*}
2788 np={nxc^d*}
2789
2790 length=np*size_real
2791 lengthcc=nc*size_real
2792
2793 length_coords=3*length
2794 length_conn=2**^nd*size_int*nc
2795 length_offsets=nc*size_int
2796
2797 ! Note: using the w_write, writelevel, writespshift
2798 ! we can clip parts of the grid away, select variables, levels etc.
2799 do level=levmin,levmax
2800 if (writelevel(level)) then
2801 do morton_no=morton_start(mype),morton_stop(mype)
2802 igrid=sfc_to_igrid(morton_no)
2803 if (node(plevel_,igrid)/=level) cycle
2804 ! only output a grid when fully within clipped region selected
2805 ! by writespshift array
2806 if (({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
2807 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
2808 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
2809 select case(convert_type)
2810 case('pvtuBmpi')
2811 ! we write out every grid as one VTK PIECE
2812 write(qunit,'(a,i7,a,i7,a)') &
2813 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
2814 write(qunit,'(a)')'<PointData>'
2815 do iw=1,nw
2816 if(.not.w_write(iw))cycle
2817
2818 write(qunit,'(a,a,a,i16,a)')&
2819 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
2820 '" format="appended" offset="',offset,'">'
2821 write(qunit,'(a)')'</DataArray>'
2822 offset=offset+length+size_int
2823 enddo
2824 do iw=nw+1,nw+nwauxio
2825
2826 write(qunit,'(a,a,a,i16,a)')&
2827 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
2828 '" format="appended" offset="',offset,'">'
2829 write(qunit,'(a)')'</DataArray>'
2830 offset=offset+length+size_int
2831 enddo
2832 write(qunit,'(a)')'</PointData>'
2833
2834 write(qunit,'(a)')'<Points>'
2835 write(qunit,'(a,i16,a)') &
2836 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
2837 ! write cell corner coordinates in a backward dimensional loop, always 3D output
2838 offset=offset+length_coords+size_int
2839 write(qunit,'(a)')'</Points>'
2840 case('pvtuBCCmpi')
2841 ! we write out every grid as one VTK PIECE
2842 write(qunit,'(a,i7,a,i7,a)') &
2843 '<Piece NumberOfPoints="',np,'" NumberOfCells="',nc,'">'
2844 write(qunit,'(a)')'<CellData>'
2845 do iw=1,nw
2846 if(.not.w_write(iw))cycle
2847
2848 write(qunit,'(a,a,a,i16,a)')&
2849 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
2850 '" format="appended" offset="',offset,'">'
2851 write(qunit,'(a)')'</DataArray>'
2852 offset=offset+lengthcc+size_int
2853 enddo
2854 do iw=nw+1,nw+nwauxio
2855
2856 write(qunit,'(a,a,a,i16,a)')&
2857 '<DataArray type="Float32" Name="',trim(wnamei(iw)), &
2858 '" format="appended" offset="',offset,'">'
2859 write(qunit,'(a)')'</DataArray>'
2860 offset=offset+lengthcc+size_int
2861 enddo
2862 write(qunit,'(a)')'</CellData>'
2863 write(qunit,'(a)')'<Points>'
2864 write(qunit,'(a,i16,a)') &
2865 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',offset,'"/>'
2866 ! write cell corner coordinates in a backward dimensional loop, always 3D output
2867 offset=offset+length_coords+size_int
2868 write(qunit,'(a)')'</Points>'
2869 end select
2870 write(qunit,'(a)')'<Cells>'
2871 ! connectivity part
2872 write(qunit,'(a,i16,a)')&
2873 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',offset,'"/>'
2874 offset=offset+length_conn+size_int
2875 ! offsets data array
2876 write(qunit,'(a,i16,a)') &
2877 '<DataArray type="Int32" Name="offsets" format="appended" offset="',offset,'"/>'
2878 offset=offset+length_offsets+size_int
2879 ! VTK cell type data array
2880 write(qunit,'(a,i16,a)') &
2881 '<DataArray type="Int32" Name="types" format="appended" offset="',offset,'"/>'
2882 offset=offset+size_int+nc*size_int
2883 write(qunit,'(a)')'</Cells>'
2884 write(qunit,'(a)')'</Piece>'
2885 end if
2886 end do
2887 end if
2888 end do
2889
2890 write(qunit,'(a)')'</UnstructuredGrid>'
2891 write(qunit,'(a)')'<AppendedData encoding="raw">'
2892 close(qunit)
2893 ! next to make gfortran compiler happy, as it does not know
2894 ! form='binary' and produces error on compilation
2895 !bufform='binary'
2896 !open(qunit,file=pfilename,form=bufform,position='append')
2897 !This should in principle do also for gfortran (tested with gfortran 4.6.0 and Intel 11.1):
2898 open(qunit,file=pfilename,access='stream',form='unformatted',position='append')
2899 buf='_'
2900 write(qunit) trim(buf)
2901
2902 do level=levmin,levmax
2903 if (writelevel(level)) then
2904 do morton_no=morton_start(mype),morton_stop(mype)
2905 igrid=sfc_to_igrid(morton_no)
2906 if (node(plevel_,igrid)/=level) cycle
2907 ! only output a grid when fully within clipped region selected
2908 ! by writespshift array
2909 if (({rnode(rpxmin^d_,igrid)>=xprobmin^d+(xprobmax^d-xprobmin^d)&
2910 *writespshift(^d,1)|.and.}).and.({rnode(rpxmax^d_,igrid)&
2911 <=xprobmax^d-(xprobmax^d-xprobmin^d)*writespshift(^d,2)|.and.})) then
2912 call calc_x(igrid,xc,xcc)
2913 call calc_grid(qunit,igrid,xc,xcc,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
2914 ixc^l,ixcc^l,.true.)
2915 do iw=1,nw
2916 if(.not.w_write(iw))cycle
2917 select case(convert_type)
2918 case('pvtuBmpi')
2919 write(qunit) length
2920 write(qunit) {(|}real(wc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixcmin^d,ixcmax^d)}
2921 case('pvtuBCCmpi')
2922 write(qunit) lengthcc
2923 write(qunit) {(|}real(wcc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixccmin^d,ixccmax^d)}
2924 end select
2925 enddo
2926 do iw=nw+1,nw+nwauxio
2927 select case(convert_type)
2928 case('pvtuBmpi')
2929 write(qunit) length
2930 write(qunit) {(|}real(wc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixcmin^d,ixcmax^d)}
2931 case('pvtuBCCmpi')
2932 write(qunit) lengthcc
2933 write(qunit) {(|}real(wcc_tmp(ix^d,iw)*normconv(iw)),{ix^d=ixccmin^d,ixccmax^d)}
2934 end select
2935 enddo
2936 write(qunit) length_coords
2937 {do ix^db=ixcmin^db,ixcmax^db \}
2938 x_vtk(1:3)=zero;
2939 x_vtk(1:ndim)=xc_tmp(ix^d,1:ndim)*normconv(0);
2940 do k=1,3
2941 write(qunit) real(x_vtk(k))
2942 end do
2943 {end do \}
2944 write(qunit) length_conn
2945 call write_connvtk_binary(qunit)
2946 write(qunit) length_offsets
2947 do icel=1,nc
2948 write(qunit) icel*(2**^nd)
2949 end do
2950 vtk_type=vtk_cell_type()
2951 write(qunit) size_int*nc
2952 do icel=1,nc
2953 write(qunit) vtk_type
2954 end do
2955 end if
2956 end do
2957 end if
2958 end do
2959
2960 close(qunit)
2961 open(qunit,file=pfilename,status='unknown',form='formatted',position='append')
2962 write(qunit,'(a)')'</AppendedData>'
2963 write(qunit,'(a)')'</VTKFile>'
2964 close(qunit)
2965
2966 end subroutine punstructuredvtkb_mpi
2967 {^iftwod
2968 ! subroutines to convert 2.5D data to 3D data
2969 subroutine unstructuredvtkb23(qunit)
2970 ! output for vtu format to paraview, binary version output
2971 ! not parallel, uses calc_grid to compute nwauxio variables
2973 use mod_physics
2975
2976 integer, intent(in) :: qunit
2977
2978 double precision :: x_VTK(1:3)
2979 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,3) :: xC_TMP
2980 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,& 3) :: xCC_TMP
2981 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,nw+nwauxio) :: wC_TMP
2982 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,nw& +nwauxio) :: wCC_TMP
2983 double precision, dimension(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1,1:nw& +nwauxio) :: w
2984 double precision :: normconv(0:nw+nwauxio)
2985 double precision :: zlength
2986 double precision ::d3grid,zlengsc,zgridsc
2987 integer*8 :: offset
2988 integer:: igrid,iigrid,level,igonlevel,icel,ixCmin1,ixCmin2,&
2989 ixCmin3,ixCmax1,ixCmax2,ixCmax3,ixCCmin1,ixCCmin2,ixCCmin3,ixCCmax1,&
2990 ixCCmax2,ixCCmax3
2991 integer:: NumGridsOnLevel(1:nlevelshi)
2992 integer :: nx1,nx2,nx3,nxC1,nxC2,nxC3,nodesonlevel,elemsonlevel,nc,np,&
2993 VTK_type,ix1,ix2,ix3
2994 integer :: size_length,recsep,k,iw
2995 integer :: length,lengthcc,offset_points,offset_cells, length_coords,&
2996 length_conn,length_offsets
2997 integer :: i3grid,n3grid
2998 logical :: fileopen
2999 character:: buffer
3000 character(len=6):: bufform
3001 character(len=80):: filename
3002 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:3+nw+nwauxio)
3003 character(len=1024) :: outfilehead
3004
3005 if(npe>1)then
3006 if(mype==0) print *,'unstructuredvtkB23 not parallel, use vtumpi'
3007 call mpistop('npe>1, unstructuredvtkB23')
3008 end if
3009
3010 offset=0
3011 recsep=4
3012 size_length=4
3013 inquire(qunit,opened=fileopen)
3014 if(.not.fileopen)then
3015 ! generate filename
3016 write(filename,'(a,a,i4.4,a)') trim(base_filename),"3D",snapshotini,".vtu"
3017 ! Open the file for the header part
3018 open(qunit,file=filename,status='replace')
3019 endif
3020 call getheadernames(wnamei,xandwnamei,outfilehead)
3021 ! generate xml header
3022 write(qunit,'(a)')'<?xml version="1.0"?>'
3023 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
3024 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
3025 write(qunit,'(a)')'<UnstructuredGrid>'
3026 write(qunit,'(a)')'<FieldData>'
3027 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
3028 'NumberOfTuples="1" format="ascii">'
3029 write(qunit,'(f10.2)') real(global_time*time_convert_factor)
3030 write(qunit,'(a)')'</DataArray>'
3031 write(qunit,'(a)')'</FieldData>'
3032
3033 ! number of cells, number of corner points, per grid.
3034 nx1=ixmhi1-ixmlo1+1;nx2=ixmhi2-ixmlo2+1;nx3=ixmhi1-ixmlo1+1;
3035 nxc1=nx1+1;nxc2=nx2+1;nxc3=nx3+1;
3036 nc=nx1*nx2*nx3
3037 np=nxc1*nxc2*nxc3
3038
3039 length=np*size_real
3040 lengthcc=nc*size_real
3041
3042 length_coords=3*length
3043 length_conn=2**3*size_int*nc
3044 length_offsets=nc*size_int
3045
3046 ! Note: using the w_write, writelevel, writespshift
3047 ! we can clip parts of the grid away, select variables, levels etc.
3048 zgridsc=2.d0
3049 zlengsc=2.d0*zgridsc
3050 zlength=zlengsc*(xprobmax1-xprobmin1)
3051 do level=levmin,levmax
3052 if (writelevel(level)) then
3053 do iigrid=1,igridstail; igrid=igrids(iigrid);
3054 if (node(plevel_,igrid)/=level) cycle
3055 block=>ps(igrid)
3056 ! only output a grid when fully within clipped region selected
3057 ! by writespshift array
3058 if ((rnode(rpxmin1_,igrid)>=xprobmin1+(xprobmax1-xprobmin1)&
3059 *writespshift(1,1).and.rnode(rpxmin2_,igrid)>=xprobmin2&
3060 +(xprobmax2-xprobmin2)*writespshift(2,1))&
3061 .and.(rnode(rpxmax1_,igrid)<=xprobmax1-(xprobmax1-xprobmin1)&
3062 *writespshift(1,2).and.rnode(rpxmax2_,igrid)<=xprobmax2-(xprobmax2&
3063 -xprobmin2)*writespshift(2,2))) then
3064 d3grid=zgridsc*(rnode(rpxmax1_,igrid)-rnode(rpxmin1_,igrid))
3065 n3grid=nint(zlength/d3grid)
3066 do i3grid=1,n3grid !subcycles
3067 select case(convert_type)
3068 case('vtuB23')
3069 ! we write out every grid as one VTK PIECE
3070 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3071 '" NumberOfCells="',nc,'">'
3072 write(qunit,'(a)')'<PointData>'
3073 do iw=1,nw
3074 if(.not.w_write(iw))cycle
3075 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3076 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3077 write(qunit,'(a)')'</DataArray>'
3078 offset=offset+length+size_int
3079 enddo
3080 if(nwauxio>0)then
3081 do iw=nw+1,nw+nwauxio
3082 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3083 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3084 write(qunit,'(a)')'</DataArray>'
3085 offset=offset+length+size_int
3086 enddo
3087 endif
3088 write(qunit,'(a)')'</PointData>'
3089
3090 write(qunit,'(a)')'<Points>'
3091 write(qunit,'(a,i16,a)') &
3092 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3093 offset,'"/>'
3094 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3095 offset=offset+length_coords+size_int
3096 write(qunit,'(a)')'</Points>'
3097 case('vtuBCC23')
3098 ! we write out every grid as one VTK PIECE
3099 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3100 '" NumberOfCells="',nc,'">'
3101 write(qunit,'(a)')'<CellData>'
3102 do iw=1,nw
3103 if(.not.w_write(iw))cycle
3104 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3105 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3106 write(qunit,'(a)')'</DataArray>'
3107 offset=offset+lengthcc+size_int
3108 enddo
3109 if(nwauxio>0)then
3110 do iw=nw+1,nw+nwauxio
3111 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3112 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3113 write(qunit,'(a)')'</DataArray>'
3114 offset=offset+lengthcc+size_int
3115 enddo
3116 endif
3117 write(qunit,'(a)')'</CellData>'
3118 write(qunit,'(a)')'<Points>'
3119 write(qunit,'(a,i16,a)') &
3120 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3121 offset,'"/>'
3122 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3123 offset=offset+length_coords+size_int
3124 write(qunit,'(a)')'</Points>'
3125 end select
3126 write(qunit,'(a)')'<Cells>'
3127 ! connectivity part
3128 write(qunit,'(a,i16,a)')&
3129 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',&
3130 offset,'"/>'
3131 offset=offset+length_conn+size_int
3132 ! offsets data array
3133 write(qunit,'(a,i16,a)') &
3134 '<DataArray type="Int32" Name="offsets" format="appended" offset="',&
3135 offset,'"/>'
3136 offset=offset+length_offsets+size_int
3137 ! VTK cell type data array
3138 write(qunit,'(a,i16,a)') &
3139 '<DataArray type="Int32" Name="types" format="appended" offset="',&
3140 offset,'"/>'
3141 offset=offset+size_length+nc*size_int
3142 write(qunit,'(a)')'</Cells>'
3143 write(qunit,'(a)')'</Piece>'
3144 end do !subcycles
3145 end if
3146 end do
3147 end if
3148 end do
3149
3150 write(qunit,'(a)')'</UnstructuredGrid>'
3151 write(qunit,'(a)')'<AppendedData encoding="raw">'
3152 close(qunit)
3153 open(qunit,file=filename,form='unformatted',access='stream',status='old',position='append')
3154 buffer='_'
3155 write(qunit) trim(buffer)
3156
3157 do level=levmin,levmax
3158 if (writelevel(level)) then
3159 do iigrid=1,igridstail; igrid=igrids(iigrid);
3160 if (node(plevel_,igrid)/=level) cycle
3161 block=>ps(igrid)
3162 ! only output a grid when fully within clipped region selected
3163 ! by writespshift array
3164 if ((rnode(rpxmin1_,igrid)>=xprobmin1+(xprobmax1-xprobmin1)&
3165 *writespshift(1,1).and.rnode(rpxmin2_,igrid)>=xprobmin2&
3166 +(xprobmax2-xprobmin2)*writespshift(2,1))&
3167 .and.(rnode(rpxmax1_,igrid)<=xprobmax1-(xprobmax1-xprobmin1)&
3168 *writespshift(1,2).and.rnode(rpxmax2_,igrid)<=xprobmax2-(xprobmax2&
3169 -xprobmin2)*writespshift(2,2))) then
3170 d3grid=zgridsc*(rnode(rpxmax1_,igrid)-rnode(rpxmin1_,igrid))
3171 n3grid=nint(zlength/d3grid)
3172 ! In case primitives to be saved: use primitive subroutine
3173 ! extra layer around mesh only needed when storing corner values and averaging
3174 if(saveprim) then
3175 call phys_to_primitive(ixglo1,ixglo2,ixghi1,ixghi2,&
3176 ixglo1,ixglo2,ixghi1,ixghi2,ps(igrid)%w,ps(igrid)%x)
3177 endif
3178 ! using array w so that new output auxiliaries can be calculated by the user
3179 ! extend 2D data to 3D insuring variables are independent on the third coordinate
3180 do ix3=ixglo1,ixghi1
3181 w(ixglo1:ixghi1,ixglo2:ixghi2,ix3,1:nw)=ps(igrid)%w(ixglo1:ixghi1,&
3182 ixglo2:ixghi2,1:nw)
3183 end do
3184 do i3grid=1,n3grid !subcycles
3185 call calc_grid23(qunit,igrid,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
3186 ixcmin1,ixcmin2,ixcmin3,ixcmax1,ixcmax2,ixcmax3,ixccmin1,ixccmin2,&
3187 ixccmin3,ixccmax1,ixccmax2,ixccmax3,.true.,i3grid,d3grid,w,zlength,zgridsc)
3188 do iw=1,nw
3189 if(.not.w_write(iw))cycle
3190 select case(convert_type)
3191 case('vtuB23')
3192 write(qunit) length
3193 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3194 =ixcmin1,ixcmax1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3195 case('vtuBCC23')
3196 write(qunit) lengthcc
3197 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3198 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3199 =ixccmin3,ixccmax3)
3200 end select
3201 enddo
3202 if(nwauxio>0)then
3203 do iw=nw+1,nw+nwauxio
3204 select case(convert_type)
3205 case('vtuB23')
3206 write(qunit) length
3207 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3208 =ixcmin1,ixcmax1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3209 case('vtuBCC23')
3210 write(qunit) lengthcc
3211 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3212 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3213 =ixccmin3,ixccmax3)
3214 end select
3215 end do
3216 end if
3217 write(qunit) length_coords
3218 do ix3=ixcmin3,ixcmax3
3219 do ix2=ixcmin2,ixcmax2
3220 do ix1=ixcmin1,ixcmax1
3221 x_vtk(1:3)=zero;
3222 x_vtk(1:3)=xc_tmp(ix1,ix2,ix3,1:3)*normconv(0);
3223 do k=1,3
3224 write(qunit) real(x_vtk(k))
3225 end do
3226 end do
3227 end do
3228 end do
3229 write(qunit) length_conn
3230 do ix3=1,nx3
3231 do ix2=1,nx2
3232 do ix1=1,nx1
3233 write(qunit)&
3234 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
3235 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3236 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3237 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
3238 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
3239 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3240 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3241 ix3*nxc2*nxc1+ ix2*nxc1+ix1
3242 end do
3243 end do
3244 end do
3245 write(qunit) length_offsets
3246 do icel=1,nc
3247 write(qunit) icel*(2**3)
3248 end do
3249 vtk_type=11
3250 write(qunit) size_int*nc
3251 do icel=1,nc
3252 write(qunit) vtk_type
3253 end do
3254 end do !subcycles
3255 end if
3256 end do
3257 end if
3258 end do
3259
3260 close(qunit)
3261 open(qunit,file=filename,status='unknown',form='formatted',position='append')
3262
3263 write(qunit,'(a)')'</AppendedData>'
3264 write(qunit,'(a)')'</VTKFile>'
3265 close(qunit)
3266
3267 end subroutine unstructuredvtkb23
3268
3269 subroutine unstructuredvtkbsym23(qunit)
3270 ! output for vtu format to paraview, binary version output
3271 ! not parallel, uses calc_grid to compute nwauxio variables
3272 ! use this subroutine when the physical domain is symmetric/asymmetric about (0,y,z)
3273 ! plane, xprobmin1=0 and the computational domain is a half of the physical domain
3275 use mod_physics
3277
3278 integer, intent(in) :: qunit
3279
3280 double precision :: x_VTK(1:3)
3281 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,3) :: xC_TMP
3282 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,& 3) :: xCC_TMP
3283 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,nw+nwauxio) :: wC_TMP
3284 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,nw& +nwauxio) :: wCC_TMP
3285 double precision, dimension(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1,1:nw& +nwauxio) :: w
3286 double precision :: normconv(0:nw+nwauxio)
3287 double precision ::d3grid,zlengsc,zgridsc
3288 double precision :: zlength
3289 integer*8 :: offset
3290 integer:: igrid,iigrid,level,igonlevel,icel,ixCmin1,ixCmin2,&
3291 ixCmin3,ixCmax1,ixCmax2,ixCmax3,ixCCmin1,ixCCmin2,ixCCmin3,ixCCmax1,&
3292 ixCCmax2,ixCCmax3
3293 integer:: NumGridsOnLevel(1:nlevelshi)
3294 integer :: nx1,nx2,nx3,nxC1,nxC2,nxC3,nodesonlevel,elemsonlevel,nc,np,&
3295 VTK_type,ix1,ix2,ix3
3296 integer :: size_length,recsep,k,iw
3297 integer :: length,lengthcc,offset_points,offset_cells, length_coords,&
3298 length_conn,length_offsets
3299 integer :: i3grid,n3grid
3300 logical :: fileopen
3301 character(len=80):: filename
3302 character(len=name_len) :: wnamei(1:nw+nwauxio),xandwnamei(1:3+nw+nwauxio)
3303 character(len=1024) :: outfilehead
3304 character:: buffer
3305 character(len=6):: bufform
3306
3307 if(npe>1)then
3308 if(mype==0) print *,'unstructuredvtkBsym23 not parallel, use vtumpi'
3309 call mpistop('npe>1, unstructuredvtkBsym23')
3310 end if
3311
3312 offset=0
3313 recsep=4
3314 size_length=4
3315
3316 inquire(qunit,opened=fileopen)
3317 if(.not.fileopen)then
3318 ! generate filename
3319 write(filename,'(a,a,i4.4,a)') trim(base_filename),"3D",snapshotini,".vtu"
3320 ! Open the file for the header part
3321 open(qunit,file=filename,status='unknown')
3322 end if
3323
3324 call getheadernames(wnamei,xandwnamei,outfilehead)
3325 ! generate xml header
3326 write(qunit,'(a)')'<?xml version="1.0"?>'
3327 write(qunit,'(a)',advance='no') '<VTKFile type="UnstructuredGrid"'
3328 write(qunit,'(a)')' version="0.1" byte_order="LittleEndian">'
3329 write(qunit,'(a)')'<UnstructuredGrid>'
3330 write(qunit,'(a)')'<FieldData>'
3331 write(qunit,'(2a)')'<DataArray type="Float32" Name="TIME" ',&
3332 'NumberOfTuples="1" format="ascii">'
3333 write(qunit,'(f10.2)') real(global_time*time_convert_factor)
3334 write(qunit,'(a)')'</DataArray>'
3335 write(qunit,'(a)')'</FieldData>'
3336
3337 ! number of cells, number of corner points, per grid.
3338 nx1=ixmhi1-ixmlo1+1;nx2=ixmhi2-ixmlo2+1;nx3=ixmhi1-ixmlo1+1;
3339 nxc1=nx1+1;nxc2=nx2+1;nxc3=nx3+1;
3340 nc=nx1*nx2*nx3
3341 np=nxc1*nxc2*nxc3
3342
3343 length=np*size_real
3344 lengthcc=nc*size_real
3345
3346 length_coords=3*length
3347 length_conn=2**3*size_int*nc
3348 length_offsets=nc*size_int
3349
3350 ! Note: using the w_write, writelevel, writespshift
3351 ! we can clip parts of the grid away, select variables, levels etc.
3352 zlengsc=4.d0
3353 zgridsc=2.d0
3354 zlength=zlengsc*(xprobmax1-xprobmin1)
3355 do level=levmin,levmax
3356 if (writelevel(level)) then
3357 do iigrid=1,igridstail; igrid=igrids(iigrid);
3358 if (node(plevel_,igrid)/=level) cycle
3359 block=>ps(igrid)
3360 ! only output a grid when fully within clipped region selected
3361 ! by writespshift array
3362 if ((rnode(rpxmin1_,igrid)>=xprobmin1+(xprobmax1-xprobmin1)&
3363 *writespshift(1,1).and.rnode(rpxmin2_,igrid)>=xprobmin2&
3364 +(xprobmax2-xprobmin2)*writespshift(2,1))&
3365 .and.(rnode(rpxmax1_,igrid)<=xprobmax1-(xprobmax1-xprobmin1)&
3366 *writespshift(1,2).and.rnode(rpxmax2_,igrid)<=xprobmax2-(xprobmax2&
3367 -xprobmin2)*writespshift(2,2))) then
3368 d3grid=zgridsc*(rnode(rpxmax1_,igrid)-rnode(rpxmin1_,igrid))
3369 n3grid=nint(zlength/d3grid)
3370 do i3grid=1,n3grid !subcycles
3371 !! original domain ----------------------------------start
3372 select case(convert_type)
3373 case('vtuBsym23')
3374 ! we write out every grid as one VTK PIECE
3375 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3376 '" NumberOfCells="',nc,'">'
3377 write(qunit,'(a)')'<PointData>'
3378 do iw=1,nw
3379 if(.not.w_write(iw))cycle
3380 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3381 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3382 write(qunit,'(a)')'</DataArray>'
3383 offset=offset+length+size_length
3384 enddo
3385 if(nwauxio>0)then
3386 do iw=nw+1,nw+nwauxio
3387 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3388 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3389 write(qunit,'(a)')'</DataArray>'
3390 offset=offset+length+size_length
3391 enddo
3392 endif
3393 write(qunit,'(a)')'</PointData>'
3394 write(qunit,'(a)')'<Points>'
3395 write(qunit,'(a,i16,a)') &
3396 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3397 offset,'"/>'
3398 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3399 offset=offset+length_coords+size_length
3400 write(qunit,'(a)')'</Points>'
3401 case('vtuBCCsym23')
3402 ! we write out every grid as one VTK PIECE
3403 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3404 '" NumberOfCells="',nc,'">'
3405 write(qunit,'(a)')'<CellData>'
3406 do iw=1,nw
3407 if(.not.w_write(iw))cycle
3408 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3409 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3410 write(qunit,'(a)')'</DataArray>'
3411 offset=offset+lengthcc+size_length
3412 enddo
3413 if(nwauxio>0)then
3414 do iw=nw+1,nw+nwauxio
3415 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3416 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3417 write(qunit,'(a)')'</DataArray>'
3418 offset=offset+lengthcc+size_length
3419 enddo
3420 endif
3421 write(qunit,'(a)')'</CellData>'
3422
3423 write(qunit,'(a)')'<Points>'
3424 write(qunit,'(a,i16,a)') &
3425 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3426 offset,'"/>'
3427 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3428 offset=offset+length_coords+size_length
3429 write(qunit,'(a)')'</Points>'
3430 end select
3431 write(qunit,'(a)')'<Cells>'
3432 ! connectivity part
3433 write(qunit,'(a,i16,a)')&
3434 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',&
3435 offset,'"/>'
3436 offset=offset+length_conn+size_length
3437 ! offsets data array
3438 write(qunit,'(a,i16,a)') &
3439 '<DataArray type="Int32" Name="offsets" format="appended" offset="',&
3440 offset,'"/>'
3441 offset=offset+length_offsets+size_length
3442 ! VTK cell type data array
3443 write(qunit,'(a,i16,a)') &
3444 '<DataArray type="Int32" Name="types" format="appended" offset="',&
3445 offset,'"/>'
3446 offset=offset+size_length+nc*size_int
3447 write(qunit,'(a)')'</Cells>'
3448 write(qunit,'(a)')'</Piece>'
3449 !! original domain ----------------------------------end
3450 !! symetric/asymetric mirror domain -----------------start
3451 select case(convert_type)
3452 case('vtuBsym23')
3453 ! we write out every grid as one VTK PIECE
3454 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3455 '" NumberOfCells="',nc,'">'
3456 write(qunit,'(a)')'<PointData>'
3457 do iw=1,nw
3458 if(.not.w_write(iw))cycle
3459 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3460 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3461 write(qunit,'(a)')'</DataArray>'
3462 offset=offset+length+size_length
3463 enddo
3464 if(nwauxio>0)then
3465 do iw=nw+1,nw+nwauxio
3466 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3467 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3468 write(qunit,'(a)')'</DataArray>'
3469 offset=offset+length+size_length
3470 enddo
3471 endif
3472 write(qunit,'(a)')'</PointData>'
3473 write(qunit,'(a)')'<Points>'
3474 write(qunit,'(a,i16,a)') &
3475 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3476 offset,'"/>'
3477 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3478 offset=offset+length_coords+size_length
3479 write(qunit,'(a)')'</Points>'
3480 case('vtuBCCsym23')
3481 ! we write out every grid as one VTK PIECE
3482 write(qunit,'(a,i7,a,i7,a)') '<Piece NumberOfPoints="',np,&
3483 '" NumberOfCells="',nc,'">'
3484 write(qunit,'(a)')'<CellData>'
3485 do iw=1,nw
3486 if(.not.w_write(iw))cycle
3487 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3488 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3489 write(qunit,'(a)')'</DataArray>'
3490 offset=offset+lengthcc+size_length
3491 enddo
3492 if(nwauxio>0)then
3493 do iw=nw+1,nw+nwauxio
3494 write(qunit,'(a,a,a,i16,a)')'<DataArray type="Float32" Name="',&
3495 trim(wnamei(iw)), '" format="appended" offset="',offset,'">'
3496 write(qunit,'(a)')'</DataArray>'
3497 offset=offset+lengthcc+size_length
3498 enddo
3499 endif
3500 write(qunit,'(a)')'</CellData>'
3501 write(qunit,'(a)')'<Points>'
3502 write(qunit,'(a,i16,a)') &
3503 '<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="',&
3504 offset,'"/>'
3505 ! write cell corner coordinates in a backward dimensional loop, always 3D output
3506 offset=offset+length_coords+size_length
3507 write(qunit,'(a)')'</Points>'
3508 end select
3509 write(qunit,'(a)')'<Cells>'
3510 ! connectivity part
3511 write(qunit,'(a,i16,a)')&
3512 '<DataArray type="Int32" Name="connectivity" format="appended" offset="',&
3513 offset,'"/>'
3514 offset=offset+length_conn+size_length
3515 ! offsets data array
3516 write(qunit,'(a,i16,a)') &
3517 '<DataArray type="Int32" Name="offsets" format="appended" offset="',&
3518 offset,'"/>'
3519 offset=offset+length_offsets+size_length
3520 ! VTK cell type data array
3521 write(qunit,'(a,i16,a)') &
3522 '<DataArray type="Int32" Name="types" format="appended" offset="',&
3523 offset,'"/>'
3524 offset=offset+size_length+nc*size_int
3525 write(qunit,'(a)')'</Cells>'
3526 write(qunit,'(a)')'</Piece>'
3527 !! symetric/asymetric mirror domain -----------------end
3528 end do !subcycles
3529 end if
3530 end do
3531 end if
3532 end do
3533
3534 write(qunit,'(a)')'</UnstructuredGrid>'
3535 write(qunit,'(a)')'<AppendedData encoding="raw">'
3536 close(qunit)
3537 open(qunit,file=filename,form='unformatted',access='stream',status='old',position='append')
3538 buffer='_'
3539 write(qunit) trim(buffer)
3540 do level=levmin,levmax
3541 if (writelevel(level)) then
3542 do iigrid=1,igridstail; igrid=igrids(iigrid);
3543 if (node(plevel_,igrid)/=level) cycle
3544 block=>ps(igrid)
3545 ! only output a grid when fully within clipped region selected
3546 ! by writespshift array
3547 if ((rnode(rpxmin1_,igrid)>=xprobmin1+(xprobmax1-xprobmin1)&
3548 *writespshift(1,1).and.rnode(rpxmin2_,igrid)>=xprobmin2&
3549 +(xprobmax2-xprobmin2)*writespshift(2,1))&
3550 .and.(rnode(rpxmax1_,igrid)<=xprobmax1-(xprobmax1-xprobmin1)&
3551 *writespshift(1,2).and.rnode(rpxmax2_,igrid)<=xprobmax2-(xprobmax2&
3552 -xprobmin2)*writespshift(2,2))) then
3553 d3grid=zgridsc*(rnode(rpxmax1_,igrid)-rnode(rpxmin1_,igrid))
3554 n3grid=nint(zlength/d3grid)
3555 ! In case primitives to be saved: use primitive subroutine
3556 ! extra layer around mesh only needed when storing corner values and averaging
3557 if(saveprim) then
3558 call phys_to_primitive(ixglo1,ixglo2,ixghi1,ixghi2,&
3559 ixglo1,ixglo2,ixghi1,ixghi2,ps(igrid)%w,ps(igrid)%x)
3560 endif
3561 ! using array w so that new output auxiliaries can be calculated by the user
3562 ! extend 2D data to 3D insuring variables are independent on the third coordinate
3563 do ix3=ixglo1,ixghi1
3564 w(ixglo1:ixghi1,ixglo2:ixghi2,ix3,1:nw)=ps(igrid)%w(ixglo1:ixghi1,&
3565 ixglo2:ixghi2,1:nw)
3566 end do
3567 do i3grid=1,n3grid !subcycles
3568 call calc_grid23(qunit,igrid,xc_tmp,xcc_tmp,wc_tmp,wcc_tmp,normconv,&
3569 ixcmin1,ixcmin2,ixcmin3,ixcmax1,ixcmax2,ixcmax3,ixccmin1,ixccmin2,&
3570 ixccmin3,ixccmax1,ixccmax2,ixccmax3,.true.,i3grid,d3grid,w,zlength,zgridsc)
3571 !! original domain ----------------------------------start
3572 do iw=1,nw
3573 if(.not.w_write(iw))cycle
3574 select case(convert_type)
3575 case('vtuBsym23')
3576 write(qunit) length
3577 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3578 =ixcmin1,ixcmax1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3579 case('vtuBCCsym23')
3580 write(qunit) lengthcc
3581 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3582 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3583 =ixccmin3,ixccmax3)
3584 end select
3585 enddo
3586 if(nwauxio>0)then
3587 do iw=nw+1,nw+nwauxio
3588 select case(convert_type)
3589 case('vtuBsym23')
3590 write(qunit) length
3591 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3592 =ixcmin1,ixcmax1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3593 case('vtuBCCsym23')
3594 write(qunit) lengthcc
3595 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3596 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3597 =ixccmin3,ixccmax3)
3598 end select
3599 enddo
3600 endif
3601 write(qunit) length_coords
3602 do ix3=ixcmin3,ixcmax3
3603 do ix2=ixcmin2,ixcmax2
3604 do ix1=ixcmin1,ixcmax1
3605 x_vtk(1:3)=zero;
3606 x_vtk(1:3)=xc_tmp(ix1,ix2,ix3,1:3)*normconv(0);
3607 do k=1,3
3608 write(qunit) real(x_vtk(k))
3609 end do
3610 end do
3611 end do
3612 end do
3613 write(qunit) length_conn
3614 do ix3=1,nx3
3615 do ix2=1,nx2
3616 do ix1=1,nx1
3617 write(qunit)&
3618 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
3619 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3620 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3621 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
3622 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
3623 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3624 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3625 ix3*nxc2*nxc1+ ix2*nxc1+ix1
3626 end do
3627 end do
3628 end do
3629 write(qunit) length_offsets
3630 do icel=1,nc
3631 write(qunit) icel*(2**3)
3632 end do
3633 vtk_type=11
3634 write(qunit) size_int*nc
3635 do icel=1,nc
3636 write(qunit) vtk_type
3637 end do
3638 !! original domain ----------------------------------end
3639 !! symetric/asymetric mirror domain -----------------start
3640 do iw=1,nw
3641 if(.not.w_write(iw))cycle
3642 if(iw==2 .or. iw==4 .or. iw==7) then
3643 wc_tmp(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,iw)=&
3644 -wc_tmp(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,iw)
3645 wcc_tmp(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,iw)=&
3646 -wcc_tmp(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,iw)
3647 end if
3648 select case(convert_type)
3649 case('vtuBsym23')
3650 write(qunit) length
3651 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3652 =ixcmax1,ixcmin1,-1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3653 case('vtuBCCsym23')
3654 write(qunit) lengthcc
3655 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3656 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3657 =ixccmin3,ixccmax3)
3658 end select
3659 enddo
3660 if(nwauxio>0)then
3661 do iw=nw+1,nw+nwauxio
3662 select case(convert_type)
3663 case('vtuBsym23')
3664 write(qunit) length
3665 write(qunit) (((real(wc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3666 =ixcmax1,ixcmin1,-1),ix2=ixcmin2,ixcmax2),ix3=ixcmin3,ixcmax3)
3667 case('vtuBCCsym23')
3668 write(qunit) lengthcc
3669 write(qunit) (((real(wcc_tmp(ix1,ix2,ix3,iw)*normconv(iw)),ix1&
3670 =ixccmin1,ixccmax1),ix2=ixccmin2,ixccmax2),ix3&
3671 =ixccmin3,ixccmax3)
3672 end select
3673 end do
3674 end if
3675 write(qunit) length_coords
3676 do ix3=ixcmin3,ixcmax3
3677 do ix2=ixcmin2,ixcmax2
3678 do ix1=ixcmax1,ixcmin1,-1
3679 x_vtk(1:3)=zero;
3680 x_vtk(1:3)=xc_tmp(ix1,ix2,ix3,1:3)*normconv(0);
3681 x_vtk(1)=-x_vtk(1)
3682 do k=1,3
3683 write(qunit) real(x_vtk(k))
3684 end do
3685 end do
3686 end do
3687 end do
3688 write(qunit) length_conn
3689 do ix3=1,nx3
3690 do ix2=1,nx2
3691 do ix1=nx1,1,-1
3692 write(qunit)&
3693 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
3694 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3695 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3696 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
3697 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
3698 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3699 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3700 ix3*nxc2*nxc1+ ix2*nxc1+ix1
3701 end do
3702 end do
3703 end do
3704 write(qunit) length_offsets
3705 do icel=1,nc
3706 write(qunit) icel*(2**3)
3707 end do
3708 vtk_type=11
3709 write(qunit) size_int*nc
3710 do icel=1,nc
3711 write(qunit) vtk_type
3712 end do
3713 !! symetric/asymetric mirror domain -----------------end
3714 end do !subcycles
3715 end if
3716 end do
3717 end if
3718 end do
3719 close(qunit)
3720 open(qunit,file=filename,status='unknown',form='formatted',position='append')
3721 write(qunit,'(a)')'</AppendedData>'
3722 write(qunit,'(a)')'</VTKFile>'
3723 close(qunit)
3724
3725 end subroutine unstructuredvtkbsym23
3726
3727 subroutine calc_grid23(qunit,igrid,xC_TMP,xCC_TMP,wC_TMP,wCC_TMP,normconv,&
3728 ixCmin1,ixCmin2,ixCmin3,ixCmax1,ixCmax2,ixCmax3,ixCCmin1,ixCCmin2,ixCCmin3,&
3729 ixCCmax1,ixCCmax2,ixCCmax3,first,i3grid,d3grid,w,zlength,zgridsc)
3730 ! this subroutine computes both corner as well as cell-centered values
3731 ! it handles how we do the center to corner averaging, as well as
3732 ! whether we switch to cartesian or want primitive or conservative output,
3733 ! handling the addition of B0 in B0+B1 cases, ...
3734 ! the normconv is passed on to specialvar_output for extending with
3735 ! possible normalization values for the nw+1:nw+nwauxio entries
3737 integer, intent(in) :: qunit, igrid,i3grid
3738 logical, intent(in) :: first
3739
3740 double precision :: dx1,dx2,dx3,d3grid,zlength,zgridsc
3741 double precision :: ldw(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1),&
3742 dwC(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1)
3743 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,3) :: xC
3744 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,& 3) :: xCC
3745 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,nw+nwauxio) :: wC
3746 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,nw& +nwauxio) :: wCC
3747 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,3) :: xC_TMP
3748 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,& 3) :: xCC_TMP
3749 double precision, dimension(ixMlo1-1:ixMhi1,ixMlo2-1:ixMhi2,ixMlo1& -1:ixMhi1,nw+nwauxio) :: wC_TMP
3750 double precision, dimension(ixMlo1:ixMhi1,ixMlo2:ixMhi2,ixMlo1:ixMhi1,nw& +nwauxio) :: wCC_TMP
3751 double precision, dimension(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1,1:nw& +nwauxio) :: w
3752 double precision,dimension(0:nw+nwauxio) :: normconv
3753 integer :: nx1,nx2,nx3, nxC1,nxC2,nxC3, ix1,ix2,ix3, ix, iw, level, idir
3754 integer :: ixCmin1,ixCmin2,ixCmin3,ixCmax1,ixCmax2,ixCmax3,ixCCmin1,&
3755 ixCCmin2,ixCCmin3,ixCCmax1,ixCCmax2,ixCCmax3,nxCC1,nxCC2,nxCC3
3756 integer :: idims,jxCmin1,jxCmin2,jxCmin3,jxCmax1,jxCmax2,jxCmax3
3757 logical, save :: subfirst=.true.
3758
3759 ! following only for allowing compiler to go through with debug on
3760 nx1=ixmhi1-ixmlo1+1;nx2=ixmhi2-ixmlo2+1;nx3=ixmhi1-ixmlo1+1;
3761 level=node(plevel_,igrid)
3762 dx1=dx(1,level);dx2=dx(2,level);dx3=zgridsc*dx(1,level);
3763 ! for normalization within the code
3764 if(saveprim) then
3765 normconv(0) = length_convert_factor
3766 normconv(1:nw) = w_convert_factor
3767 else
3768 normconv(0)=length_convert_factor
3769 ! assuming density
3770 normconv(1)=w_convert_factor(1)
3771 ! assuming momentum=density*velocity
3772 if (nw>=2) normconv(2:2+3)=w_convert_factor(1)*w_convert_factor(2:2+3)
3773 ! assuming energy/pressure and magnetic field
3774 if (nw>=2+3) normconv(2+3:nw)=w_convert_factor(2+3:nw)
3775 end if
3776 ! coordinates of cell centers
3777 nxcc1=nx1;nxcc2=nx2;nxcc3=nx3;
3778 ixccmin1=ixmlo1;ixccmin2=ixmlo2;ixccmin3=ixmlo1; ixccmax1=ixmhi1
3779 ixccmax2=ixmhi2;ixccmax3=ixmhi1;
3780 do ix=ixccmin1,ixccmax1
3781 xcc(ix,ixccmin2:ixccmax2,ixccmin3:ixccmax3,1)=rnode(rpxmin1_,igrid)&
3782 +(dble(ix-ixccmin1)+half)*dx1
3783 end do
3784 do ix=ixccmin2,ixccmax2
3785 xcc(ixccmin1:ixccmax1,ix,ixccmin3:ixccmax3,2)=rnode(rpxmin2_,igrid)&
3786 +(dble(ix-ixccmin2)+half)*dx2
3787 end do
3788 do ix=ixccmin3,ixccmax3
3789 xcc(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ix,3)=-zlength/two+&
3790 dble(i3grid-1)*d3grid+(dble(ix-ixccmin3)+half)*dx3
3791 end do
3792
3793 ! coordinates of cell corners
3794 nxc1=nx1+1;nxc2=nx2+1;nxc3=nx3+1;
3795 ixcmin1=ixmlo1-1;ixcmin2=ixmlo2-1;ixcmin3=ixmlo1-1; ixcmax1=ixmhi1
3796 ixcmax2=ixmhi2;ixcmax3=ixmhi1;
3797 do ix=ixcmin1,ixcmax1
3798 xc(ix,ixcmin2:ixcmax2,ixcmin3:ixcmax3,1)=rnode(rpxmin1_,igrid)&
3799 +dble(ix-ixcmin1)*dx1
3800 end do
3801 do ix=ixcmin2,ixcmax2
3802 xc(ixcmin1:ixcmax1,ix,ixcmin3:ixcmax3,2)=rnode(rpxmin2_,igrid)&
3803 +dble(ix-ixcmin2)*dx2
3804 end do
3805 do ix=ixcmin3,ixcmax3
3806 xc(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ix,3)=-zlength/two+&
3807 dble(i3grid-1)*d3grid+dble(ix-ixcmin3)*dx3
3808 end do
3809
3810 if (nwextra>0) then
3811 ! here we actually fill the ghost layers for the nwextra variables using
3812 ! continuous extrapolation (as these values do not exist normally in ghost
3813 ! cells)
3814 do idims=1,3
3815 select case(idims)
3816 case(1)
3817 jxcmin1=ixghi1+1-nghostcells;jxcmin2=ixglo2;jxcmin3=ixglo1;
3818 jxcmax1=ixghi1;jxcmax2=ixghi2;jxcmax3=ixghi1;
3819 do ix1=jxcmin1,jxcmax1
3820 w(ix1,jxcmin2:jxcmax2,jxcmin3:jxcmax3,nw-nwextra+1:nw) = w(jxcmin1&
3821 -1,jxcmin2:jxcmax2,jxcmin3:jxcmax3,nw-nwextra+1:nw)
3822 end do
3823 jxcmin1=ixglo1;jxcmin2=ixglo2;jxcmin3=ixglo1;
3824 jxcmax1=ixglo1-1+nghostcells;jxcmax2=ixghi2;jxcmax3=ixghi1;
3825 do ix1=jxcmin1,jxcmax1
3826 w(ix1,jxcmin2:jxcmax2,jxcmin3:jxcmax3,nw-nwextra+1:nw) = w(jxcmax1&
3827 +1,jxcmin2:jxcmax2,jxcmin3:jxcmax3,nw-nwextra+1:nw)
3828 end do
3829 case(2)
3830 jxcmin1=ixglo1;jxcmin2=ixghi2+1-nghostcells;jxcmin3=ixglo1;
3831 jxcmax1=ixghi1;jxcmax2=ixghi2;jxcmax3=ixghi1;
3832 do ix2=jxcmin2,jxcmax2
3833 w(jxcmin1:jxcmax1,ix2,jxcmin3:jxcmax3,nw-nwextra+1:nw) &
3834 = w(jxcmin1:jxcmax1,jxcmin2-1,jxcmin3:jxcmax3,nw-nwextra+1:nw)
3835 end do
3836 jxcmin1=ixglo1;jxcmin2=ixglo2;jxcmin3=ixglo1;
3837 jxcmax1=ixghi1;jxcmax2=ixglo2-1+nghostcells;jxcmax3=ixghi1;
3838 do ix2=jxcmin2,jxcmax2
3839 w(jxcmin1:jxcmax1,ix2,jxcmin3:jxcmax3,nw-nwextra+1:nw) &
3840 = w(jxcmin1:jxcmax1,jxcmax2+1,jxcmin3:jxcmax3,nw-nwextra+1:nw)
3841 end do
3842 case(3)
3843 jxcmin1=ixglo1;jxcmin2=ixglo2;jxcmin3=ixghi1+1-nghostcells;
3844 jxcmax1=ixghi1;jxcmax2=ixghi2;jxcmax3=ixghi1;
3845 do ix3=jxcmin3,jxcmax3
3846 w(jxcmin1:jxcmax1,jxcmin2:jxcmax2,ix3,nw-nwextra+1:nw) &
3847 = w(jxcmin1:jxcmax1,jxcmin2:jxcmax2,jxcmin3-1,nw-nwextra+1:nw)
3848 end do
3849 jxcmin1=ixglo1;jxcmin2=ixglo2;jxcmin3=ixglo1;
3850 jxcmax1=ixghi1;jxcmax2=ixghi2;jxcmax3=ixglo1-1+nghostcells;
3851 do ix3=jxcmin3,jxcmax3
3852 w(jxcmin1:jxcmax1,jxcmin2:jxcmax2,ix3,nw-nwextra+1:nw) &
3853 = w(jxcmin1:jxcmax1,jxcmin2:jxcmax2,jxcmax3+1,nw-nwextra+1:nw)
3854 end do
3855 end select
3856 end do
3857 end if
3858 ! next lines needed when specialvar_output uses gradients
3859 ! and later on when dwlimiter2 is used
3860 if(nwauxio>0)then
3861 ! auxiliary io variables can be computed and added by user
3862 ! next few lines ensure correct usage of routines like divvector etc
3863 dxlevel(1)=rnode(rpdx1_,igrid);dxlevel(2)=rnode(rpdx2_,igrid)
3864 ! default (no) normalization for auxiliary variables
3865 normconv(nw+1:nw+nwauxio)=one
3866 ! maybe need for restriction to ixG^LL^LSUB1
3867 call specialvar_output23(ixglo1,ixglo2,ixglo1,ixghi1,ixghi2,ixghi1,ixglo1&
3868 +1,ixglo2+1,ixglo1+1,ixghi1-1,ixghi2-1,ixghi1-1,w,xcc,normconv)
3869 endif
3870 ! compute the cell-center values for w first
3871 !===========================================
3872 ! cell center values obtained from mere copy, while B0+B1 split handled here
3873 wcc(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,:)=w(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,:)
3874 if(b0field) then
3875 do ix3=ixccmin3,ixccmax3
3876 do ix2=ixccmin2,ixccmax2
3877 do ix1=ixccmin1,ixccmax1
3878 wcc(ix1,ix2,ix3,iw_mag(:))=wcc(ix1,ix2,ix3,iw_mag(:))+ps(igrid)%B0(ix1,ix2,&
3879 :,0)
3880 end do
3881 end do
3882 end do
3883 end if
3884 if(.not.saveprim .and. b0field .and. iw_e>0) then
3885 do ix3=ixccmin3,ixccmax3
3886 do ix2=ixccmin2,ixccmax2
3887 do ix1=ixccmin1,ixccmax1
3888 wcc(ix1,ix2,ix3,iw_e)=w(ix1,ix2,ix3,iw_e) +half*sum(ps(igrid)%B0(ix1,&
3889 ix2,:,0)**2 ) + sum(w(ix1,ix2,ix3,&
3890 iw_mag(:))*ps(igrid)%B0(ix1,ix2,:,0))
3891 end do
3892 end do
3893 end do
3894 end if
3895 ! compute the corner values for w now by averaging
3896 !=================================================
3897 if(slab_uniform)then
3898 ! for slab symmetry: no geometrical info required
3899 do iw=1,nw+nwauxio
3900 if (b0field.and.iw>iw_mag(1)-1.and.iw<=iw_mag(ndir)) then
3901 idir=iw-iw_mag(1)+1
3902 do ix3=ixcmin3,ixcmax3
3903 do ix2=ixcmin2,ixcmax2
3904 do ix1=ixcmin1,ixcmax1
3905 wc(ix1,ix2,ix3,iw)=sum(w(ix1:ix1+1,ix2:ix2+1,ix3,iw) &
3906 +ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3907 ,idir,0))/dble(2**3)+&
3908 sum(w(ix1:ix1+1,ix2:ix2+1,ix3+1,iw) &
3909 +ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3910 ,idir,0))/dble(2**3)
3911 end do
3912 end do
3913 end do
3914 else
3915 do ix3=ixcmin3,ixcmax3
3916 do ix2=ixcmin2,ixcmax2
3917 do ix1=ixcmin1,ixcmax1
3918 wc(ix1,ix2,ix3,iw)=sum(w(ix1:ix1+1,ix2:ix2+1,ix3:ix3&
3919 +1,iw))/dble(2**3)
3920 end do
3921 end do
3922 end do
3923 end if
3924 end do
3925 if(.not.saveprim .and. b0field .and. iw_e>0) then
3926 do ix3=ixcmin3,ixcmax3
3927 do ix2=ixcmin2,ixcmax2
3928 do ix1=ixcmin1,ixcmax1
3929 wc(ix1,ix2,ix3,iw_e)=sum( w(ix1:ix1+1,ix2:ix2+1,ix3,iw_e) &
3930 +half*sum(ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3931 ,:,0)**2,dim=ndim+1) + sum( w(ix1:ix1+1,ix2:ix2+1,ix3&
3932 ,iw_mag(:))*ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3933 ,:,0),dim=ndim+1) ) /dble(2**3)+&
3934 sum( w(ix1:ix1+1,ix2:ix2+1,ix3+1,iw_e) &
3935 +half*sum(ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3936 ,:,0)**2,dim=ndim+1) + sum( w(ix1:ix1+1,ix2:ix2+1,ix3&
3937 +1,iw_mag(:))*ps(igrid)%B0(ix1:ix1+1,ix2:ix2+1&
3938 ,:,0),dim=ndim+1) ) /dble(2**3)
3939 end do
3940 end do
3941 end do
3942 end if
3943 end if
3944 ! keep the coordinate and vector components
3945 xc_tmp(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,1:3) &
3946 = xc(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,1:3)
3947 wc_tmp(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,1:nw&
3948 +nwauxio) = wc(ixcmin1:ixcmax1,ixcmin2:ixcmax2,ixcmin3:ixcmax3,1:nw&
3949 +nwauxio)
3950 xcc_tmp(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,&
3951 1:3) = xcc(ixccmin1:ixccmax1,ixccmin2:ixccmax2,&
3952 ixccmin3:ixccmax3,1:3)
3953 wcc_tmp(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,1:nw&
3954 +nwauxio) = wcc(ixccmin1:ixccmax1,ixccmin2:ixccmax2,ixccmin3:ixccmax3,&
3955 1:nw+nwauxio)
3956 end subroutine calc_grid23
3957
3958 subroutine save_connvtk23(qunit,igrid)
3959 ! this saves the basic line, pixel and voxel connectivity,
3960 ! as used by VTK file outputs for unstructured grid
3962
3963 integer, intent(in) :: qunit, igrid
3964
3965 integer :: nx1,nx2,nx3, nxC1,nxC2,nxC3, ix1,ix2,ix3
3966
3967 nx1=ixmhi1-ixmlo1+1;nx2=ixmhi2-ixmlo2+1;nx3=ixmhi1-ixmlo1+1;
3968 nxc1=nx1+1;nxc2=nx2+1;nxc3=nx3+1;
3969 do ix3=1,nx3
3970 do ix2=1,nx2
3971 do ix1=1,nx1
3972 write(qunit,'(8(i7,1x))')&
3973 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1-1, &
3974 (ix3-1)*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3975 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3976 (ix3-1)*nxc2*nxc1+ ix2*nxc1+ix1,&
3977 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1-1,&
3978 ix3*nxc2*nxc1+(ix2-1)*nxc1+ix1,&
3979 ix3*nxc2*nxc1+ ix2*nxc1+ix1-1,&
3980 ix3*nxc2*nxc1+ ix2*nxc1+ix1
3981
3982 end do
3983 end do
3984 end do
3985 end subroutine save_connvtk23
3986
3987 subroutine specialvar_output23(ixImin1,ixImin2,ixImin3,ixImax1,ixImax2,&
3988 ixImax3,ixOmin1,ixOmin2,ixOmin3,ixOmax1,ixOmax2,ixOmax3,w,x,normconv)
3989 ! this subroutine can be used in convert, to add auxiliary variables to the
3990 ! converted output file, for further analysis using tecplot, paraview, ....
3991 ! these auxiliary values need to be stored in the nw+1:nw+nwauxio slots
3992 ! the array normconv can be filled in the (nw+1:nw+nwauxio) range with
3993 ! corresponding normalization values (default value 1)
3995
3996 integer, intent(in) :: ixImin1,ixImin2,ixImin3,ixImax1,ixImax2,&
3997 ixImax3,ixOmin1,ixOmin2,ixOmin3,ixOmax1,ixOmax2,ixOmax3
3998 double precision, intent(in) :: x(ixImin1:ixImax1,ixImin2:ixImax2,&
3999 ixImin3:ixImax3,1:3)
4000 double precision :: w(ixImin1:ixImax1,ixImin2:ixImax2,&
4001 ixImin3:ixImax3,nw+nwauxio)
4002 double precision :: normconv(0:nw+nwauxio)
4003
4004 double precision :: qvec(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1,1:ndir),&
4005 curlvec(ixGlo1:ixGhi1,ixGlo2:ixGhi2,ixGlo1:ixGhi1,1:ndir)
4006 integer :: idirmin
4007
4008 ! output Te
4009 !if(saveprim)then
4010 ! w(ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,nw+1)=w(ixOmin1:ixOmax1,&
4011 ! ixOmin2:ixOmax2,ixOmin3:ixOmax3,iw_e)/w(ixOmin1:ixOmax1,ixOmin2:ixOmax2,&
4012 ! ixOmin3:ixOmax3,iw_rho)
4013 !endif
4014 !!! store current
4015 ! qvec(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,1)=w(ixImin1:ixImax1,&
4016 ! ixImin2:ixImax2,ixImin3:ixImax3,mag(1))
4017 ! qvec(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,2)=w(ixImin1:ixImax1,&
4018 ! ixImin2:ixImax2,ixImin3:ixImax3,mag(2))
4019 ! qvec(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,3)=w(ixImin1:ixImax1,&
4020 ! ixImin2:ixImax2,ixImin3:ixImax3,mag(3));
4021 !call curlvector3D(qvec,ixImin1,ixImin2,ixImin3,ixImax1,ixImax2,ixImax3,ixOmin1,&
4022 ! ixOmin2,ixOmin3,ixOmax1,ixOmax2,ixOmax3,curlvec,idirmin,1,ndir)
4023 !w(ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,nw+2)=curlvec&
4024 ! (ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,1)
4025 !w(ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,nw+3)=curlvec&
4026 ! (ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,2)
4027 !w(ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,nw+4)=curlvec&
4028 ! (ixOmin1:ixOmax1,ixOmin2:ixOmax2,ixOmin3:ixOmax3,3);
4029 end subroutine specialvar_output23
4030 \}
4031
4032end module mod_convert_files
4033
subroutine, public alloc_state_output(igrid, s, ixgl)
allocate memory to physical state of igrid node for output with auxio
Handles computations for coordinates and variables in output.
subroutine getheadernames(wnamei, xandwnamei, outfilehead)
get all variables names
subroutine calc_grid(qunit, igrid, xc, xcc, xc_tmp, xcc_tmp, wc_tmp, wcc_tmp, normconv, ixcl, ixccl, first)
Compute both corner as well as cell-centered values for output.
subroutine calc_x(igrid, xc, xcc)
computes cell corner (xC) and cell center (xCC) coordinates
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
subroutine unstructuredvtkb64(qunit)
subroutine punstructuredvtk_mpi(qunit)
subroutine write_vtk(qunit, ixil, ixcl, ixccl, igrid, nc, np, nxd, nxcd, normconv, wnamei, xc, xcc, wc, wcc)
subroutine tecplot_mpi(qunit)
subroutine oneblock(qunit)
subroutine write_pvtu(qunit)
subroutine imagedatavtk_mpi(qunit)
subroutine save_connvtk(qunit, igrid)
integer function nodenumbertec2d(i1, i2, nx1, nx2, ig, igrid)
subroutine calc_grid23(qunit, igrid, xc_tmp, xcc_tmp, wc_tmp, wcc_tmp, normconv, ixcmin1, ixcmin2, ixcmin3, ixcmax1, ixcmax2, ixcmax3, ixccmin1, ixccmin2, ixccmin3, ixccmax1, ixccmax2, ixccmax3, first, i3grid, d3grid, w, zlength, zgridsc)
subroutine tecplot(qunit)
subroutine generate_plotfile
integer function nodenumbertec1d(i1, nx1, ig, igrid)
subroutine unstructuredvtk(qunit)
subroutine unstructuredvtkb23(qunit)
subroutine unstructuredvtkb(qunit)
subroutine write_vti(qunit, ixil, ixcl, ixccl, igd, nxd, normconv, wnamei, wc, wcc)
integer function nodenumbertec3d(i1, i2, i3, nx1, nx2, nx3, ig, igrid)
subroutine write_connvtk_binary(qunit)
subroutine save_conntec(qunit, igrid, igonlevel)
logical function vtk_coordinates_transformed()
subroutine save_connvtk23(qunit, igrid)
subroutine onegrid(qunit)
subroutine unstructuredvtk_mpi(qunit)
subroutine punstructuredvtkb_mpi(qunit)
subroutine unstructuredvtkbsym23(qunit)
subroutine specialvar_output23(iximin1, iximin2, iximin3, iximax1, iximax2, iximax3, ixomin1, ixomin2, ixomin3, ixomax1, ixomax2, ixomax3, w, x, normconv)
integer function vtk_cell_type()
subroutine convert_all()
Definition mod_convert.t:91
Module with basic grid data structures.
Definition mod_forest.t:2
integer, dimension(:), allocatable, save sfc_to_igrid
Go from a Morton number to an igrid index (for a single processor)
Definition mod_forest.t:53
integer, dimension(:), allocatable, save morton_start
First Morton number per processor.
Definition mod_forest.t:62
integer, dimension(:), allocatable, save morton_stop
Last Morton number per processor.
Definition mod_forest.t:65
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
Definition mod_forest.t:32
Module with geometry-related routines (e.g., divergence, curl)
Definition mod_geometry.t:2
integer coordinate
Definition mod_geometry.t:7
integer, parameter spherical
integer, parameter cartesian
Definition mod_geometry.t:8
integer, parameter cylindrical
integer, parameter cartesian_expansion
integer, parameter cartesian_stretched
Definition mod_geometry.t:9
update ghost cells of all blocks including physical boundaries
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision, dimension(:), allocatable w_convert_factor
Conversion factors the primitive variables.
type(state), pointer block
Block pointer for using one block and its previous state.
logical nocartesian
IO switches for conversion.
double precision global_time
The global simulation time.
integer type_block_xc_io
MPI type for IO: cell corner (xc) or cell center (xcc) coordinates.
integer snapshotini
Resume from the snapshot with this index.
logical saveprim
If true, convert from conservative to primitive variables in output.
character(len=std_len) convert_type
Which format to use when converting.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision time_convert_factor
Conversion factor for time unit.
integer icomm
The MPI communicator.
integer, dimension(:), allocatable ng
number of grid blocks in domain per dimension, in array over levels
integer mype
The rank of the current MPI task.
integer type_block_io
MPI type for IO: block excluding ghost cells.
double precision length_convert_factor
Conversion factor for length unit.
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range of a physical block without ghost cells
integer ierrmpi
A global MPI error return code.
logical autoconvert
If true, already convert to output format during the run.
integer type_block_wc_io
MPI type for IO: cell corner (wc) or cell center (wcc) variables.
integer snapshotnext
IO: snapshot and collapsed views output numbers/labels.
integer npe
The number of MPI tasks.
integer nwauxio
Number of auxiliary variables that are only included in output.
logical, dimension(:), allocatable w_write
if true write the w variable in output
logical b0field
split magnetic field as background B0 field
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
logical, dimension(:), allocatable writelevel
double precision, dimension(:,:), allocatable dx
spatial steps for all dimensions at all levels
integer nghostcells
Number of ghost cells surrounding a grid.
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
character(len=std_len) base_filename
Base file name for simulation output, which will be followed by a number.
double precision, dimension(^nd, 2) writespshift
domain percentage cut off shifted from each boundary when converting data
integer, parameter unitconvert
integer, dimension(:,:), allocatable node
Finite-volume relative magnetic helicity on a uniform Cartesian mesh.
subroutine, public mh_run_task()
subroutine, public mt_run_topology_task()
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
procedure(sub_convert), pointer phys_to_primitive
Definition mod_physics.t:52
procedure(sub_check_params), pointer phys_te_images
Definition mod_physics.t:94
Module with all the methods that users can customize in AMRVAC.
procedure(aux_output), pointer usr_aux_output
procedure(special_convert), pointer usr_special_convert
Pointer to a tree_node.
Definition mod_forest.t:6