Xdmf3 Fortran API: Difference between revisions

From XdmfWeb
Jump to navigationJump to search
(Created page with "Image:XdmfLogo1.gif __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a...")
 
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 131: Line 131:
     |->Grid Collection2
     |->Grid Collection2
     |->Grid Collection3
     |->Grid Collection3
===Xdmf Arrays and other Data===
====Adding Data to Grids====
When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within.
{| class="wikitable"
!Object
!Working Arrays Cleared
|-
|GridCollection
|Attributes, Information, Maps, Sets
|-
|Grid
|Attributes, Information, Maps, Sets
|-
|Attribute
|Information
|-
|Information
|None
|-
|Map
|none
|-
|Set
|Attributes, Information
|}
====Retrieving Data from Closed Grids====
After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called.
! Adding an attribute that is named "Attribute 1"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), &
        XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
        XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
Xdmf Tree:
Attribute 1
! Adding an information named "Information 1"
  tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 1
|Information 1
|}
Xdmf Tree:
Attribute 1
Information 1
! Adding an attribute that is named "Attribute 2"
! Centered on Nodex
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), &
        XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
        XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|-
|Attribute 2
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
Xdmf Tree:
Attribute 1
Attribute 2
|->Information 1
! Adding a set that is named "Set 1"
! A set of Node Type
! contains 12 float values loaded from myNodeAttribute
  testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, &
                          myNodeAttribute,  12, XDMF_ARRAY_TYPE_FLOAT64)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
    |->Information 1
! Adding an attribute that is named "Attribute 3"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), &
        XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
        XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
! Adding an Information named "Information 2"
  tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
    |->Information 1
Attribute 3
Information 2
! Adding a grid named "Unstructured Grid"
  CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
    |->Grid Collection2
    |->Grid Collection3
      |->Unstructured Grid
          |->Set 1
              |->Attribute 1
              |->Attribute 2
                  |->Information 1
          |->Attribute 3
          |->Information 2
====Adding Previously Created Datasets====
If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays.
! Note: Using hard coded indecies here
!      the return value from any of the add functions
!      such as XdmfAddInformation may also be used
  CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3)
  CALL XDMFADDPREVIOUSINFORMATION(obj, 2)
  CALL XDMFADDPREVIOUSSET(obj, 1)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
    |->Information 1
Attribute 3
Information 2
Domain
|->Grid Collection
    |->Grid Collection2
    |->Grid Collection3
      |->Unstructured Grid
          |->Set 1
              |->Attribute 1
              |->Attribute 2
                  |->Information 1
          |->Attribute 3
          |->Information 2
Then we simply call add grid again to insert a grid with the current contents of the working arrays
! Adding a grid named "Unstructured Grid 2"
  CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
    |->Grid Collection2
    |->Grid Collection3
      |->Unstructured Grid
          |->Set 1
              |->Attribute 1
              |->Attribute 2
                  |->Information 1
          |->Attribute 3
          |->Information 2
      |->Unstructured Grid 2
          |->Set 1
              |->Attribute 1
              |->Attribute 2
                  |->Information 1
          |->Attribute 3
          |->Information 2
===Writing to File===
After using the above steps to construct the desired data structure, the structure can be written to file.
CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
CALL XDMFWRITE(obj, 'my_output.xmf'//CHAR(0), 10, .TRUE.)
Then the XdmfFortran API should be closed.
CALL XDMFCLOSE(obj)
===Reading from File===
The following call will read an Xdmf structure from a file and set the API's domain to the domain that was read from the file.
CALL XDMFREAD(obj, 'my_output.xmf'//CHAR(0))
===Retrieving Data from the Xdmf Structure===
====Opening Items====
When a Domain has been read from file no data is yet accessable. First the user needs to open the grids that the Domain contains.
Each object has a corresponding XDMFOPEN call, using an Unstructured Grid as an example:
CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1)
This call will open the unstructured grid at index 0 from the grid collection currently at the top of the stack. The Maps, Attributes, Information, and Sets of that grid will be placed in the appropriate working arrays based on the last four values passed accordingly. This example opens all of them.
====Retrieving/Modifying Data from Arrays====
When an array such as an Attribute is loaded into the working array, its attributes can be interacted with. XdmfRetrieveNumAttributes will produce the number of attributes currently loaded, which can then be referenced by index.
CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained)
PRINT *, 'Number of Grid Attributes: ', numContained
An Attribute's data can be retrieved like so:
  CHARACTER*256 itemName, itemKey, itemValue, itemTag
  INTEGER numContained, typeHolder
  REAL*8 myNodeAttributeOutput(12)
  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256)
  PRINT *, 'Attribute Name: ', itemName
  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained)
  PRINT *, "Number of Properties: ", numContained
  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
  PRINT *, "Key: ", itemKey
  PRINT *, "Value: ", itemValue
  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
  PRINT *, "Value: ", itemValue
  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256)
  PRINT *, 'Attribute Tag: ', itemTag
  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder)
  PRINT *, 'Attribute Type: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder)
  PRINT *, 'Attribute Center: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder)
  PRINT *, 'Attribute Value Type: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained)
  PRINT *, 'Number of Values: ', numContained
  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
  PRINT 3, myNodeAttributeOutput
