XDMF API: Difference between revisions

From XdmfWeb
Jump to navigationJump to search
(New page: '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give a...)
 
No edit summary
Line 1: Line 1:
'''XDMF API'''
'''XDMF API'''


Line 6: Line 5:




All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.


Most examples here are written in Python for clarity.
Most examples here are written in Python for clarity.
Line 12: Line 12:
'''XdmfDOM'''
'''XdmfDOM'''


To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.  
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.  


The XdmfDOM can parser strings or files :
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
Status = XdmfDOM.Parse(MyXMLString)
or
or
Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>)
Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>)


As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.


Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :


XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
  XdmfXmlNode     FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)


If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :


DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults
  DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>)       <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode)  <nowiki>#</nowiki> Index is zero based  
  GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode)  <nowiki>#</nowiki> Index is zero based  


By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)  <nowiki>#</nowiki> XPath is 1 based
  GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)  <nowiki>#</nowiki> XPath is 1 based


Once the desired node is found, it can be queried and modified :
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>)


And finally written back out :
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
XmlString = XdmfDOM.Serialize(GridNode)
or
or
Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>)
Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>)


'''XdmfElement'''
'''XdmfElement'''


Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element  
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,  
the UpdateInformation() method will initialize the basic structure of the element  
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.


GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)   
GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)   
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid = XdmfGrid()               <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.UpdateInformation()       <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Grid.Update()                   <nowiki>#</nowiki> Read HeavyData


Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
Is the same as
DOM = Grid.GetDOM()
 
GridNode = Grid.GetElement()
DOM = Grid.GetDOM()
GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)


For output, the XdmfElement methods Insert() and Build() are used.  Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.  
For output, the XdmfElement methods Insert() and Build() are used.  Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.  
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
 
Info.SetName("Time")
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetValue("0.0123")
Info.SetName("Time")
Grid = XdmfGrid()
Info.SetValue("0.0123")
Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>)
Grid = XdmfGrid()
Grid.Insert(Info)
Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>)
Grid.Build()
Grid.Insert(Info)
Grid.Build()


Results in  
Results in  


&lt;Grid Name="My Grid"&gt;
&lt;Grid Name="My Grid"&gt;
&lt;Information Name="Time" Value="0.0123" /&gt;
&lt;Information Name="Time" Value="0.0123" /&gt;
&lt;/Grid&gt;
&lt;/Grid&gt;
 
The Build() method is recursive so that Build() will automatically be called for all child elements.
The Build() method is recursive so that Build() will automatically be called for all child elements.


'''XdmfArray'''
'''XdmfArray'''


The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
float   <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
XdmfInt64       total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray       <nowiki>*</nowiki>xyz = new XdmfArray;


dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE)
xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE)
xyz-&gt;SetShape(3, dims);    // KDim, JDim, IDim
xyz-&gt;SetShape(3, dims);    // KDim, JDim, IDim
xyz-&gt;SetValues(0, x, total, 3, 1);  // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
xyz-&gt;SetValues(0, x, total, 3, 1);  //       SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,  // XdmfInt64 ValuesStride=1)
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,  // XdmfInt64 ValuesStride=1)
xyz-&gt;SetValues(1, y, total, 3, 1);
xyz-&gt;SetValues(1, y, total, 3, 1);
xyz-&gt;SetValues(2, z, total, 3, 1);
xyz-&gt;SetValues(2, z, total, 3, 1);


When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import <nowiki>*</nowiki>
from Xdmf import <nowiki>*</nowiki>


def Expression(<nowiki>*</nowiki>args) :
def Expression(<nowiki>*</nowiki>args) :
     e = <nowiki></nowiki><nowiki></nowiki>
     e = <nowiki></nowiki><nowiki></nowiki>
     for arg in args :
     for arg in args :
         if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) :
         if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) :
             e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki>
             e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki>
         else :
         else :
             e += arg + <nowiki></nowiki> <nowiki></nowiki>
             e += arg + <nowiki></nowiki> <nowiki></nowiki>
     return XdmfExpr(e)
     return XdmfExpr(e)




if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> :
if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> :
     a1 = XdmfArray()
     a1 = XdmfArray()
     a1.SetNumberType(XDMF_FLOAT32_TYPE)
     a1.SetNumberType(XDMF_FLOAT32_TYPE)
Line 120: Line 125:
     a2.SetNumberOfElements(5)
     a2.SetNumberOfElements(5)
     a2.Generate(2, 10)
     a2.Generate(2, 10)
     print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues()
     print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues()
     print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>]</nowiki><nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
     print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
     print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no
     print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues()
