Write Xdmf: Difference between revisions

From XdmfWeb
Jump to navigationJump to search
(New page: == 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, provi...)
 
No edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 7: Line 7:
  from Xdmf import *
  from Xdmf import *
   
   
d = XdmfDOM()
  root = XdmfDomain.New()
  root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
  # Information
  # Information
  i = XdmfInformation() # Arbitrary Name=Value Facility
  info = XdmfInformation.New() # Arbitrary Name=Value Facility
  i.SetName("Time")
  info.SetName("SampleLocation")
  i.SetValue("0.0123")
  info.SetValue("4")
  root.Insert(i) # XML DOM is used as the keeper of the structure
  root.insert(i) # XML Domain is used as the keeper of the structure
              # Insert() creates an XML node and inserts it under
                # Insert() creates an XML node and inserts it under
              # the parent
                # the parent
  # Domain
  # Origin X,Y,Z
  dm = XdmfDomain()
newGridOrigin = XdmfArray.New()
  root.Insert(dm)
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
  newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
  newNumPoints.pushBackAsUInt32(30)
  # Grid
  # Grid
  g = XdmfGrid()
  grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
g.SetName("Structured Grid")
  # Topology and Geometry are set based on the provided arrays
  # Topology
  grid.setName("Structured Grid")
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
  # Attribute
  attr = XdmfAttribute()
  attr = XdmfAttribute.New()
  attr.SetName("Pressure")
  attr.setName("Pressure")
  attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
  attr.setAttributeCenter(XdmfAttributeCenter.Node());
  attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
  attr.setAttributeType(XdmfAttributeType.Scalar());
  p = attr.GetValues()
  # The attribute has the same dims as the Grid
  p.SetNumberOfElements(10 * 20 * 30)
attr.initialize(XdmfArrayType.Float64(), newNumPoints)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
  # Fill with values however you prefer
  g.Insert(attr)
# Simply using a loop to fill in this case
  # Update XML and Write Values to DataItems
for i in range(0, 10 * 20 * 30)
root.Build() # DataItems > 100 values are heavy
  attr.insertAsFloat64(i, 5.0)
print d.Serialize() # prints to stdout
  grid.insert(attr)
   
  writer = XdmfWriter.New('SMesh.xmf')  
d.Write('SMesh.xmf') # write to file
  root.accept(writer)






Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
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.
to be written to SMesh.h5.


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
  <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
  <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
  <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
   <Information Name="Time" Value="0.0123"/>
   <Information Name="SampleLocation" Value="4"/>
   <Domain>
   <Domain>
     <Grid Name="Structured Grid" GridType="Uniform">
     <Grid Name="Structured Grid" GridType="Uniform">
Line 72: Line 70:
       </Geometry>
       </Geometry>
       <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
       <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
         <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
         <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">SMesh.xmf.h5:/Data</DataItem>
       </Attribute>
       </Attribute>
     </Grid>
     </Grid>
   </Domain>
   </Domain>
  </Xdmf>
  </Xdmf>
~
 
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfArrays can be provided a child HeavyDataController that points to a dataset in heavy data. When the XdmfWriter is set to DistributedHeavyData mode it will not read in the data and write it out to a new heavy data location.
 
#!/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
array = XdmfArray.New()
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
array.initialize(XdmfArrayType.Float64(), dims)
# Simply using a loop to fill in this case
for i in range(0, 10 * 20 * 30)
  attr.insertAsFloat64(i, 5.0)
h5writer = XdmfHDF5Writer.New('XdmfByHand.h5')
array.accept(h5writer)
# Retrieve the data set that the writer wrote to
dataset = array.getHeavyDataController().getDataSetPath()
root = XdmfDomain.New()
root.SetDOM(d)
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("SampleLocation")
i.setValue("4")
root.insert(i) # XML Domain is used as the keeper of the structure
                # Insert() creates an XML node and inserts it under
                # the parent