3 FORMAT (' ', 3F6.1)
If you wanted to modify an Attribute's array instead of retrieve it.
CALL XDMFMODIFYATTRIBUTEVALUES(obj, &
                                startIndex, &
                                myNodeAttributeVals, &
                                XDMF_ARRAY_TYPE_FLOAT64, &
                                numVals, &
                                valueStartIndex, &
                                1, &
                                1)

Latest revision as of 14:58, 7 November 2014

XdmfLogo1.gif

XDMF API

The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root.

After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain.

 CALL XDMFINIT(obj, filename)

The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root.

XdmfGridCollections

After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to.

Xdmf API Grid Collection Stack:

Domain <-- top of stack

Add a Grid Collection to the tree:

! Adding a Grid Collection named "Grid Collection" 
  CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)

Xdmf API Grid Collection Stack:

Grid Collection <-- top of stack
Domain

Another Grid Collection is added:

! Adding a Grid Collection named "Grid Collection2" 
  CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)

Xdmf API Grid Collection Stack:

Grid Collection2 <-- top of stack
Grid Collection
Domain

Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION.

Xdmf API Grid Collection Stack:

Grid Collection2 <-- top of stack
Grid Collection
Domain

Remove a Grid Collection from the top of the stack:

  CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)

Xdmf API Grid Collection Stack:

Grid Collection <-- top of stack
Domain

Returning a Grid Collection to the stack adds it to the top:

! Returning the Grid Collection contained in the domain at position 0 to the stack

 CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)

Xdmf API Grid Collection Stack:

Grid Collection2 <-- top of stack
Grid Collection
Domain

In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added.

Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls.

CALL XDMFINIT(obj, filename)

Xdmf API Grid Collection Stack:

Domain <-- top of stack

Xdmf Tree:

Domain
! Adding a Grid Collection named "Grid Collection" 
  CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)

Xdmf API Grid Collection Stack:

Grid Collection <-- top of stack
Domain

Xdmf Tree:

Domain
|->Grid Collection

! Adding a Grid Collection named "Grid Collection2"

 CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
      XDMF_GRID_COLLECTION_TYPE_TEMPORAL)

Xdmf API Grid Collection Stack:

Grid Collection2 <-- top of stack
Grid Collection
Domain

Xdmf Tree

Domain
|->Grid Collection
   |->Grid Collection2

! Removing the grid Collection from the top of the stack.

 CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)

Xdmf API Grid Collection Stack:

Grid Collection <-- top of stack
Domain

Xdmf Tree:

Domain
|->Grid Collection
   |->Grid Collection2
! Adding a Grid Collection named "Grid Collection3" 
  CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), &
       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)

Xdmf API Grid Collection Stack:

Grid Collection3 <-- top of stack
Grid Collection
Domain

Xdmf Tree:

Domain
|->Grid Collection
   |->Grid Collection2
   |->Grid Collection3

Xdmf Arrays and other Data

Adding Data to Grids

When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within.

Object Working Arrays Cleared
GridCollection Attributes, Information, Maps, Sets
Grid Attributes, Information, Maps, Sets
Attribute Information
Information None
Map none
Set Attributes, Information

Retrieving Data from Closed Grids

After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called.

! Adding an attribute that is named "Attribute 1"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), &
       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
       XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
Attribute Working Attribute Archive
Attribute 1 Attribute 1

Xdmf Tree:

Attribute 1
! Adding an information named "Information 1"
  tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0))
Attribute Working Attribute Archive
Attribute 1 Attribute 1


Information Working Information Archive
Information 1 Information 1

Xdmf Tree:

Attribute 1
Information 1
! Adding an attribute that is named "Attribute 2"
! Centered on Nodex
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), &
       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
       XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
Attribute Working Attribute Archive
Attribute 1 Attribute 1
Attribute 2 Attribute 2


Information Working Information Archive
Information 1

Xdmf Tree:

Attribute 1
Attribute 2
|->Information 1
! Adding a set that is named "Set 1"
! A set of Node Type
! contains 12 float values loaded from myNodeAttribute
  testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, &
                         myNodeAttribute,  12, XDMF_ARRAY_TYPE_FLOAT64)
Attribute Working Attribute Archive
Attribute 1
Attribute 2


Information Working Information Archive
Information 1
Set Working Set Archive
Set 1 Set 1

Xdmf Tree:

Set 1
|->Attribute 1
|->Attribute 2
    |->Information 1
! Adding an attribute that is named "Attribute 3"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), &
       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
       XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
! Adding an Information named "Information 2"
  tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0))
Attribute Working Attribute Archive
Attribute 3 Attribute 1
Attribute 2
Attribute 3
Information Working Information Archive
Information 2 Information 1
Information 2
Set Working Set Archive
Set 1 Set 1

Xdmf Tree:

Set 1
|->Attribute 1
|->Attribute 2
    |->Information 1
