diff --git a/src/xdmf.jl b/src/xdmf.jl
index c117a63..4f87610 100644
--- a/src/xdmf.jl
+++ b/src/xdmf.jl
@@ -35,20 +35,12 @@ using LightXML
# > #define XDMF_3DSMESH 0x1100
# > #define XDMF_3DRECTMESH 0x1101
# > #define XDMF_3DCORECTMESH 0x1102
-"""
-Build a new model for outout
-Parameters
-----------
+global eltypes = Dict{Symbol, Int}(
+ :Tet4 => 0x6,
+ :Quad4 => 0x5,
+ :Tet10 => 0x0026)
-Examples
--------
-
-```julia
-@assert 1+1 == 3
-```
-
-"""
function xdmf_new_model(xdmf_version="2.1")
xdoc = XMLDocument()
xroot = create_root(xdoc, "Xdmf")
@@ -63,11 +55,11 @@ function xdmf_new_temporal_collection(model)
set_attribute(temporal_collection, "CollectionType", "Temporal")
set_attribute(temporal_collection, "GridType", "Collection")
set_attribute(temporal_collection, "Name", "Collection")
- geometry = new_child(temporal_collection, "Geometry")
- set_attribute(geometry, "Type", "None")
- topology = new_child(temporal_collection, "Topology")
- set_attribute(topology, "Dimensions", "0")
- set_attribute(topology, "Type", "NoTopology")
+# geometry = new_child(temporal_collection, "Geometry")
+# set_attribute(geometry, "Type", "None")
+# topology = new_child(temporal_collection, "Topology")
+# set_attribute(topology, "Dimensions", "0")
+# set_attribute(topology, "Type", "NoTopology")
return temporal_collection
end
@@ -79,102 +71,51 @@ function xdmf_new_grid(temporal_collection; time=0)
return grid
end
-#function xdmf_new_mesh(grid, X, elmap)
-# geometry = new_child(grid, "Geometry")
-# set_attribute(geometry, "Type", "XYZ")
-# dataitem = new_child(geometry, "DataItem")
-# set_attribute(dataitem, "DataType", "Float")
-# set_attribute(dataitem, "Dimensions", length(X))
-# set_attribute(dataitem, "Format", "XML")
-# set_attribute(dataitem, "Precision", "4")
-# add_text(dataitem, join(X, " "))
-# topology = new_child(grid, "Topology")
-# set_attribute(topology, "Dimensions", "1")
-# set_attribute(topology, "Type", "Mixed")
-# dataitem = new_child(topology, "DataItem")
-# set_attribute(dataitem, "DataType", "Int")
-# set_attribute(dataitem, "Dimensions", length(elmap))
-# set_attribute(dataitem, "Format", "XML")
-# set_attribute(dataitem, "Precision", 4)
-# elmap2 = copy(elmap)
-# elmap2[2:end,:] -= 1
-# add_text(dataitem, join(elmap2, " "))
-#end
+function xdmf_new_mesh!(grid, nodes, elements)
-function xdmf_new_mesh(grid, X, elmap)
- dim, nnodes = size(X)
+ # 1. write nodes
geometry = new_child(grid, "Geometry")
set_attribute(geometry, "Type", "XYZ")
dataitem = new_child(geometry, "DataItem")
set_attribute(dataitem, "DataType", "Float")
- set_attribute(dataitem, "Dimensions", "$nnodes $dim")
+ ndim = sum([length(node) for node in nodes])
+ info("XDFM: ndim = $ndim")
+ set_attribute(dataitem, "Dimensions", "$ndim")
set_attribute(dataitem, "Format", "XML")
set_attribute(dataitem, "Precision", 8)
- #add_text(dataitem, join(X, " "))
- s = "\n"
-
- for i=1:nnodes
- s *= "\t\t" * join(X[:,i], " ") * "\n"
- end
- s *= " "
- add_text(dataitem, s)
-
- elmap2 = copy(elmap)
- elmap2[2:end,:] -= 1
- dim, nelements = size(elmap2)
+ s = join([join(node, " ") for node in round(nodes, 5)], "\n")
+ add_text(dataitem, "\n"*s*"\n")
+ # 2. write elements
topology = new_child(grid, "Topology")
- #set_attribute(topology, "Dimensions", "1")
+ eldim = sum([length(element[2]) for element in elements]) + length(elements)
set_attribute(topology, "TopologyType", "Mixed")
- set_attribute(topology, "NumberOfElements", nelements)
+ set_attribute(topology, "NumberOfElements", length(elements))
dataitem = new_child(topology, "DataItem")
- set_attribute(dataitem, "DataType", "Int")
- set_attribute(dataitem, "Dimensions", "$nelements $dim")
set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", 8)
- s = "\n"
- for i=1:nelements
- s *= "\t\t" * join(elmap2[:,i], " ") * "\n"
- end
- add_text(dataitem, s)
- #add_text(dataitem, join(elmap2, " "))
+ set_attribute(dataitem, "DataType", "Int")
+ set_attribute(dataitem, "Dimensions", "$eldim")
+# set_attribute(dataitem, "Precision", 8)
+ # note: id numbers start from 0 in Xdmf
+ s = join([join([eltypes[eltype]; connectivity-1], " ") for (eltype, connectivity) in elements], "\n")
+ add_text(dataitem, "\n"*s*"\n")
+
end
-
-function xdmf_new_field(grid, name, source, data)
- loc = Dict("elements" => "Cell",
- "nodes" => "Node")
-
- dim1, dim2 = size(data'')
- if dim1 == 1
- Type = "Scalar"
- end
- if dim1 == 3
- Type = "Vector"
- end
-
- typ = string(typeof(data))
- datatype = "unknown"
- for j in ["Int", "Float"]
- if contains(typ, j)
- datatype = j
- end
- end
- if datatype == "unknown"
- throw("unknown data type ", typ)
- end
-
-
+""" Write Vector field to nodes. """
+function xdmf_new_nodal_field!(grid, name, data)
attribute = new_child(grid, "Attribute")
- set_attribute(attribute, "Center", loc[source])
+ set_attribute(attribute, "Center", "Node")
set_attribute(attribute, "Name", name)
- set_attribute(attribute, "Type", Type)
+ set_attribute(attribute, "Type", "Vector")
dataitem = new_child(attribute, "DataItem")
- set_attribute(dataitem, "DataType", datatype)
- set_attribute(dataitem, "Dimensions", length(data))
+ set_attribute(dataitem, "DataType", "Float")
+ ndim = sum([length(d) for d in data])
+ set_attribute(dataitem, "Dimensions", "$ndim")
set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", 4)
- add_text(dataitem, join(data, " "))
+ set_attribute(dataitem, "Precision", 8)
+ s = join([join(d, " ") for d in round(data, 5)], "\n")
+ add_text(dataitem, "\n"*s*"\n")
end
function xdmf_save_model(xdoc, filename)
diff --git a/test/test_xdmf.jl b/test/test_xdmf.jl
index 8c4f922..559ce30 100644
--- a/test/test_xdmf.jl
+++ b/test/test_xdmf.jl
@@ -1,32 +1,72 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
-using FactCheck
-using Logging
-@Logging.configure(level=INFO)
+module XDMFTests
-using LightXML
+using JuliaFEM
+using JuliaFEM.Postprocess
+using JuliaFEM.Test
testdata = """\
-
-
-
+
- 0 0 0 1 0 0 0 1 0 0 0 1
+
+0.0 0.0 0.0
+1.0 0.0 0.0
+0.0 1.0 0.0
+0.0 0.0 1.0
+0.5 0.0 0.0
+0.5 0.5 0.0
+0.0 0.5 0.0
+0.0 0.0 0.5
+0.5 0.0 0.5
+0.0 0.5 0.5
+1.0 1.0 1.0
+2.0 1.0 1.0
+1.0 2.0 1.0
+1.0 1.0 2.0
+1.5 1.0 1.0
+1.5 1.5 1.0
+1.0 1.5 1.0
+1.0 1.0 1.5
+1.5 1.0 1.5
+1.0 1.5 1.5
+
-
- 6 0 1 2 3
+
+
+38 0 1 2 3 4 5 6 7 8 9
+38 10 11 12 13 14 15 16 17 18 19
+
-
- 56
-
-
- 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0
+
+
+0.0 0.0 0.0
+1.0 0.0 0.0
+0.0 1.0 0.0
+0.0 0.0 1.0
+0.5 0.0 0.0
+0.5 0.5 0.0
+0.0 0.5 0.0
+0.0 0.0 0.5
+0.5 0.0 0.5
+0.0 0.5 0.5
+1.0 1.0 1.0
+2.0 1.0 1.0
+1.0 2.0 1.0
+1.0 1.0 2.0
+1.5 1.0 1.0
+1.5 1.5 1.0
+1.0 1.5 1.0
+1.0 1.0 1.5
+1.5 1.0 1.5
+1.0 1.5 1.5
+
@@ -34,100 +74,56 @@ testdata = """\
"""
-# makes no sense for vector field
-# 1 2 4 7
+function test_write_to_xml()
+ nodes = Vector{Float64}[
+ [0.0, 0.0, 0.0],
+ [1.0, 0.0, 0.0],
+ [0.0, 1.0, 0.0],
+ [0.0, 0.0, 1.0],
+ [0.5, 0.0, 0.0],
+ [0.5, 0.5, 0.0],
+ [0.0, 0.5, 0.0],
+ [0.0, 0.0, 0.5],
+ [0.5, 0.0, 0.5],
+ [0.0, 0.5, 0.5],
+ [1.0, 1.0, 1.0],
+ [2.0, 1.0, 1.0],
+ [1.0, 2.0, 1.0],
+ [1.0, 1.0, 2.0],
+ [1.5, 1.0, 1.0],
+ [1.5, 1.5, 1.0],
+ [1.0, 1.5, 1.0],
+ [1.0, 1.0, 1.5],
+ [1.5, 1.0, 1.5],
+ [1.0, 1.5, 1.5]]
-facts("test test data") do
- 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")
- geometry = new_child(temporal_collection, "Geometry")
- set_attribute(geometry, "Type", "None")
- topology = new_child(temporal_collection, "Topology")
- set_attribute(topology, "Dimensions", "0")
- set_attribute(topology, "Type", "NoTopology")
-
- grid = new_child(temporal_collection, "Grid")
- set_attribute(grid, "Name", "Grid")
- time = new_child(grid, "Time")
- set_attribute(time, "Value", "123")
- geometry = new_child(grid, "Geometry")
- set_attribute(geometry, "Type", "XYZ")
- dataitem = new_child(geometry, "DataItem")
- set_attribute(dataitem, "DataType", "Float")
- set_attribute(dataitem, "Dimensions", "12")
- set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", "4")
- add_text(dataitem, "0 0 0 1 0 0 0 1 0 0 0 1")
-
- topology = new_child(grid, "Topology")
- set_attribute(topology, "Dimensions", "1")
- set_attribute(topology, "Type", "Mixed")
- dataitem = new_child(topology, "DataItem")
- set_attribute(dataitem, "DataType", "Int")
- set_attribute(dataitem, "Dimensions", "5")
- set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", 4)
- add_text(dataitem, "6 0 1 2 3")
- attribute = new_child(grid, "Attribute")
- set_attribute(attribute, "Center", "Cell")
- set_attribute(attribute, "Name", "Temperature field")
- set_attribute(attribute, "Type", "Scalar")
- dataitem = new_child(attribute, "DataItem")
- set_attribute(dataitem, "DataType", "Int")
- set_attribute(dataitem, "Dimensions", 1)
- set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", 4)
- add_text(dataitem, "56")
- attribute = new_child(grid, "Attribute")
- set_attribute(attribute, "Center", "Node")
- set_attribute(attribute, "Name", "Density")
- set_attribute(attribute, "Type", "Vector")
- dataitem = new_child(attribute, "DataItem")
- set_attribute(dataitem, "DataType", "Float")
- set_attribute(dataitem, "Dimensions", 12)
- set_attribute(dataitem, "Format", "XML")
- set_attribute(dataitem, "Precision", 4)
- add_text(dataitem, "1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0")
- #save_file(xdoc, "/tmp/model.xmf")
- @fact string(xdoc) => testdata
+ elements = [
+ (:Tet10, [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+ (:Tet10, [11, 12, 13, 14, 15, 16, 17, 18, 19, 20])]
+
+ displacement_field = nodes # same structure
+ xdoc, model = JuliaFEM.Postprocess.xdmf_new_model()
+ temporal_collection = JuliaFEM.Postprocess.xdmf_new_temporal_collection(model)
+ grid = JuliaFEM.Postprocess.xdmf_new_grid(temporal_collection; time=1)
+ JuliaFEM.Postprocess.xdmf_new_mesh!(grid, nodes, elements)
+ JuliaFEM.Postprocess.xdmf_new_nodal_field!(grid, "Displacement", displacement_field)
+ JuliaFEM.Postprocess.xdmf_save_model(xdoc, "/tmp/foo.xmf")
+ #info("exported data model: \n$(string(xdoc))")
+ #@test string(xdoc) == testdata
+ d1 = split(string(xdoc), "\n")
+# d2 = split(testdata, "\n")
+ d2 = open(readlines, Pkg.dir("JuliaFEM")*"/test/testdata/quad_two_tet10.xmf")
+ println("comparing string")
+ for i in 1:length(d1)
+ println("d1: $(d1[i])")
+ println("d2: $(d2[i])")
+ #status = d1 == d2 ? "MATCHES" : "NO MATCH"
+ #info("line: $(d1[i]) $status")
+ #if d1 != d2
+ # info("should be:\n$(d2[i])")
+ #end
+ d1 == d2 || error("No match")
+ end
end
-using JuliaFEM: xdmf_new_model, xdmf_new_grid, xdmf_new_temporal_collection, xdmf_new_mesh, xdmf_new_field, xdmf_save_model
-
-facts("test model write XML") do
- X = [0 0 0; 1 0 0; 0 1 0; 0 0 1]'
- elmap = [6 1 2 3 4]' # element type 6, nodes 1 2 3 4
- temperature_field = [56]
- density_field = Float64[1 2 3; 4 5 6; 7 8 9; 10 11 12]'
- xdoc, model = xdmf_new_model()
- temporal_collection = xdmf_new_temporal_collection(model)
- grid = xdmf_new_grid(temporal_collection; time=123)
- xdmf_new_mesh(grid, X, elmap)
- xdmf_new_field(grid, "Temperature field", "elements", temperature_field)
- xdmf_new_field(grid, "Density", "nodes", density_field)
- @fact string(xdoc) => testdata
-end
-
-facts("test that xdmf throws error when trying to add field not able to handle") do
- xdoc, model = xdmf_new_model()
- temporal_collection = xdmf_new_temporal_collection(model)
- grid = xdmf_new_grid(temporal_collection; time=123)
- temperature_field = ["56"] # strings not supported by xdmf
- @fact_throws xdmf_new_field(grid, "unknown field data", "elements", temperature_field)
-end
-
-facts("test saving xdmf model") do
- xdoc, model = xdmf_new_model()
- # FIXME: xdoc here is just / of xml file, we're not interested of it but
- # xdmf_new_model returns it that we're able to save xml file.
- t = tempname()
- xdmf_save_model(xdoc, t)
- @fact isfile(t) => true
end
diff --git a/test/testdata/quad_two_tet10.xmf b/test/testdata/quad_two_tet10.xmf
index a831814..e534c40 100644
--- a/test/testdata/quad_two_tet10.xmf
+++ b/test/testdata/quad_two_tet10.xmf
@@ -3,37 +3,61 @@
+
-
-
- 0.0 0.0 0.0
- 1.0 0.0 0.0
- 0.0 1.0 0.0
- 0.0 0.0 1.0
- 0.5 0.0 0.0
- 0.5 0.5 0.0
- 0.0 0.5 0.0
- 0.0 0.0 0.5
- 0.5 0.0 0.5
- 0.0 0.5 0.5
- 1.0 1.0 1.0
- 2.0 1.0 1.0
- 1.0 2.0 1.0
- 1.0 1.0 2.0
- 1.5 1.0 1.0
- 1.5 1.5 1.0
- 1.0 1.5 1.0
- 1.0 1.0 1.5
- 1.5 1.0 1.5
- 1.0 1.5 1.5
-
+
+0.0 0.0 0.0
+1.0 0.0 0.0
+0.0 1.0 0.0
+0.0 0.0 1.0
+0.5 0.0 0.0
+0.5 0.5 0.0
+0.0 0.5 0.0
+0.0 0.0 0.5
+0.5 0.0 0.5
+0.0 0.5 0.5
+1.0 1.0 1.0
+2.0 1.0 1.0
+1.0 2.0 1.0
+1.0 1.0 2.0
+1.5 1.0 1.0
+1.5 1.5 1.0
+1.0 1.5 1.0
+1.0 1.0 1.5
+1.5 1.0 1.5
+1.0 1.5 1.5
+
-
-
- 38 0 1 2 3 4 5 6 7 8 9
- 38 10 11 12 13 14 15 16 17 18 19
-
+
+
+38 0 1 2 3 4 5 6 7 8 9
+38 10 11 12 13 14 15 16 17 18 19
+
+
+
+0.0 0.0 0.0
+1.0 0.0 0.0
+0.0 1.0 0.0
+0.0 0.0 1.0
+0.5 0.0 0.0
+0.5 0.5 0.0
+0.0 0.5 0.0
+0.0 0.0 0.5
+0.5 0.0 0.5
+0.0 0.5 0.5
+1.0 1.0 1.0
+2.0 1.0 1.0
+1.0 2.0 1.0
+1.0 1.0 2.0
+1.5 1.0 1.0
+1.5 1.5 1.0
+1.0 1.5 1.0
+1.0 1.0 1.5
+1.5 1.0 1.5
+1.0 1.5 1.5
+
+