wiki>).GetValues()
     print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues()
     a2.SetNumberType(XDMF_FLOAT32_TYPE)
     a2.SetNumberType(XDMF_FLOAT32_TYPE)
     a2.SetNumberOfElements(20)
     a2.SetNumberOfElements(20)
     a2.Generate(21, 40)
     a2.Generate(21, 40)
     print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
     print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
     print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues()
     print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues()
     print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues()
     print <nowiki></nowiki>where(a1 &gt; 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>where(a1 &gt; 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki>]</nowiki><nowiki></nowiki>).GetValues()
     print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10
)<nowiki>]</nowiki><nowiki></nowiki>).GetValues()


While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArray a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.


'''XdmfHDF'''
'''XdmfHDF'''
Line 144: Line 152:




from Xdmf import <nowiki>*</nowiki>
        from Xdmf import <nowiki>*</nowiki>


Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 ��
Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75  
Connectivity = <nowiki></nowiki>3 2 5 1 .
Connectivity = <nowiki></nowiki>3 2 5 1 .
Values = <nowiki></nowiki>100 200 300 ..
Values = <nowiki></nowiki>100 200 300 ..


<nowiki>#</nowiki> Geometry
<nowiki>#</nowiki> Geometry
GeometryArray = XdmfArray()
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
H5.CopyShape(GeometryArray)
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>)
H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>)
H5.Write(GeometryArray)
H5.Write(GeometryArray)
H5.Close()
H5.Close()


<nowiki>#</nowiki> Connectivity
<nowiki>#</nowiki> Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ConnectivityArray)
H5.Write(ConnectivityArray)
H5.Close()
H5.Close()




<nowiki>#</nowiki> Values
<nowiki>#</nowiki> Values
ValueArray = XdmfArray()
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
H5.CopyShape(ValueArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ValueArray)
H5.Write(ValueArray)
H5.Close()
H5.Close()


For reading, XdmfHDF will allocate an array if none is specified :
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
ValueArray = H5.Read()
ValueArray = H5.Read()


'''Reading XDMF'''
'''Reading XDMF'''
Line 192: Line 200:
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.


dom = XdmfDOM()
dom = XdmfDOM()
dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>)
dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>)


ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>)
ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>)
grid = XdmfGrid()
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetDOM(dom)
grid.SetElement(ge)
grid.SetElement(ge)
grid.UpdateInformation()
grid.UpdateInformation()
grid.Update()
grid.Update()  


top = grid.GetTopology()
top = grid.GetTopology()
top.DebugOn()
top.DebugOn()
conn = top.GetConnectivity()
conn = top.GetConnectivity()
print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues()
print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues()


geo = grid.GetGeometry()
geo = grid.GetGeometry()
points = geo.GetPoints()
points = geo.GetPoints()
print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints()
print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>,   geo.GetNumberOfPoints()
print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6)
print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6)


'''Writing XDMF'''
'''Writing XDMF'''


Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api can get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec
ursively.


d = XdmfDOM()
d = XdmfDOM()


root = XdmfRoot()
root = XdmfRoot()
root.SetDOM(d)
root.SetDOM(d)
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.Build()
root.Build()
<nowiki>#</nowiki> Information
<nowiki>#</nowiki> Information
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i.SetName("Time")
i.SetName("Time")
i.SetValue("0.0123")
i.SetValue("0.0123")
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
              <nowiki>#</nowiki> Insert() creates an XML node and inserts it under
                <nowiki>#</nowiki> Insert() creates an XML node and inserts it under
              <nowiki>#</nowiki> the parent
                <nowiki>#</nowiki> the parent
<nowiki>#</nowiki> Domain
<nowiki>#</nowiki> Domain
dm = XdmfDomain()
dm = XdmfDomain()
root.Insert(dm)
root.Insert(dm)
<nowiki>#</nowiki> Grid
<nowiki>#</nowiki> Grid
g = XdmfGrid()
g = XdmfGrid()
g.SetName("Structured Grid")
g.SetName("Structured Grid")
<nowiki>#</nowiki> Topology
<nowiki>#</nowiki> Topology
t = g.GetTopology()
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>)
t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>)
<nowiki>#</nowiki> Geometry
<nowiki>#</nowiki> Geometry
geo = g.GetGeometry()
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
dm.Insert(g)
<nowiki>#</nowiki> Attribute
<nowiki>#</nowiki> Attribute
attr = XdmfAttribute()
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p = attr.GetValues()
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
g.Insert(attr)
<nowiki>#</nowiki> Update XML and Write Values to DataItems
<nowiki>#</nowiki> Update XML and Write Values to DataItems
root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy
root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy
print d.Serialize() <nowiki>#</nowiki> prints to stdout
print d.Serialize() <nowiki>#</nowiki> prints to stdout  


d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file
d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file

Revision as of 11:30, 3 May 2007

XDMF API


While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.


All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively.

Most examples here are written in Python for clarity.