# Origin X,Y,Z
newGridOrigin = XdmfArray.New()
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
newNumPoints.pushBackAsUInt32(30)
# Grid
grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
# Topology and Geometry are set based on the provided arrays
grid.setName("Structured Grid")
root.insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter.Node())
attr.setAttributeType(XdmfAttributeType.Scalar())
# Build a heavy data controller
starts = UInt32Vector()
starts.push_back(0)
starts.push_back(0)
starts.push_back(0)
strides = UInt32Vector()
strides.push_back(1)
strides.push_back(1)
strides.push_back(1)
controller = XdmfHDF5Controller.New('SMesh.h5',
                                    dataset, # Stored from earlier
                                    XdmfArrayType.Float64(),
                                    starts,
                                    strides,
                                    dims,
                                    dims)
writer = XdmfWriter.New('secondSMesh.h5')
writer.setMode(XdmfWriter.DistributedHeavyData)
root.accept(writer)
 
This results in identical XML with just the name of the HDF5 dataset changed.

Latest revision as of 12:16, 10 November 2014

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 *

root = XdmfDomain.New()
# Information
info = XdmfInformation.New() # Arbitrary Name=Value Facility
info.SetName("SampleLocation")
info.SetValue("4")
root.insert(i) # XML Domain is used as the keeper of the structure
               # Insert() creates an XML node and inserts it under
               # the parent
# Origin X,Y,Z
newGridOrigin = XdmfArray.New()
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
newNumPoints.pushBackAsUInt32(30)
# Grid
grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
# Topology and Geometry are set based on the provided arrays
grid.setName("Structured Grid")
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter.Node());
attr.setAttributeType(XdmfAttributeType.Scalar());
# The attribute has the same dims as the Grid
attr.initialize(XdmfArrayType.Float64(), newNumPoints)
# Fill with values however you prefer
# Simply using a loop to fill in this case
for i in range(0, 10 * 20 * 30)
  attr.insertAsFloat64(i, 5.0)
grid.insert(attr)
writer = XdmfWriter.New('SMesh.xmf') 
root.accept(writer)


Would result in the Light Data XML to be written to the file SMesh.xmf and the Heavy data to be written to SMesh.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">SMesh.xmf.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 XdmfArrays can be provided a child HeavyDataController that points to a dataset in heavy data. When the XdmfWriter is set to DistributedHeavyData mode it will not read in the data and write it out to a new heavy data location.

#!/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
array = XdmfArray.New()
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
array.initialize(XdmfArrayType.Float64(), dims)
# Simply using a loop to fill in this case
for i in range(0, 10 * 20 * 30)
  attr.insertAsFloat64(i, 5.0)
h5writer = XdmfHDF5Writer.New('XdmfByHand.h5')
array.accept(h5writer)
# Retrieve the data set that the writer wrote to
dataset = array.getHeavyDataController().getDataSetPath()

root = XdmfDomain.New()
root.SetDOM(d)
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("SampleLocation")
i.setValue("4")
root.insert(i) # XML Domain is used as the keeper of the structure
               # Insert() creates an XML node and inserts it under
               # the parent
# Origin X,Y,Z
newGridOrigin = XdmfArray.New()
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
newNumPoints.pushBackAsUInt32(30)
# Grid
grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
# Topology and Geometry are set based on the provided arrays
grid.setName("Structured Grid")
root.insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter.Node())
attr.setAttributeType(XdmfAttributeType.Scalar())
# Build a heavy data controller
starts = UInt32Vector()
starts.push_back(0)
starts.push_back(0)
starts.push_back(0)
strides = UInt32Vector()
strides.push_back(1)
strides.push_back(1)
strides.push_back(1)
controller = XdmfHDF5Controller.New('SMesh.h5',
                                    dataset, # Stored from earlier
                                    XdmfArrayType.Float64(),
                                    starts,
                                    strides,
                                    dims,
                                    dims)
writer = XdmfWriter.New('secondSMesh.h5')
writer.setMode(XdmfWriter.DistributedHeavyData)
root.accept(writer)

This results in identical XML with just the name of the HDF5 dataset changed.