diff --git a/src/xdmf.jl b/src/xdmf.jl index 7ab0d11687d829d0f08a29e1df2da9ac252a14af..bdfd06c0de1c5f5ca4acb3e13d3a478a254ecda7 100644 --- a/src/xdmf.jl +++ b/src/xdmf.jl @@ -4,6 +4,7 @@ const XDMF_END = """ """ mutable struct XDMFOutput + buffer::IOBuffer dir::String h5_filename::String mesh_filename::String @@ -25,7 +26,9 @@ function XDMFOutput(dir) open(mesh_filename, "w") do file end - return XDMFOutput(dir, h5_filename, mesh_filename, 0, 0) + buffer = IOBuffer() + + return XDMFOutput(buffer, dir, h5_filename, mesh_filename, 0, 0) end @@ -35,21 +38,20 @@ function xdmfwrite_mesh(xdmf::XDMFOutput, mesh::Mesh) throw(ArgumentError("Mesh has already been write")) end - buffer = IOBuffer() - write_mesh_header(buffer) + # buffer = IOBuffer() + write_mesh_header(xdmf.buffer) # Using "w" here to overwrite in case previous calls failed h5open(xdmf.h5_filename, "w") do file - write_mesh(file, buffer, mesh) + write_mesh(file, xdmf.buffer, mesh) end - write_mesh_end(buffer) + write_mesh_end(xdmf.buffer) # finish up xml files # Using "w" here to overwrite in case previous calls failed open(xdmf.mesh_filename, "a") do file - seekstart(buffer) - write(file, buffer) + write(file, take!(xdmf.buffer)) end # updating count after all writes succeeded @@ -59,13 +61,14 @@ end function write_mesh_header(buffer) - write(buffer, """ + print(buffer, """ <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="3.0"> <Domain> <Grid GridType="Collection" CollectionType="Spatial"> """) + return end @@ -131,61 +134,67 @@ size3d(sz::NTuple{2}) = (sz[1],sz[2],1) # size3d(sz::NTuple{3}) = (sz[1],sz[2],sz[3]) -function xdmfwrite_scalar(xdmf::XDMFOutput, mesh::Mesh, t, vars, names) +function write_scalar(h5, buffer, mesh::Mesh, dir, tcount, t, var, name) - buffers = IOBuffer[] - for _ in vars - b = IOBuffer() - write(b, """ + write(buffer, """ <Grid GridType="Collection" CollectionType="Temporal"><Grid GridType="Collection" CollectionType="Spatial"> <Time Value="$t"/> """) - push!(buffers, b) - end - tcount = xdmf.tcount + 1 - celliters = [ eachcell(mesh, var) for var in vars ] - h5open(xdmf.h5_filename, "r+") do h5 - - # an other group the new time step - h5group_t = create_group(h5, string(tcount)) - # sub groups for each mesh - groups = [ create_group(h5group_t, string(i)) for i = 1:ncells(mesh) ] - - for (cellit, name, buffer) in zip(celliters, names, buffers) - for (i,(cellvar,g)) in enumerate(zip(cellit,groups)) - nx, ny, nz = size3d(size(cellvar)) - g[name] = view(cellvar,:) - write(buffer, """ + variter = eachcell(mesh, var) + + # a group to gather grids from one time step + tgroup = create_group(h5, string(tcount)) + + for (i,v) in enumerate(variter) + nx, ny, nz = size3d(size(v)) + g = create_group(tgroup, string(i)) + g[name] = v + write(buffer, """ <Grid Name="$i"><xi:include href="mesh.xdmf" xpointer="xpointer(/Xdmf/Domain/Grid[1]/Grid[$i]/child::*)"/><Attribute Name="$name"><DataItem Dimensions="$nz $ny $nx" Format="HDF"> data.h5:/$tcount/$i/$name </DataItem></Attribute></Grid> """) - end - write(buffer, "</Grid></Grid>") - end end - # finish up xml files - for (buffer,name) in zip(buffers,names) - filename = joinpath(xdmf.dir, "$name.xdmf") - existed = isfile(filename) - open(filename, "a") do file - if !existed - print(file, """ + write(buffer, "</Grid></Grid>") + + filename = joinpath(dir, "$name.xdmf") + existed = isfile(filename) + open(filename, "a") do file + if !existed + print(file, """ <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="3.0"> <Domain> """) - else - skip(file, -length(XDMF_END)) - end - seekstart(buffer) - write(file, buffer) - write(file, XDMF_END) + else + skip(file, -length(XDMF_END)) + end + write(file, take!(buffer)) + write(file, XDMF_END) + end + + return +end + +function xdmfwrite_scalar(xdmf::XDMFOutput, mesh::Mesh, t, vars, names) + + tcount = xdmf.tcount + 1 + h5 = h5open(xdmf.h5_filename, "r+") + + try + for (var, name) in zip(vars, names) + write_scalar(h5, xdmf.buffer, mesh, xdmf.dir, tcount, t, var, name) end + catch e + rethrow(e) + finally + close(h5) end # updating count after all writes succeeded xdmf.tcount = tcount + return + end