From 9c2b314bf938abe99bd38d0b08ee923181e90686 Mon Sep 17 00:00:00 2001 From: amartin Date: Sun, 17 Oct 2021 23:40:25 +1100 Subject: [PATCH 1/8] Working on a proposal to support parallel file formats --- proposal_pvtk_grid.jl | 158 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 proposal_pvtk_grid.jl diff --git a/proposal_pvtk_grid.jl b/proposal_pvtk_grid.jl new file mode 100644 index 00000000..2e667813 --- /dev/null +++ b/proposal_pvtk_grid.jl @@ -0,0 +1,158 @@ +#module ParallelDatasetFiles + using WriteVTK + using LightXML + + struct ParallelDatasetFile <: WriteVTK.VTKFile + xdoc::XMLDocument + path::AbstractString + num_pieces::Integer + ParallelDatasetFile(xdoc,path::AbstractString,num_pieces::Integer)=new(xdoc,path,num_pieces) + end + + function WriteVTK.vtk_save(vtk::ParallelDatasetFile) + if isopen(vtk) + save_file(vtk.xdoc, vtk.path) + close(vtk) + end + return [vtk.path] :: Vector{String} + end + + function get_dataset_extension(dataset::WriteVTK.DatasetFile) + path, ext = splitext(dataset.path) + @assert ext != "" + ext + end + + function get_dataset_path(dataset::WriteVTK.DatasetFile) + path, ext = splitext(dataset.path) + @assert ext != "" + path + end + + function get_type(dataset::WriteVTK.DatasetFile) + r=root(dataset.xdoc) + attribute(r,"type") + end + + function get_grid_element(dataset::WriteVTK.DatasetFile, + element::AbstractString) + r=root(dataset.xdoc) + uns=find_element(r,get_type(dataset)) + piece=find_element(uns,"Piece") + find_element(piece,element) + end + + function num_children(element) + length(collect(child_elements(element))) + end + + function get_child_attribute(element,child,attr) + children=collect(child_elements(element)) + attribute(children[child],attr) + end + + function set_attribute_if_valid_value(node,name,value) + if (value!="nothing") + set_attribute(node,name,value) + end + end + + function generate_pieces(grid_xml_node, + dataset::WriteVTK.DatasetFile, + num_pieces::Int) + + path=get_dataset_path(dataset) + ext=get_dataset_extension(dataset) + for i=1:num_pieces + piece=new_child(grid_xml_node,"Piece") + set_attribute(piece,"Source",path*string(i)*ext) + end + grid_xml_node + end + + function pvtk_grid(dataset::WriteVTK.DatasetFile, + filename::AbstractString, + num_pieces::Integer; + ghost_level=0) + + # Initialise Paraview parallel file format (extension .pXXX). + # filename: filename with or without the extension (.pvd). + dataset_extension = get_dataset_extension(dataset) + pdataset_extension = ".p" * dataset_extension[2:end] + filename_full = WriteVTK.add_extension(filename, pdataset_extension) + xpvtX = XMLDocument() + xroot = create_root(xpvtX, "VTKFile") + set_attribute(xroot, "type", "P"*get_type(dataset)) + set_attribute(xroot, "version", "1.0") + if WriteVTK.IS_LITTLE_ENDIAN + set_attribute(xroot, "byte_order", "LittleEndian") + else + set_attribute(xroot, "byte_order", "BigEndian") + end + + # Generate parallel grid node + grid_xml_node=new_child(xroot,"P"*get_type(dataset)) + set_attribute(grid_xml_node, "GhostLevel", string(ghost_level)) + + # Generate PPoints + ppoints=new_child(grid_xml_node,"PPoints") + ppointsarray=new_child(ppoints,"PDataArray") + points=get_grid_element(dataset,"Points") + set_attribute(ppointsarray, "type", + get_child_attribute(points,1,"type")) + set_attribute(ppointsarray, "NumberOfComponents", + get_child_attribute(points,1,"NumberOfComponents")) + + # Generate PPointData + pointdata=get_grid_element(dataset,"PointData") + if pointdata != nothing + if (num_children(pointdata)>0) + ppointdata=new_child(grid_xml_node,"PPointData") + for child=1:num_children(pointdata) + parray=new_child(ppointdata,"PDataArray") + set_attribute(parray, "type", + get_child_attribute(pointdata,child,"type")) + set_attribute(parray, "NumberOfComponents", + get_child_attribute(pointdata,child,"NumberOfComponents")) + set_attribute(parray, "Name", + get_child_attribute(pointdata,child,"Name")) + end + end + end + + # Generate PCellData + celldata=get_grid_element(dataset,"CellData") + if celldata!=nothing + if (num_children(celldata)>0) + ppointdata=new_child(grid_xml_node,"PCellData") + for child=1:num_children(celldata) + parray=new_child(ppointdata,"PDataArray") + set_attribute(parray, "type", + get_child_attribute(celldata,child,"type")) + set_attribute(parray, "Name", + get_child_attribute(celldata,child,"Name")) + set_attribute_if_valid_value(parray, "NumberOfComponents", + get_child_attribute(celldata,child,"NumberOfComponents")) + end + end + end + + # Generate pieces + generate_pieces(grid_xml_node,dataset,num_pieces) + + ParallelDatasetFile(xpvtX,filename_full,num_pieces) + end + + + # Suppose that the mesh is made of 5 points: + cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), + MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] + + x=rand(5) + y=rand(5) + vtkfile = vtk_grid("my_vtk_file", x, y, cells) # 2D + vtkfile["Pressure"] = x + pvtkfile=pvtk_grid(vtkfile,"simulation",2) + vtk_save(pvtkfile) + vtk_save(vtkfile) +#end From ab9f3cbb81a10399f7ad602793e74aa52f6c8f12 Mon Sep 17 00:00:00 2001 From: amartin Date: Mon, 18 Oct 2021 18:48:41 +1100 Subject: [PATCH 2/8] A more definite (still partial though) sketch for pvtk_grid --- proposal_pvtk_grid.jl | 392 ++++++++++++++++++++++++++++++------------ 1 file changed, 278 insertions(+), 114 deletions(-) diff --git a/proposal_pvtk_grid.jl b/proposal_pvtk_grid.jl index 2e667813..6148ffa8 100644 --- a/proposal_pvtk_grid.jl +++ b/proposal_pvtk_grid.jl @@ -1,158 +1,322 @@ -#module ParallelDatasetFiles - using WriteVTK - using LightXML - - struct ParallelDatasetFile <: WriteVTK.VTKFile - xdoc::XMLDocument - path::AbstractString - num_pieces::Integer - ParallelDatasetFile(xdoc,path::AbstractString,num_pieces::Integer)=new(xdoc,path,num_pieces) - end +using WriteVTK +using LightXML - function WriteVTK.vtk_save(vtk::ParallelDatasetFile) - if isopen(vtk) - save_file(vtk.xdoc, vtk.path) - close(vtk) - end - return [vtk.path] :: Vector{String} - end +struct ParallelDatasetFile <: WriteVTK.VTKFile + xdoc::XMLDocument + seq_vtk_data_set::WriteVTK.AbstractVTKDataset + path::AbstractString + num_pieces::Integer + ParallelDatasetFile(xdoc,seq_data_set::WriteVTK.AbstractVTKDataset,path::AbstractString,num_pieces::Integer)=new(xdoc,seq_data_set,path,num_pieces) +end - function get_dataset_extension(dataset::WriteVTK.DatasetFile) - path, ext = splitext(dataset.path) - @assert ext != "" - ext +function WriteVTK.vtk_save(vtk::ParallelDatasetFile) + if isopen(vtk) + save_file(vtk.xdoc, vtk.path) + close(vtk) end + return [vtk.path] :: Vector{String} +end - function get_dataset_path(dataset::WriteVTK.DatasetFile) - path, ext = splitext(dataset.path) - @assert ext != "" - path +function new_pdata_array(xParent, + type::Type{<:WriteVTK.VTKDataType}, + name::AbstractString, + Nc=nothing) + xDA = new_child(xParent, "PDataArray") + set_attribute(xDA, "type", WriteVTK.datatype_str(type)) + set_attribute(xDA, "Name", name) + if Nc != nothing + set_attribute(xDA, "NumberOfComponents", Nc) end +end - function get_type(dataset::WriteVTK.DatasetFile) - r=root(dataset.xdoc) - attribute(r,"type") - end +function get_extension(filename::AbstractString) + path, ext = splitext(filename) + ext +end + +function get_path(filename::AbstractString) + path, ext = splitext(filename) + path +end - function get_grid_element(dataset::WriteVTK.DatasetFile, - element::AbstractString) - r=root(dataset.xdoc) - uns=find_element(r,get_type(dataset)) - piece=find_element(uns,"Piece") - find_element(piece,element) +function parallel_file_extension(g::WriteVTK.AbstractVTKDataset) + ext=WriteVTK.file_extension(g) + replace(ext,"."=>".p") +end + +function parallel_xml_name(g::WriteVTK.AbstractVTKDataset) + "P"*WriteVTK.xml_name(g) +end + +function parallel_xml_write_header(pvtx::XMLDocument,dtype::WriteVTK.AbstractVTKDataset) + xroot = create_root(pvtx, "VTKFile") + set_attribute(xroot, "type", parallel_xml_name(dtype)) + set_attribute(xroot, "version", "1.0") + if WriteVTK.IS_LITTLE_ENDIAN + set_attribute(xroot, "byte_order", "LittleEndian") + else + set_attribute(xroot, "byte_order", "BigEndian") end + xroot +end - function num_children(element) - length(collect(child_elements(element))) +function add_pieces!(grid_xml_node, + prefix::AbstractString, + extension::AbstractString, + num_pieces::Int) + for i=1:num_pieces + piece=new_child(grid_xml_node,"Piece") + set_attribute(piece,"Source",prefix*string(i)*extension) end + grid_xml_node +end - function get_child_attribute(element,child,attr) - children=collect(child_elements(element)) - attribute(children[child],attr) +function add_ppoints!(grid_xml_node; + type::Type{<:WriteVTK.VTKDataType}=Float64) + ppoints=new_child(grid_xml_node,"PPoints") + new_pdata_array(ppoints,type,"Points",3) +end + +function add_ppoint_data!(pdataset::ParallelDatasetFile, + name::AbstractString; + type::Type{<:WriteVTK.VTKDataType}=Float64, + Nc::Integer=1) + xroot=root(pdataset.xdoc) + grid_xml_node=find_element(xroot,parallel_xml_name(pdataset.seq_vtk_data_set)) + @assert grid_xml_node != nothing + grid_xml_node_ppoint=find_element(grid_xml_node,"PPointData") + if (grid_xml_node_ppoint==nothing) + grid_xml_node_ppoint=new_child(grid_xml_node,"PPointData") end + new_pdata_array(grid_xml_node_ppoint,type,name,Nc) +end - function set_attribute_if_valid_value(node,name,value) - if (value!="nothing") - set_attribute(node,name,value) - end +function add_pcell_data!(pdataset::ParallelDatasetFile, + name::AbstractString; + type::Type{<:WriteVTK.VTKDataType}=Float64, + Nc=nothing) + xroot=root(pdataset.xdoc) + grid_xml_node=find_element(xroot,parallel_xml_name(pdataset.seq_vtk_data_set)) + @assert grid_xml_node != nothing + grid_xml_node_pcell=find_element(grid_xml_node,"PCellData") + if (grid_xml_node_pcell==nothing) + grid_xml_node_pcell=new_child(grid_xml_node,"PCellData") end + new_pdata_array(grid_xml_node_pcell,type,name,Nc) +end - function generate_pieces(grid_xml_node, - dataset::WriteVTK.DatasetFile, - num_pieces::Int) - - path=get_dataset_path(dataset) - ext=get_dataset_extension(dataset) - for i=1:num_pieces - piece=new_child(grid_xml_node,"Piece") - set_attribute(piece,"Source",path*string(i)*ext) - end - grid_xml_node +function Base.setindex!(vtk::ParallelDatasetFile, + type::Type{<:WriteVTK.VTKDataType}, + name::AbstractString, + loc::WriteVTK.AbstractFieldData) + + Nc=nothing + if isa(loc,VTKPointData) + Nc=1 end + parallel_add_field_data!(vtk,name,loc,type=type,Nc=Nc) +end + +function Base.setindex!(vtk::ParallelDatasetFile, + Nc::Integer, + name::AbstractString, + loc::WriteVTK.AbstractFieldData) + parallel_add_field_data!(vtk,name,loc,Nc=Nc) +end + +function Base.setindex!(vtk::ParallelDatasetFile, + type_Nc::Tuple{DataType,Integer}, + name::AbstractString, + loc::WriteVTK.AbstractFieldData) + parallel_add_field_data!(vtk,name,loc,type=type_Nc[1],Nc=type_Nc[2]) +end + +function parallel_add_field_data!( + vtk::ParallelDatasetFile, + name::AbstractString, + loc::WriteVTK.AbstractFieldData; + type::Type{<:WriteVTK.VTKDataType}=Float64, + Nc=nothing) + + @assert isa(loc,VTKPointData) || isa(loc,VTKCellData) + + if isa(loc,VTKPointData) + @assert isa(Nc,Integer) + add_ppoint_data!(vtk,name,type=type,Nc=Nc) + else + add_pcell_data!(vtk,name,type=type,Nc=Nc) + end +end + +function pvtk_grid( + dtype::WriteVTK.VTKUnstructuredGrid, + filename::AbstractString, + num_pieces::Integer; + points_type::Type{<:WriteVTK.VTKDataType}=Float64, + ghost_level=0) + + pvtu = XMLDocument() + xroot = parallel_xml_write_header(pvtu,dtype) + pextension = parallel_file_extension(dtype) + pfilename = WriteVTK.add_extension(filename,pextension) - function pvtk_grid(dataset::WriteVTK.DatasetFile, - filename::AbstractString, - num_pieces::Integer; - ghost_level=0) - - # Initialise Paraview parallel file format (extension .pXXX). - # filename: filename with or without the extension (.pvd). - dataset_extension = get_dataset_extension(dataset) - pdataset_extension = ".p" * dataset_extension[2:end] - filename_full = WriteVTK.add_extension(filename, pdataset_extension) - xpvtX = XMLDocument() - xroot = create_root(xpvtX, "VTKFile") - set_attribute(xroot, "type", "P"*get_type(dataset)) - set_attribute(xroot, "version", "1.0") - if WriteVTK.IS_LITTLE_ENDIAN - set_attribute(xroot, "byte_order", "LittleEndian") + # Generate parallel grid node + grid_xml_node=new_child(xroot,parallel_xml_name(dtype)) + set_attribute(grid_xml_node, "GhostLevel", ghost_level) + prefix=get_path(pfilename) + extension=WriteVTK.file_extension(dtype) + add_pieces!(grid_xml_node,prefix,extension,num_pieces) + add_ppoints!(grid_xml_node,type=points_type) + ParallelDatasetFile(pvtu,dtype,pfilename,num_pieces) +end + +function get_dataset_extension(dataset::WriteVTK.DatasetFile) + path, ext = splitext(dataset.path) + @assert ext != "" + ext +end + +function get_dataset_path(dataset::WriteVTK.DatasetFile) + path, ext = splitext(dataset.path) + @assert ext != "" + path +end + +function xml_name_to_VTK_Dataset(xml_name::AbstractString) + if (xml_name=="ImageData") + WriteVTK.VTKImageData() + elseif (xml_name=="RectilinearGrid") + WriteVTK.VTKRectilinearGrid() + elseif (xml_name=="PolyData") + WriteVTK.VTKPolyData() + elseif (xml_name=="StructuredGrid") + WriteVTK.VTKStructuredGrid() + elseif (xml_name=="UnstructuredGrid") + WriteVTK.VTKUnstructuredGrid() else - set_attribute(xroot, "byte_order", "BigEndian") + @assert false end +end + +function num_children(element) + length(collect(child_elements(element))) +end + +function get_child_attribute(element,child,attr) + children=collect(child_elements(element)) + attribute(children[child],attr) +end + +function get_dataset_xml_type(dataset::WriteVTK.DatasetFile) + r=root(dataset.xdoc) + attribute(r,"type") +end + +function get_dataset_xml_grid_element(dataset::WriteVTK.DatasetFile, + element::AbstractString) + r=root(dataset.xdoc) + uns=find_element(r,get_dataset_xml_type(dataset)) + piece=find_element(uns,"Piece") + find_element(piece,element) +end + + +const string_to_VTKDataType = Dict("Int8"=>Int8, + "UInt8"=>UInt8, + "Int16"=>Int16, + "UInt16"=>UInt16, + "Int32"=>Int32, + "UInt32"=>UInt32, + "Int64"=>Int64, + "UInt64"=>UInt64, + "Float32"=>Float32, + "Float64"=>Float64, + "String"=>String) + +""" + Creates a Parallel VTK data set by mirroring the XML tree + corresponding to an already set up Sequential VTK data set +""" +function pvtk_grid(dataset::WriteVTK.DatasetFile, + filename::AbstractString, + num_pieces::Integer; + ghost_level=0) + + pvtx = XMLDocument() + dtype = xml_name_to_VTK_Dataset(dataset.grid_type) + xroot = parallel_xml_write_header(pvtx,dtype) # Generate parallel grid node - grid_xml_node=new_child(xroot,"P"*get_type(dataset)) + grid_xml_node=new_child(xroot,"P"*dataset.grid_type) set_attribute(grid_xml_node, "GhostLevel", string(ghost_level)) + prefix=get_path(filename) + extension=WriteVTK.file_extension(dtype) + add_pieces!(grid_xml_node,prefix,extension,num_pieces) + + pextension = parallel_file_extension(dtype) + pfilename = WriteVTK.add_extension(filename,pextension) + pdataset=ParallelDatasetFile(pvtx,dtype,pfilename,num_pieces) + # Generate PPoints - ppoints=new_child(grid_xml_node,"PPoints") - ppointsarray=new_child(ppoints,"PDataArray") - points=get_grid_element(dataset,"Points") - set_attribute(ppointsarray, "type", - get_child_attribute(points,1,"type")) - set_attribute(ppointsarray, "NumberOfComponents", - get_child_attribute(points,1,"NumberOfComponents")) + points=get_dataset_xml_grid_element(dataset,"Points") + type=get_child_attribute(points,1,"type") + add_ppoints!(grid_xml_node,type=string_to_VTKDataType[type]) # Generate PPointData - pointdata=get_grid_element(dataset,"PointData") + pointdata=get_dataset_xml_grid_element(dataset,"PointData") if pointdata != nothing if (num_children(pointdata)>0) - ppointdata=new_child(grid_xml_node,"PPointData") for child=1:num_children(pointdata) - parray=new_child(ppointdata,"PDataArray") - set_attribute(parray, "type", - get_child_attribute(pointdata,child,"type")) - set_attribute(parray, "NumberOfComponents", - get_child_attribute(pointdata,child,"NumberOfComponents")) - set_attribute(parray, "Name", - get_child_attribute(pointdata,child,"Name")) + name=get_child_attribute(pointdata,child,"Name") + type=get_child_attribute(pointdata,child,"type") + Nc=get_child_attribute(pointdata,child,"NumberOfComponents") + add_ppoint_data!(pdataset, + name; + type=string_to_VTKDataType[type], + Nc=parse(Int64,Nc)) end end end # Generate PCellData - celldata=get_grid_element(dataset,"CellData") + celldata=get_dataset_xml_grid_element(dataset,"CellData") if celldata!=nothing if (num_children(celldata)>0) - ppointdata=new_child(grid_xml_node,"PCellData") for child=1:num_children(celldata) - parray=new_child(ppointdata,"PDataArray") - set_attribute(parray, "type", - get_child_attribute(celldata,child,"type")) - set_attribute(parray, "Name", - get_child_attribute(celldata,child,"Name")) - set_attribute_if_valid_value(parray, "NumberOfComponents", - get_child_attribute(celldata,child,"NumberOfComponents")) + name=get_child_attribute(celldata,child,"Name") + type=get_child_attribute(celldata,child,"type") + Nc=get_child_attribute(celldata,child,"NumberOfComponents") + add_pcell_data!(pdataset, + name; + type=string_to_VTKDataType[type], + Nc=(Nc==nothing ? nothing : parse(Int64,Nc))) end end end - - # Generate pieces - generate_pieces(grid_xml_node,dataset,num_pieces) - - ParallelDatasetFile(xpvtX,filename_full,num_pieces) + pdataset end +# Scenario 1 +# Parallel Dataset XML tree created from scratch +pvtk=pvtk_grid(WriteVTK.VTKUnstructuredGrid(),"simulation",10) +pvtk["Velocity",VTKPointData()] = (Float32,3) +pvtk["Pressure",VTKPointData()] = (Float64,1) +pvtk["Processor",VTKCellData()] = Int64 +pvtk["Normals",VTKCellData()] = (Float64,3) +vtk_save(pvtk) + - # Suppose that the mesh is made of 5 points: - cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), - MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] +# Scenario 1 +# Parallel Dataset XML tree created by mirroring sequential dataset - x=rand(5) - y=rand(5) - vtkfile = vtk_grid("my_vtk_file", x, y, cells) # 2D - vtkfile["Pressure"] = x - pvtkfile=pvtk_grid(vtkfile,"simulation",2) - vtk_save(pvtkfile) - vtk_save(vtkfile) -#end +# Suppose that the mesh is made of 5 points: +cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), + MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] +x=rand(5) +y=rand(5) +vtkfile = vtk_grid("my_vtk_file", x, y, cells) # 2D +vtkfile["Pressure"] = x +vtkfile["Processor"] = rand(2) +pvtk=pvtk_grid(vtkfile,"simulation_seq_data_set",5) +vtk_save(pvtk) From 5e97d2fe06daa55b554cf055dff04f20f8705e25 Mon Sep 17 00:00:00 2001 From: "Alberto F. Martin" <38347633+amartinhuertas@users.noreply.github.com> Date: Mon, 18 Oct 2021 20:52:05 +1100 Subject: [PATCH 3/8] Update proposal_pvtk_grid.jl --- proposal_pvtk_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposal_pvtk_grid.jl b/proposal_pvtk_grid.jl index 6148ffa8..7f891bf0 100644 --- a/proposal_pvtk_grid.jl +++ b/proposal_pvtk_grid.jl @@ -307,7 +307,7 @@ pvtk["Normals",VTKCellData()] = (Float64,3) vtk_save(pvtk) -# Scenario 1 +# Scenario 2 # Parallel Dataset XML tree created by mirroring sequential dataset # Suppose that the mesh is made of 5 points: From 32b1ef45d147d0feaf98fb29ae7a638812434d9d Mon Sep 17 00:00:00 2001 From: amartin Date: Tue, 19 Oct 2021 19:36:11 +1100 Subject: [PATCH 4/8] Implemented new high level API that mirrors the vtk_grid sequential one --- proposal_pvtk_grid.jl | 150 +++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 91 deletions(-) diff --git a/proposal_pvtk_grid.jl b/proposal_pvtk_grid.jl index 6148ffa8..03921c70 100644 --- a/proposal_pvtk_grid.jl +++ b/proposal_pvtk_grid.jl @@ -1,18 +1,36 @@ using WriteVTK using LightXML +struct PVTKLayout + part::Int + nparts::Int + ismain::Bool +end +# By default, we assume that part 1 is the main part +PVTKLayout(part,nparts) = PVTKLayout(part,nparts,part==1) + + struct ParallelDatasetFile <: WriteVTK.VTKFile + layout::PVTKLayout xdoc::XMLDocument - seq_vtk_data_set::WriteVTK.AbstractVTKDataset + dataset::WriteVTK.DatasetFile path::AbstractString - num_pieces::Integer - ParallelDatasetFile(xdoc,seq_data_set::WriteVTK.AbstractVTKDataset,path::AbstractString,num_pieces::Integer)=new(xdoc,seq_data_set,path,num_pieces) + function ParallelDatasetFile(layout::PVTKLayout, + xdoc::XMLDocument, + dataset::WriteVTK.DatasetFile, + path::AbstractString) + new(layout,xdoc,dataset,path) + end end function WriteVTK.vtk_save(vtk::ParallelDatasetFile) if isopen(vtk) - save_file(vtk.xdoc, vtk.path) - close(vtk) + _pvtk_grid_body(vtk) + if vtk.layout.ismain + save_file(vtk.xdoc, vtk.path) + end + vtk_save(vtk.dataset) + close(vtk) end return [vtk.path] :: Vector{String} end @@ -82,7 +100,8 @@ function add_ppoint_data!(pdataset::ParallelDatasetFile, type::Type{<:WriteVTK.VTKDataType}=Float64, Nc::Integer=1) xroot=root(pdataset.xdoc) - grid_xml_node=find_element(xroot,parallel_xml_name(pdataset.seq_vtk_data_set)) + dtype = xml_name_to_VTK_Dataset(pdataset.dataset.grid_type) + grid_xml_node=find_element(xroot,parallel_xml_name(dtype)) @assert grid_xml_node != nothing grid_xml_node_ppoint=find_element(grid_xml_node,"PPointData") if (grid_xml_node_ppoint==nothing) @@ -96,7 +115,8 @@ function add_pcell_data!(pdataset::ParallelDatasetFile, type::Type{<:WriteVTK.VTKDataType}=Float64, Nc=nothing) xroot=root(pdataset.xdoc) - grid_xml_node=find_element(xroot,parallel_xml_name(pdataset.seq_vtk_data_set)) + dtype = xml_name_to_VTK_Dataset(pdataset.dataset.grid_type) + grid_xml_node=find_element(xroot,parallel_xml_name(dtype)) @assert grid_xml_node != nothing grid_xml_node_pcell=find_element(grid_xml_node,"PCellData") if (grid_xml_node_pcell==nothing) @@ -105,69 +125,15 @@ function add_pcell_data!(pdataset::ParallelDatasetFile, new_pdata_array(grid_xml_node_pcell,type,name,Nc) end -function Base.setindex!(vtk::ParallelDatasetFile, - type::Type{<:WriteVTK.VTKDataType}, +function Base.setindex!(pvtk::ParallelDatasetFile, + data, name::AbstractString, loc::WriteVTK.AbstractFieldData) - - Nc=nothing - if isa(loc,VTKPointData) - Nc=1 - end - parallel_add_field_data!(vtk,name,loc,type=type,Nc=Nc) -end - -function Base.setindex!(vtk::ParallelDatasetFile, - Nc::Integer, - name::AbstractString, - loc::WriteVTK.AbstractFieldData) - parallel_add_field_data!(vtk,name,loc,Nc=Nc) -end - -function Base.setindex!(vtk::ParallelDatasetFile, - type_Nc::Tuple{DataType,Integer}, - name::AbstractString, - loc::WriteVTK.AbstractFieldData) - parallel_add_field_data!(vtk,name,loc,type=type_Nc[1],Nc=type_Nc[2]) -end - -function parallel_add_field_data!( - vtk::ParallelDatasetFile, - name::AbstractString, - loc::WriteVTK.AbstractFieldData; - type::Type{<:WriteVTK.VTKDataType}=Float64, - Nc=nothing) - - @assert isa(loc,VTKPointData) || isa(loc,VTKCellData) - - if isa(loc,VTKPointData) - @assert isa(Nc,Integer) - add_ppoint_data!(vtk,name,type=type,Nc=Nc) - else - add_pcell_data!(vtk,name,type=type,Nc=Nc) - end + pvtk.dataset[name,loc]=data end -function pvtk_grid( - dtype::WriteVTK.VTKUnstructuredGrid, - filename::AbstractString, - num_pieces::Integer; - points_type::Type{<:WriteVTK.VTKDataType}=Float64, - ghost_level=0) - - pvtu = XMLDocument() - xroot = parallel_xml_write_header(pvtu,dtype) - pextension = parallel_file_extension(dtype) - pfilename = WriteVTK.add_extension(filename,pextension) - - # Generate parallel grid node - grid_xml_node=new_child(xroot,parallel_xml_name(dtype)) - set_attribute(grid_xml_node, "GhostLevel", ghost_level) - prefix=get_path(pfilename) - extension=WriteVTK.file_extension(dtype) - add_pieces!(grid_xml_node,prefix,extension,num_pieces) - add_ppoints!(grid_xml_node,type=points_type) - ParallelDatasetFile(pvtu,dtype,pfilename,num_pieces) +function Base.setindex!(vtk::ParallelDatasetFile, data, name::AbstractString) + pvtk.dataset[name]=data end function get_dataset_extension(dataset::WriteVTK.DatasetFile) @@ -233,13 +199,22 @@ const string_to_VTKDataType = Dict("Int8"=>Int8, "Float64"=>Float64, "String"=>String) +function pvtk_grid(layout::PVTKLayout,args...;ghost_level=0,kwargs...) + filename=args[1] + path, ext = splitext(filename) + bname=basename(path) + path = mkpath(path) + filename=joinpath(path,bname*string(layout.part)*ext) + vtk=vtk_grid((filename,args[2:end]...)...;kwargs...) + _pvtk_grid_header(layout,vtk,path;ghost_level=ghost_level) +end + """ - Creates a Parallel VTK data set by mirroring the XML tree - corresponding to an already set up Sequential VTK data set """ -function pvtk_grid(dataset::WriteVTK.DatasetFile, - filename::AbstractString, - num_pieces::Integer; +function _pvtk_grid_header( + layout::PVTKLayout, + dataset::WriteVTK.DatasetFile, + filename::AbstractString; ghost_level=0) pvtx = XMLDocument() @@ -250,19 +225,24 @@ function pvtk_grid(dataset::WriteVTK.DatasetFile, grid_xml_node=new_child(xroot,"P"*dataset.grid_type) set_attribute(grid_xml_node, "GhostLevel", string(ghost_level)) - prefix=get_path(filename) + prefix=joinpath(filename,basename(filename)) extension=WriteVTK.file_extension(dtype) - add_pieces!(grid_xml_node,prefix,extension,num_pieces) + add_pieces!(grid_xml_node,prefix,extension,layout.nparts) pextension = parallel_file_extension(dtype) pfilename = WriteVTK.add_extension(filename,pextension) - pdataset=ParallelDatasetFile(pvtx,dtype,pfilename,num_pieces) + pdataset=ParallelDatasetFile(layout,pvtx,dataset,pfilename) # Generate PPoints points=get_dataset_xml_grid_element(dataset,"Points") type=get_child_attribute(points,1,"type") add_ppoints!(grid_xml_node,type=string_to_VTKDataType[type]) + pdataset + end + +function _pvtk_grid_body(pdataset::ParallelDatasetFile) + dataset=pdataset.dataset # Generate PPointData pointdata=get_dataset_xml_grid_element(dataset,"PointData") if pointdata != nothing @@ -297,26 +277,14 @@ function pvtk_grid(dataset::WriteVTK.DatasetFile, pdataset end -# Scenario 1 -# Parallel Dataset XML tree created from scratch -pvtk=pvtk_grid(WriteVTK.VTKUnstructuredGrid(),"simulation",10) -pvtk["Velocity",VTKPointData()] = (Float32,3) -pvtk["Pressure",VTKPointData()] = (Float64,1) -pvtk["Processor",VTKCellData()] = Int64 -pvtk["Normals",VTKCellData()] = (Float64,3) -vtk_save(pvtk) - - -# Scenario 1 -# Parallel Dataset XML tree created by mirroring sequential dataset - # Suppose that the mesh is made of 5 points: cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] x=rand(5) y=rand(5) -vtkfile = vtk_grid("my_vtk_file", x, y, cells) # 2D -vtkfile["Pressure"] = x -vtkfile["Processor"] = rand(2) -pvtk=pvtk_grid(vtkfile,"simulation_seq_data_set",5) + +layout=PVTKLayout(1,1) +pvtk = pvtk_grid(layout,"simulation", x, y, cells) # 2D +pvtk["Pressure"] = x +pvtk["Processor"] = rand(2) vtk_save(pvtk) From 4393d2fd959992be8a4222a616bf827790658b81 Mon Sep 17 00:00:00 2001 From: amartin Date: Wed, 20 Oct 2021 19:12:08 +1100 Subject: [PATCH 5/8] Moving proposal to something more definite --- proposal_pvtk_grid.jl => src/pvtk_grid.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposal_pvtk_grid.jl => src/pvtk_grid.jl (100%) diff --git a/proposal_pvtk_grid.jl b/src/pvtk_grid.jl similarity index 100% rename from proposal_pvtk_grid.jl rename to src/pvtk_grid.jl From 50558a967383b1ec448283c93f9a5e7ef07a409e Mon Sep 17 00:00:00 2001 From: amartin Date: Wed, 20 Oct 2021 19:29:25 +1100 Subject: [PATCH 6/8] Moving (draft) pvtk_grid proposal to source directory Added minimum tests (to be completed) --- src/WriteVTK.jl | 4 +++ src/pvtk_grid.jl | 73 ++++++++++++++++++--------------------------- test/checksums.sha1 | 1 + test/pvtk_grid.jl | 16 ++++++++++ test/runtests.jl | 2 +- 5 files changed, 51 insertions(+), 45 deletions(-) create mode 100644 test/pvtk_grid.jl diff --git a/src/WriteVTK.jl b/src/WriteVTK.jl index 87ce3b98..874a1b60 100644 --- a/src/WriteVTK.jl +++ b/src/WriteVTK.jl @@ -11,6 +11,7 @@ export paraview_collection, collection_add_timestep, paraview_collection_load export vtk_write_array export VTKPointData, VTKCellData, VTKFieldData export PolyData +export pvtk_grid import CodecZlib: ZlibCompressorStream import TranscodingStreams @@ -147,6 +148,9 @@ include("gridtypes/unstructured/polydata.jl") include("gridtypes/array.jl") +# Parallel DataSet Formats +include("pvtk_grid.jl") + # This allows using do-block syntax for generation of VTK files. for func in (:vtk_grid, :vtk_multiblock, :paraview_collection, :paraview_collection_load) diff --git a/src/pvtk_grid.jl b/src/pvtk_grid.jl index 03921c70..187b1eed 100644 --- a/src/pvtk_grid.jl +++ b/src/pvtk_grid.jl @@ -1,6 +1,3 @@ -using WriteVTK -using LightXML - struct PVTKLayout part::Int nparts::Int @@ -10,20 +7,20 @@ end PVTKLayout(part,nparts) = PVTKLayout(part,nparts,part==1) -struct ParallelDatasetFile <: WriteVTK.VTKFile +struct ParallelDatasetFile <: VTKFile layout::PVTKLayout xdoc::XMLDocument - dataset::WriteVTK.DatasetFile + dataset::DatasetFile path::AbstractString function ParallelDatasetFile(layout::PVTKLayout, xdoc::XMLDocument, - dataset::WriteVTK.DatasetFile, + dataset::DatasetFile, path::AbstractString) new(layout,xdoc,dataset,path) end end -function WriteVTK.vtk_save(vtk::ParallelDatasetFile) +function vtk_save(vtk::ParallelDatasetFile) if isopen(vtk) _pvtk_grid_body(vtk) if vtk.layout.ismain @@ -36,11 +33,11 @@ function WriteVTK.vtk_save(vtk::ParallelDatasetFile) end function new_pdata_array(xParent, - type::Type{<:WriteVTK.VTKDataType}, + type::Type{<:VTKDataType}, name::AbstractString, Nc=nothing) xDA = new_child(xParent, "PDataArray") - set_attribute(xDA, "type", WriteVTK.datatype_str(type)) + set_attribute(xDA, "type", datatype_str(type)) set_attribute(xDA, "Name", name) if Nc != nothing set_attribute(xDA, "NumberOfComponents", Nc) @@ -57,20 +54,20 @@ function get_path(filename::AbstractString) path end -function parallel_file_extension(g::WriteVTK.AbstractVTKDataset) - ext=WriteVTK.file_extension(g) +function parallel_file_extension(g::AbstractVTKDataset) + ext=file_extension(g) replace(ext,"."=>".p") end -function parallel_xml_name(g::WriteVTK.AbstractVTKDataset) - "P"*WriteVTK.xml_name(g) +function parallel_xml_name(g::AbstractVTKDataset) + "P"*xml_name(g) end -function parallel_xml_write_header(pvtx::XMLDocument,dtype::WriteVTK.AbstractVTKDataset) +function parallel_xml_write_header(pvtx::XMLDocument,dtype::AbstractVTKDataset) xroot = create_root(pvtx, "VTKFile") set_attribute(xroot, "type", parallel_xml_name(dtype)) set_attribute(xroot, "version", "1.0") - if WriteVTK.IS_LITTLE_ENDIAN + if IS_LITTLE_ENDIAN set_attribute(xroot, "byte_order", "LittleEndian") else set_attribute(xroot, "byte_order", "BigEndian") @@ -90,14 +87,14 @@ function add_pieces!(grid_xml_node, end function add_ppoints!(grid_xml_node; - type::Type{<:WriteVTK.VTKDataType}=Float64) + type::Type{<:VTKDataType}=Float64) ppoints=new_child(grid_xml_node,"PPoints") new_pdata_array(ppoints,type,"Points",3) end function add_ppoint_data!(pdataset::ParallelDatasetFile, name::AbstractString; - type::Type{<:WriteVTK.VTKDataType}=Float64, + type::Type{<:VTKDataType}=Float64, Nc::Integer=1) xroot=root(pdataset.xdoc) dtype = xml_name_to_VTK_Dataset(pdataset.dataset.grid_type) @@ -112,7 +109,7 @@ end function add_pcell_data!(pdataset::ParallelDatasetFile, name::AbstractString; - type::Type{<:WriteVTK.VTKDataType}=Float64, + type::Type{<:VTKDataType}=Float64, Nc=nothing) xroot=root(pdataset.xdoc) dtype = xml_name_to_VTK_Dataset(pdataset.dataset.grid_type) @@ -128,21 +125,21 @@ end function Base.setindex!(pvtk::ParallelDatasetFile, data, name::AbstractString, - loc::WriteVTK.AbstractFieldData) + loc::AbstractFieldData) pvtk.dataset[name,loc]=data end function Base.setindex!(vtk::ParallelDatasetFile, data, name::AbstractString) - pvtk.dataset[name]=data + vtk.dataset[name]=data end -function get_dataset_extension(dataset::WriteVTK.DatasetFile) +function get_dataset_extension(dataset::DatasetFile) path, ext = splitext(dataset.path) @assert ext != "" ext end -function get_dataset_path(dataset::WriteVTK.DatasetFile) +function get_dataset_path(dataset::DatasetFile) path, ext = splitext(dataset.path) @assert ext != "" path @@ -150,15 +147,15 @@ end function xml_name_to_VTK_Dataset(xml_name::AbstractString) if (xml_name=="ImageData") - WriteVTK.VTKImageData() + VTKImageData() elseif (xml_name=="RectilinearGrid") - WriteVTK.VTKRectilinearGrid() + VTKRectilinearGrid() elseif (xml_name=="PolyData") - WriteVTK.VTKPolyData() + VTKPolyData() elseif (xml_name=="StructuredGrid") - WriteVTK.VTKStructuredGrid() + VTKStructuredGrid() elseif (xml_name=="UnstructuredGrid") - WriteVTK.VTKUnstructuredGrid() + VTKUnstructuredGrid() else @assert false end @@ -173,12 +170,12 @@ function get_child_attribute(element,child,attr) attribute(children[child],attr) end -function get_dataset_xml_type(dataset::WriteVTK.DatasetFile) +function get_dataset_xml_type(dataset::DatasetFile) r=root(dataset.xdoc) attribute(r,"type") end -function get_dataset_xml_grid_element(dataset::WriteVTK.DatasetFile, +function get_dataset_xml_grid_element(dataset::DatasetFile, element::AbstractString) r=root(dataset.xdoc) uns=find_element(r,get_dataset_xml_type(dataset)) @@ -213,7 +210,7 @@ end """ function _pvtk_grid_header( layout::PVTKLayout, - dataset::WriteVTK.DatasetFile, + dataset::DatasetFile, filename::AbstractString; ghost_level=0) @@ -226,11 +223,11 @@ function _pvtk_grid_header( set_attribute(grid_xml_node, "GhostLevel", string(ghost_level)) prefix=joinpath(filename,basename(filename)) - extension=WriteVTK.file_extension(dtype) + extension=file_extension(dtype) add_pieces!(grid_xml_node,prefix,extension,layout.nparts) pextension = parallel_file_extension(dtype) - pfilename = WriteVTK.add_extension(filename,pextension) + pfilename = add_extension(filename,pextension) pdataset=ParallelDatasetFile(layout,pvtx,dataset,pfilename) # Generate PPoints @@ -276,15 +273,3 @@ function _pvtk_grid_body(pdataset::ParallelDatasetFile) end pdataset end - -# Suppose that the mesh is made of 5 points: -cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), - MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] -x=rand(5) -y=rand(5) - -layout=PVTKLayout(1,1) -pvtk = pvtk_grid(layout,"simulation", x, y, cells) # 2D -pvtk["Pressure"] = x -pvtk["Processor"] = rand(2) -vtk_save(pvtk) diff --git a/test/checksums.sha1 b/test/checksums.sha1 index fca5cbdd..0790650b 100644 --- a/test/checksums.sha1 +++ b/test/checksums.sha1 @@ -46,3 +46,4 @@ b20bf14b2531aaf323b891e090d0615d0e943ef6 collection_03.vtr 3cf1f5421c36377f38af90b2dc09083726128159 arraydata_2D.vti e0180e5cf18bb7c6f00df0bb9ded769f90b2574e arraydata_3D.vti 9e21f61ebf8641fdcc325836d4bd707e52932441 arrays.vti +bc0ce0fc82137c78a808f4c2a89bc0ca65e348c5 simulation.pvtu diff --git a/test/pvtk_grid.jl b/test/pvtk_grid.jl new file mode 100644 index 00000000..19599239 --- /dev/null +++ b/test/pvtk_grid.jl @@ -0,0 +1,16 @@ +using WriteVTK + +function main() + # Suppose that the mesh is made of 5 points: + cells = [MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]), + MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5])] + x=rand(5) + y=rand(5) + + layout=WriteVTK.PVTKLayout(1,1) + @time pvtk = pvtk_grid(layout,"simulation", x, y, cells) # 2D + pvtk["Pressure"] = x + pvtk["Processor"] = rand(2) + @time vtk_save(pvtk) +end +main() diff --git a/test/runtests.jl b/test/runtests.jl index 1b2f8d57..9f044afa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,6 +15,7 @@ const tests = [ "bezier.jl", "pvdCollection.jl", "array.jl", + "pvtk_grid.jl" ] # Only toggle to generate new checksums, if new tests are added. @@ -59,4 +60,3 @@ for test in tests outfiles = evalfile(test)::Vector{String} println() end - From 31fa4ce6f0eb76ba1dcd009ebdd62bb8f5a1888e Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 20 Oct 2021 11:51:42 +0200 Subject: [PATCH 7/8] Moving file to gridtypes folder --- src/{ => gridtypes}/pvtk_grid.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => gridtypes}/pvtk_grid.jl (100%) diff --git a/src/pvtk_grid.jl b/src/gridtypes/pvtk_grid.jl similarity index 100% rename from src/pvtk_grid.jl rename to src/gridtypes/pvtk_grid.jl From b2b6a09d6e9fe1317b4cbb2a47f00956d10c072b Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 20 Oct 2021 11:51:58 +0200 Subject: [PATCH 8/8] Deleting VTKLayout and other improvements. --- src/WriteVTK.jl | 2 +- src/gridtypes/pvtk_grid.jl | 111 +++++++++++++++++++++++++------------ test/pvtk_grid.jl | 9 ++- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/src/WriteVTK.jl b/src/WriteVTK.jl index 874a1b60..8cd6c36e 100644 --- a/src/WriteVTK.jl +++ b/src/WriteVTK.jl @@ -149,7 +149,7 @@ include("gridtypes/unstructured/polydata.jl") include("gridtypes/array.jl") # Parallel DataSet Formats -include("pvtk_grid.jl") +include("gridtypes/pvtk_grid.jl") # This allows using do-block syntax for generation of VTK files. for func in (:vtk_grid, :vtk_multiblock, :paraview_collection, diff --git a/src/gridtypes/pvtk_grid.jl b/src/gridtypes/pvtk_grid.jl index 187b1eed..f8b622f5 100644 --- a/src/gridtypes/pvtk_grid.jl +++ b/src/gridtypes/pvtk_grid.jl @@ -1,29 +1,47 @@ -struct PVTKLayout - part::Int - nparts::Int - ismain::Bool + +struct ParallelDatasetFile <: VTKFile + pvtkargs::Dict + xdoc::XMLDocument + dataset::DatasetFile + path::AbstractString + function ParallelDatasetFile( + pvtkargs::Dict, + xdoc::XMLDocument, + dataset::DatasetFile, + path::AbstractString) + new(pvtkargs,xdoc,dataset,path) + end end -# By default, we assume that part 1 is the main part -PVTKLayout(part,nparts) = PVTKLayout(part,nparts,part==1) +function _default_pvtkargs(pvtkargs) + mandatory = [:part,:nparts] + optional = [:ismain,:ghost_level] + allkeys = vcat(mandatory,optional) -struct ParallelDatasetFile <: VTKFile - layout::PVTKLayout - xdoc::XMLDocument - dataset::DatasetFile - path::AbstractString - function ParallelDatasetFile(layout::PVTKLayout, - xdoc::XMLDocument, - dataset::DatasetFile, - path::AbstractString) - new(layout,xdoc,dataset,path) - end + d = Dict{Symbol,Any}(pvtkargs) + for k in keys(d) + if !(k in allkeys) + throw(ArgumentError("$k is not a valid key in pvtkargs.")) + end + end + for k in mandatory + if !(haskey(d,k)) + throw(ArgumentError("$k is a mandatory key in pvtkargs.")) + end + end + if ! haskey(d,:ismain) + d[:ismain] = (d[:part] == 1) + end + if ! haskey(d,:ghost_level) + d[:ghost_level] = 0 + end + d end function vtk_save(vtk::ParallelDatasetFile) if isopen(vtk) _pvtk_grid_body(vtk) - if vtk.layout.ismain + if vtk.pvtkargs[:ismain] save_file(vtk.xdoc, vtk.path) end vtk_save(vtk.dataset) @@ -196,23 +214,46 @@ const string_to_VTKDataType = Dict("Int8"=>Int8, "Float64"=>Float64, "String"=>String) -function pvtk_grid(layout::PVTKLayout,args...;ghost_level=0,kwargs...) - filename=args[1] - path, ext = splitext(filename) - bname=basename(path) - path = mkpath(path) - filename=joinpath(path,bname*string(layout.part)*ext) - vtk=vtk_grid((filename,args[2:end]...)...;kwargs...) - _pvtk_grid_header(layout,vtk,path;ghost_level=ghost_level) -end - """ + pvtk_grid(args...;pvtkargs,kwargs...) + +Return a handler representing a parallel vtk file, which can be +eventually written to file with `vtk_save`. + +Positional and keyword arguments in `args` and `kwargs` +are passed to `vtk_grid` verbatim (except file names that are augmented with the +corresponding part id). + +The extra keyword argument `pvtkargs` contains +extra options (as a `Dict{Symbol,Any}` or a `Vector{Pair{Symbol,Any}}`) +that only apply for parallel vtk file formats. + +Mandatory keys in `pvtkargs` are: + +- `:part` current (1-based) part id +- `:nparts` total number of parts + +Default key/value pairs in `pvtkargs` are +- `:ismain=>part==1` True if the current part id `part` is the main (the only one that will write the .pvtk file). +- `:ghost_level=>0` Ghost level. """ +function pvtk_grid(filename::AbstractString,args...;pvtkargs,kwargs...) + _pvtkargs = _default_pvtkargs(pvtkargs) + path, ext = splitext(filename) + bname=basename(path) + path = mkpath(path) + part = _pvtkargs[:part] + nparts = _pvtkargs[:nparts] + p = lpad(part,ceil(Int,log10(nparts)),'0') + fn=joinpath(path,bname*"_$p"*ext) + vtk=vtk_grid(fn,args...;kwargs...) + _pvtk_grid_header(_pvtkargs,vtk,path) +end + function _pvtk_grid_header( - layout::PVTKLayout, - dataset::DatasetFile, - filename::AbstractString; - ghost_level=0) + pvtkargs::Dict, + dataset::DatasetFile, + filename::AbstractString) pvtx = XMLDocument() dtype = xml_name_to_VTK_Dataset(dataset.grid_type) @@ -220,15 +261,15 @@ function _pvtk_grid_header( # Generate parallel grid node grid_xml_node=new_child(xroot,"P"*dataset.grid_type) - set_attribute(grid_xml_node, "GhostLevel", string(ghost_level)) + set_attribute(grid_xml_node, "GhostLevel", string(pvtkargs[:ghost_level])) prefix=joinpath(filename,basename(filename)) extension=file_extension(dtype) - add_pieces!(grid_xml_node,prefix,extension,layout.nparts) + add_pieces!(grid_xml_node,prefix,extension,pvtkargs[:nparts]) pextension = parallel_file_extension(dtype) pfilename = add_extension(filename,pextension) - pdataset=ParallelDatasetFile(layout,pvtx,dataset,pfilename) + pdataset=ParallelDatasetFile(pvtkargs,pvtx,dataset,pfilename) # Generate PPoints points=get_dataset_xml_grid_element(dataset,"Points") diff --git a/test/pvtk_grid.jl b/test/pvtk_grid.jl index 19599239..b0109180 100644 --- a/test/pvtk_grid.jl +++ b/test/pvtk_grid.jl @@ -7,10 +7,13 @@ function main() x=rand(5) y=rand(5) - layout=WriteVTK.PVTKLayout(1,1) - @time pvtk = pvtk_grid(layout,"simulation", x, y, cells) # 2D + @time pvtk = pvtk_grid( + "simulation", x, y, cells; + pvtkargs=[:part=>1,:nparts=>1]) # 2D pvtk["Pressure"] = x pvtk["Processor"] = rand(2) - @time vtk_save(pvtk) + @time outfiles = vtk_save(pvtk) + println("Saved: ", join(outfiles, " ")) + outfiles end main()