Attribute 3
Information 2
! Adding a grid named "Unstructured Grid"
  CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.)
Attribute Working Attribute Archive
Attribute 1
Attribute 2
Attribute 3
Information Working Information Archive
Information 1
Information 2
Set Working Set Archive
Set 1

Xdmf API Grid Collection Stack:

Grid Collection3 <-- top of stack
Grid Collection
Domain

Xdmf Tree:

Domain
|->Grid Collection
   |->Grid Collection2
   |->Grid Collection3
     |->Unstructured Grid
         |->Set 1
             |->Attribute 1
             |->Attribute 2
                 |->Information 1
         |->Attribute 3
         |->Information 2

Adding Previously Created Datasets

If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays.

! Note: Using hard coded indecies here
!       the return value from any of the add functions
!       such as XdmfAddInformation may also be used
  CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3)
  CALL XDMFADDPREVIOUSINFORMATION(obj, 2)
  CALL XDMFADDPREVIOUSSET(obj, 1)
Attribute Working Attribute Archive
Attribute 3 Attribute 1
Attribute 2
Attribute 3
Information Working Information Archive
Information 2 Information 1
Information 2
Set Working Set Archive
Set 1 Set 1

Xdmf API Grid Collection Stack:

Grid Collection3 <-- top of stack
Grid Collection
Domain

Xdmf Tree:

Set 1
|->Attribute 1
|->Attribute 2
   |->Information 1
Attribute 3
Information 2
Domain
|->Grid Collection
   |->Grid Collection2
   |->Grid Collection3
     |->Unstructured Grid
         |->Set 1
             |->Attribute 1
             |->Attribute 2
                 |->Information 1
         |->Attribute 3
         |->Information 2

Then we simply call add grid again to insert a grid with the current contents of the working arrays

! Adding a grid named "Unstructured Grid 2"
  CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.)


Attribute Working Attribute Archive
Attribute 1
Attribute 2
Attribute 3
Information Working Information Archive
Information 1
Information 2
Set Working Set Archive
Set 1

Xdmf API Grid Collection Stack:

Grid Collection3 <-- top of stack
Grid Collection
Domain

Xdmf Tree:

Domain
|->Grid Collection
   |->Grid Collection2
   |->Grid Collection3
     |->Unstructured Grid
         |->Set 1
             |->Attribute 1
             |->Attribute 2
                 |->Information 1
         |->Attribute 3
         |->Information 2
     |->Unstructured Grid 2
         |->Set 1
             |->Attribute 1
             |->Attribute 2
                 |->Information 1
         |->Attribute 3
         |->Information 2

Writing to File

After using the above steps to construct the desired data structure, the structure can be written to file.

CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
CALL XDMFWRITE(obj, 'my_output.xmf'//CHAR(0), 10, .TRUE.)

Then the XdmfFortran API should be closed.

CALL XDMFCLOSE(obj)

Reading from File

The following call will read an Xdmf structure from a file and set the API's domain to the domain that was read from the file.

CALL XDMFREAD(obj, 'my_output.xmf'//CHAR(0))

Retrieving Data from the Xdmf Structure

Opening Items

When a Domain has been read from file no data is yet accessable. First the user needs to open the grids that the Domain contains.

Each object has a corresponding XDMFOPEN call, using an Unstructured Grid as an example:

CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1)

This call will open the unstructured grid at index 0 from the grid collection currently at the top of the stack. The Maps, Attributes, Information, and Sets of that grid will be placed in the appropriate working arrays based on the last four values passed accordingly. This example opens all of them.

Retrieving/Modifying Data from Arrays

When an array such as an Attribute is loaded into the working array, its attributes can be interacted with. XdmfRetrieveNumAttributes will produce the number of attributes currently loaded, which can then be referenced by index.

CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained)
PRINT *, 'Number of Grid Attributes: ', numContained

An Attribute's data can be retrieved like so:

  CHARACTER*256 itemName, itemKey, itemValue, itemTag
  INTEGER numContained, typeHolder
  REAL*8 myNodeAttributeOutput(12)
  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256)
  PRINT *, 'Attribute Name: ', itemName
  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained)
  PRINT *, "Number of Properties: ", numContained
  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
  PRINT *, "Key: ", itemKey
  PRINT *, "Value: ", itemValue
  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
  PRINT *, "Value: ", itemValue
  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256)
  PRINT *, 'Attribute Tag: ', itemTag
  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder)
  PRINT *, 'Attribute Type: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder)
  PRINT *, 'Attribute Center: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder)
  PRINT *, 'Attribute Value Type: ', typeHolder
  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained)
  PRINT *, 'Number of Values: ', numContained
  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
  PRINT 3, myNodeAttributeOutput
3 FORMAT (' ', 3F6.1)

If you wanted to modify an Attribute's array instead of retrieve it.

CALL XDMFMODIFYATTRIBUTEVALUES(obj, &
                               startIndex, &
                               myNodeAttributeVals, &
                               XDMF_ARRAY_TYPE_FLOAT64, &
                               numVals, &
                               valueStartIndex, &
                               1, &
                               1)