XdmfDOM

To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.

The XdmfDOM can parser strings or files :

Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(MyXMLFile.xmf)

As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.

Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the nth instance of an element bel ow a parent node :

 XdmfXmlNode     FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)

If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :

 DomainNode = XdmfDOM.FindElemet(Domain)       # Take all defaults
 GridNode = XdmfDOM.FindElement(Grid, 2, DomainNode)   # Index is zero based 

By utilizing the XPath functionality of libxml2, the same Grid element can be found by :

 GridNode = XdmfDOM.FindElementByPath(/Xdmf/Domain/Grid[3])  # XPath is 1 based

Once the desired node is found, it can be queried and modified :

NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, Name)
SubGrid = XdmfDOM.InsertNew(GridNode, Grid)
Status = XdmfDOM.Set(SubGrid, Name, My SubGrid)

And finally written back out :

XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write(MyFile.xmf)

XdmfElement

Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.

GridNode = DOM.FindElementByPath(/Xdmf/Domain/Grid[3])  
Grid = XdmfGrid()               # Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation()        # Update Light Structure
Grid.Update()                   # Read HeavyData

Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(Name) Is the same as

DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, Name)

For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.

Info = XdmfInformation() # Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set(Name, My Grid)
Grid.Insert(Info)
Grid.Build()

Results in

<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>

The Build() method is recursive so that Build() will automatically be called for all child elements.

XdmfArray

The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as

input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float   *x, *y, *z;
XdmfInt64       total, dims[3];
XdmfArray       *xyz = new XdmfArray;
dims[0] = 10;
dims[1] = 20;
dims[2] = 30;
total = 10 * 20 * 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims);    // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1);  //       SetValues (XdmfInt64 Index, XdmfFloat64 *Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,  // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);

When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.

from Xdmf import *
def Expression(*args) :
   e = 
   for arg in args :
       if hasattr(arg, GetTagName) :
           e += arg.GetTagName() +  
       else :
           e += arg +  
   return XdmfExpr(e)


if __name__ == __main__ :
   a1 = XdmfArray()
   a1.SetNumberType(XDMF_FLOAT32_TYPE)
   a1.SetNumberOfElements(20)
   a1.Generate(1, 20)
   a2 = XdmfArray()
   a2.SetNumberType(XDMF_INT32_TYPE)
   a2.SetNumberOfElements(5)
   a2.Generate(2, 10)
   print a1 Values = , a1.GetValues()
   print a1[2:10] =  + Expression(a1 , [ 2:10 ] ).GetValues()
   print a2 Values = , a2.GetValues()
   print a1[a2] =  + Expression(a1 , [, a2, ]</no
wiki>).GetValues()
    print <nowiki>a1 + a2 =  + Expression(a1 ,  + , a2).GetValues()
   print a1 * a2 =  + Expression(a1 ,  * , a2).GetValues()
   a2.SetNumberType(XDMF_FLOAT32_TYPE)
   a2.SetNumberOfElements(20)
   a2.Generate(21, 40)
   print a2 Values = , a2.GetValues()
   print a1 , a2 (Interlace) =  + Expression(a1 ,  , , a2).GetValues()
   print a1 , a2, a1 (Interlace) =  + Expression(a1 ,  , , a2,  , , a1).GetValues()
   print a1 ; a2 (Concat) =  + Expression(a1 ,  ; , a2).GetValues()
   print where(a1 > 10) =  + Expression(Where( , a1 ,  > 10)).GetValues()
   print a2[where(a1 > 10)] =  + Expression(a2, [Where( , a1 ,  > 10

)]).GetValues()

While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.

XdmfHDF

In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :


       from Xdmf import *
Geometry = -1.75 -1.25 0 -1.25 -1.25 0 -0.75 
Connectivity = 3 2 5 1 .
Values = 100 200 300 ..
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open(Example1.h5:/Geometry, w)
H5.Write(GeometryArray)
H5.Close()
# Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open(Example1.h5:/Connectivity, rw)
H5.Write(ConnectivityArray)
H5.Close()


# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open(Example1.h5:/Values, rw)
H5.Write(ValueArray)
H5.Close()

For reading, XdmfHDF will allocate an array if none is specified :

Status = H5.Open(Example1.h5:/Values, rw)
ValueArray = H5.Read()

Reading XDMF

Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.

dom = XdmfDOM()
dom.Parse(Points.xmf)
ge = dom.FindElementByPath(/Xdmf/Domain/Grid)
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update() 
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print Values = , conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print Geo Type = , geo.GetGeometryTypeAsString(),  # Points = ,    geo.GetNumberOfPoints()
print Points = , points.GetValues(0, 6)

Writing XDMF

Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec ursively.

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("Time")
i.SetValue("0.0123")
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_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(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(MyMesh.xmf) # write to file