Write Xdmf
Writing Xdmf
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5.
<?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() DataXml = """<DataItem Dimensions="10 20 30" NumberType="Float" Precision="8" Format="HDF"> XdmfByHand.h5:/Mydata </DataItem>""" # d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed. ~