mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-13 23:54:18 +00:00
196 lines
6.6 KiB
Julia
196 lines
6.6 KiB
Julia
# This file is a part of JuliaFEM.
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|
|
|
using LightXML
|
|
using JuliaFEM
|
|
|
|
# element codes: http://www.paraview.org/pipermail/paraview/2013-July/028859.html
|
|
# > from ./VTK/ThirdParty/xdmf2/vtkxdmf2/libsrc/XdmfTopology.h
|
|
# >
|
|
# > // Topologies
|
|
# > #define XDMF_NOTOPOLOGY 0x0
|
|
# > #define XDMF_POLYVERTEX 0x1
|
|
# > #define XDMF_POLYLINE 0x2
|
|
# > #define XDMF_POLYGON 0x3
|
|
# > #define XDMF_TRI 0x4
|
|
# > #define XDMF_QUAD 0x5
|
|
# > #define XDMF_TET 0x6
|
|
# > #define XDMF_PYRAMID 0x7
|
|
# > #define XDMF_WEDGE 0x8
|
|
# > #define XDMF_HEX 0x9
|
|
# > #define XDMF_EDGE_3 0x0022
|
|
# > #define XDMF_TRI_6 0x0024
|
|
# > #define XDMF_QUAD_8 0x0025
|
|
# > #define XDMF_QUAD_9 0x0023
|
|
# > #define XDMF_TET_10 0x0026
|
|
# > #define XDMF_PYRAMID_13 0x0027
|
|
# > #define XDMF_WEDGE_15 0x0028
|
|
# > #define XDMF_WEDGE_18 0x0029
|
|
# > #define XDMF_HEX_20 0x0030
|
|
# > #define XDMF_HEX_24 0x0031
|
|
# > #define XDMF_HEX_27 0x0032
|
|
# > #define XDMF_MIXED 0x0070
|
|
# > #define XDMF_2DSMESH 0x0100
|
|
# > #define XDMF_2DRECTMESH 0x0101
|
|
# > #define XDMF_2DCORECTMESH 0x0102
|
|
# > #define XDMF_3DSMESH 0x1100
|
|
# > #define XDMF_3DRECTMESH 0x1101
|
|
# > #define XDMF_3DCORECTMESH 0x1102
|
|
|
|
get_xdmf_element_code(element::Element{Poi1}) = 0x0001
|
|
get_xdmf_element_code(element::Element{Seg2}) = 0x0002
|
|
get_xdmf_element_code(element::Element{Seg3}) = 0x0003
|
|
get_xdmf_element_code(element::Element{Tri3}) = 0x0004
|
|
get_xdmf_element_code(element::Element{Quad4}) = 0x0005
|
|
get_xdmf_element_code(element::Element{Tet4}) = 0x0006
|
|
get_xdmf_element_code(element::Element{Hex8}) = 0x0009
|
|
get_xdmf_element_code(element::Element{Tet10}) = 0x0026
|
|
|
|
type XDMF
|
|
dimension :: Int
|
|
use_hdf :: Bool
|
|
xdoc :: XMLDocument
|
|
domain :: XMLElement
|
|
temporal_collection :: XMLElement
|
|
current_grid
|
|
permutation :: Vector{Int}
|
|
end
|
|
|
|
function XDMF()
|
|
xdoc = XMLDocument()
|
|
xroot = create_root(xdoc, "Xdmf")
|
|
set_attribute(xroot, "xmlns:xi", "http://www.w3.org/2001/XInclude")
|
|
set_attribute(xroot, "Version", "2.1")
|
|
domain = new_child(xroot, "Domain")
|
|
temporal_collection = new_child(domain, "Grid")
|
|
set_attribute(temporal_collection, "CollectionType", "Temporal")
|
|
set_attribute(temporal_collection, "GridType", "Collection")
|
|
set_attribute(temporal_collection, "Name", "Collection")
|
|
return XDMF(3, false, xdoc, domain, temporal_collection, Union{}, [])
|
|
end
|
|
|
|
function xdmf_new_result!(xdmf::XDMF, elements::Vector, time)
|
|
grid = new_child(xdmf.temporal_collection, "Grid")
|
|
set_attribute(grid, "Name", "Grid")
|
|
time_ = new_child(grid, "Time")
|
|
set_attribute(time_, "Value", time)
|
|
xdmf.current_grid = grid
|
|
|
|
# 1. calculate permutation
|
|
nids = Set()
|
|
X = Dict{Int64, Vector{Float64}}()
|
|
for element in elements
|
|
conn = get_connectivity(element)
|
|
push!(nids, conn...)
|
|
X_el = element["geometry"](time)
|
|
for (i, c) in enumerate(conn)
|
|
X[c] = X_el[i]
|
|
end
|
|
end
|
|
xdmf.permutation = sort(collect(nids))
|
|
iperm = Dict{Int64, Int64}()
|
|
for (i, j) in enumerate(xdmf.permutation)
|
|
iperm[j] = i
|
|
end
|
|
|
|
# 2. write nodes
|
|
geometry = new_child(grid, "Geometry")
|
|
set_attribute(geometry, "Type", xdmf.dimension == 3 ? "XYZ" : "XY")
|
|
dataitem = new_child(geometry, "DataItem")
|
|
set_attribute(dataitem, "DataType", "Float")
|
|
set_attribute(dataitem, "Format", "XML")
|
|
#set_attribute(dataitem, "Precision", 8)
|
|
s = ASCIIString[]
|
|
ndim = 0
|
|
for i in xdmf.permutation
|
|
ndim += length(X[i])
|
|
push!(s, join(round(X[i], 5), " "))
|
|
end
|
|
set_attribute(dataitem, "Dimensions", ndim)
|
|
add_text(dataitem, "\n"*join(s, "\n")*"\n")
|
|
|
|
# 3. write elements
|
|
topology = new_child(grid, "Topology")
|
|
set_attribute(topology, "TopologyType", "Mixed")
|
|
set_attribute(topology, "NumberOfElements", length(elements))
|
|
dataitem = new_child(topology, "DataItem")
|
|
set_attribute(dataitem, "Format", "XML")
|
|
set_attribute(dataitem, "DataType", "Int")
|
|
# set_attribute(dataitem, "Precision", 8)
|
|
s = ASCIIString[]
|
|
eldim = 0
|
|
for element in elements
|
|
eltype = get_xdmf_element_code(element)
|
|
# note: id numbers start from 0 in Xdmf
|
|
conn = [iperm[j] for j in get_connectivity(element)] - 1
|
|
data = [eltype; conn]
|
|
eldim += length(data)
|
|
push!(s, join(data, " "))
|
|
end
|
|
set_attribute(dataitem, "Dimensions", eldim)
|
|
add_text(dataitem, "\n"*join(s, "\n")*"\n")
|
|
end
|
|
|
|
function xdmf_save_field!(xdmf, elements::Vector, time, field_name; field_type="Scalar", debug=false)
|
|
f = Dict()
|
|
field_dim = 0
|
|
for element in elements
|
|
haskey(element, field_name) || continue
|
|
g = element[field_name](time)
|
|
conn = get_connectivity(element)
|
|
for (i, c) in enumerate(conn)
|
|
gi = g[i]
|
|
if (field_type == "Vector") && (length(gi) < 3)
|
|
# paraview goes crazy if 2d model with 2d displacement vector
|
|
gi = [gi; 0.0]
|
|
end
|
|
if field_dim == 0
|
|
field_dim = length(gi)
|
|
end
|
|
field_dim == length(gi) || error("several dimensions in field, dim = $field_dim.")
|
|
f[c] = gi
|
|
end
|
|
end
|
|
|
|
if length(f) == 0
|
|
warn("xdmf_save_field!(): field $field_name was not found from set of elements")
|
|
return
|
|
end
|
|
|
|
attribute = new_child(xdmf.current_grid, "Attribute")
|
|
set_attribute(attribute, "Center", "Node")
|
|
set_attribute(attribute, "Name", ucfirst(field_name))
|
|
set_attribute(attribute, "Type", field_type)
|
|
dataitem = new_child(attribute, "DataItem")
|
|
set_attribute(dataitem, "DataType", "Float")
|
|
set_attribute(dataitem, "Format", "XML")
|
|
#set_attribute(dataitem, "Precision", 8)
|
|
debug && info("field dim = $field_dim")
|
|
debug && info(f)
|
|
s = ASCIIString[]
|
|
dim = 0
|
|
for i in xdmf.permutation
|
|
gi = zeros(field_dim)
|
|
if haskey(f, i)
|
|
gi = f[i]
|
|
end
|
|
push!(s, join(round(gi, 5), " "))
|
|
dim += length(gi)
|
|
end
|
|
set_attribute(dataitem, "Dimensions", dim)
|
|
add_text(dataitem, "\n"*join(s, "\n")*"\n")
|
|
end
|
|
|
|
function xdmf_save_field!(xdmf, problem::Problem, time, field_name; field_type="Scalar")
|
|
xdmf_save_field!(xdmf, problem.elements, time, field_name; field_type=field_type)
|
|
end
|
|
|
|
function xdmf_new_result!(xdmf, problem::Problem, time)
|
|
xdmf_new_result!(xdmf, problem.elements, time)
|
|
end
|
|
|
|
function xdmf_save!(xdmf, filename)
|
|
save_file(xdmf.xdoc, filename)
|
|
end
|
|
|