input.xml
The exciting code uses one input file That is written in XML. To access the data in the input file exciting used the FoX library. The Fox Library can parse the contents of the xml into a Document object model (DOM) which is a representation of the XML-structure in Memory.
Then the getstructinput(inputnp) function walks througth that tree and converts the data into fortran data types. This code is generated from the XML Schema that describes the detailed grammar and datatypes in the code. Meaning that when something in the schema is added or changed the the fortran code necessary to read it is automatically adapted. Also if it come across an unknown entry the user gets a error message.
This code snippet reads the input file and returns the fortran data structure:
program main
use inputdom ! module that cares about the FoX Calls
use modinput ! module that contains the derived type definitions and parser functions
call loadinputDOM() ! load xml to DOM
input=getstructinput(inputnp) ! builds the tree structure populated with
!default values and configured values
end program
From now on all the data from the input file is available as native fortran datatype in the "input" structure. The values can be used in expressions directly without any further call to a function.
Example
array(1:3)=input%groundstate%ngridk
The expression input%groundstate%ngridk gives the integer array of the number of kmesh points in each direction. All the other attributes are accessed in the same way.
In case of multiple occurrences of an element the syntax to access one of the items in the list is the following as in the example of addressing the coordinates of an atom.
coords(:)=input%structure%speciesarray(is)%species%atomarray(ia)%atom%coord(:)
Remark the peculiar notation atomarray(index)%atom .. stems from the fact that fortran does not allow the construction of an array of pointers. Rather on can only define an array of derived types that contain a pointer
This path reflects directly the path in the xml input file:
<input> <title>LiF</title> <structure speciespath="../../species/"> <crystal> <basevect>3.80402 3.80402 0.00000</basevect> <basevect>3.80402 0.00000 3.80402</basevect> <basevect>0.00000 3.80402 3.80402</basevect> </crystal> <species speciesfile="Li.xml"> <atom coord="0.0000 0.0000 0.0000" /> </species> <species speciesfile="F.xml"> <atom coord="0.5000 0.5000 0.5000" /> </species> </structure> <input>
The default values data types and variable names are all defined in the schema. The input reference generated from this schema contains this information too.
species files
The same as for the input file can be done for the species file too. There is a XML Schema for the species definition and the parser code is generated from this definition. IN order to populate a the species data structure one needs to call this code:
!
Subroutine readspeciesxml
Use modmain
Use modinput, Only: input
Use modsp
Use FoX_dom
Use modspdb
Implicit None
! local variables
Integer :: is, ist, iostat
Integer :: io, nlx, ilx, lx, ilo
Type (Node), Pointer :: speciesnp, speciesdbnp
!
Allocate (speziesdeflist(nspecies))
config => newDOMConfig ()
parseerror = .False.
! parse xml and create derived type for species definitions speziesdeflist
Do is = 1, nspecies
If (trim(input%structure%speciesarray(is)%species%speciesfile) &
& .Eq. "") Then
input%structure%speciesarray(is)%species%speciesfile = trim &
& (input%structure%speciesarray(is)%species%chemicalSymbol) &
& // ".xml"
End If
Write (*,*) "open ", trim (input%structure%speciespath) // "/" &
& // trim &
& (input%structure%speciesarray(is)%species%speciesfile)
doc => parseFile (trim(input%structure%speciespath)//"/"//&
& trim(input%structure%speciesarray(is)%species%speciesfile), &
& config)
speciesdbnp => getDocumentElement (doc)
speciesnp => item (getElementsByTagname(speciesdbnp, "sp"), 0)
parseerror = .False.
speziesdeflist(is)%sp => getstructsp (speciesnp)
Call destroy (doc)
End Do
!
the type speziesdeflist is of type Type (sp_type_array) which is defined in modsp and declared in modspdb.