Working with potable files in Python

Using Configuration class to create Pair_Tabulation and EAM_Tabulation objects from potable input

atsim.potentials.config.Configuration is a factory class which accepts potable input and uses it to create tabulation objects.

Tabulation objects are typically created by passing a file like object containing potable input to the read() method of Configuration.

Example

The following example demonstrates how to create a atsim.potentials.pair_tabulation.Pair_Tabulation object from potable input by using the atsim.potentials.config.Configuration class.

The aim of the example is to find the spline coefficients for following potable input (described elsewhere Splining)

[Tabulation]
target : GULP
cutoff : 10.0
dr : 0.01

[Pair]
Si-O : spline(
                    as.zbl 14 8 
              >=0.8 
                    exp_spline 
              >=1.4 
                    as.buck 18003.7572 0.205204 133.5381 )

Running the following script python_potable_api.py will print out the spline coefficients:

import io

from atsim.potentials.config import Configuration

potable_input = """
[Tabulation]
target : GULP
cutoff : 10.0
dr : 0.01

[Pair]
Si-O : spline(
                    as.zbl 14 8 
              >=0.8 
                    exp_spline 
              >=1.4 
                    as.buck 18003.7572 0.205204 133.5381 )
"""


def main():
    # Make a file like object from the potable input string given above.
    potable_input_file = io.StringIO(potable_input)

    # Create a Configuration() object and read input from the input file.
    configuration = Configuration()
    # ... Configuration is a factory class for PairTabulation and EAMTabulation
    #     objects. In the current case it will return a GULP_PairTabulation object.
    tabulation = configuration.read(potable_input_file)

    # The potable input defines a single pair potential.
    # Potential objects are accessible from the tabulation object through
    # its .potentials property.
    potential_Si_O = tabulation.potentials[0]

    # The potential-form for this interaction is now accessed.
    multirange_potentialform = potential_Si_O.potentialFunction

    # The potential-forms created from potable input are Multi_Range_Potential_Form
    # objects. This is true even if only one range is defined, as is the case here.
    #
    # Let's get hold of the spline potential form through the Multi_Range_Potential_Form
    # .range_defns property (which returns a list of MultiRangeDefinitionTuple)
    #
    spline_potentialform = multirange_potentialform.range_defns[0].potential_form

    # Now let's get hold of the spline coefficients
    spline_coefficients = spline_potentialform.splineCoefficients

    print("Spline coefficients are: {}".format(spline_coefficients))


if __name__ == "__main__":
    main()

Overriding and adding items

Items can be amended or added to the potable input before it is passed to the Configuration class. This is done by passing a atsim.potentials.config.ConfigParser to the read_from_parser() method of the Configuration object.

The constructor of ConfigParser accepts overrides and additional parameters, each of which accept lists of atsim.potentials.config.ConfigParserOverrideTuple.

ConfigParserOverrideTuple is a collections.namedtuple with three properties section, key and value. The first two uniquely identify a location in the potable input whilst value specifies what should be added or changed.

So to add an additional pair-potential to potable input contained in a file given by fp the ConfigParser would be defined as:

cp = ConfigParser(fp,
                  additional=[
                      ConfigParserOverrideTuple(
                          "Pair", "O-O", "as.buck 444.7686 0.402 0.0")
                  ])

This would be the same as if the following had been given in the original potable input:

[Pair]
O-O : as.buck 444.7686 0.402 0.0

Similarly to change the tabulation target of a potable file you could use:

cp = ConfigParser(fp,
                  overrides=[
                      ConfigParserOverrideTuple(
                          "Tabulation", "target", "LAMMPS"),
                  ])

A tabulation object is then obtained by combining the ConfigParser with Configuration:

tabulation = Configuration().read_from_parser(cp)

Example

This example shows the use of overrides and additional items. Again the potable input from Splining is used.

[Tabulation]
target : GULP
cutoff : 10.0
dr : 0.01

[Pair]
Si-O : spline(
                    as.zbl 14 8 
              >=0.8 
                    exp_spline 
              >=1.4 
                    as.buck 18003.7572 0.205204 133.5381 )

In python_potable_api.py the tabulation target and potential cutoff in the [Tabulation] section are overriden. An additional O-O interaction is added to the [Pair] section.

This is then used to create a tabulation object which is finally output to the screen:

import io
import sys

from atsim.potentials.config import (ConfigParser, ConfigParserOverrideTuple,
                                     Configuration)

potable_input = """
[Tabulation]
target : GULP
cutoff : 10.0
dr : 0.01

[Pair]
Si-O : spline(
                    as.zbl 14 8 
              >=0.8 
                    exp_spline 
              >=1.4 
                    as.buck 18003.7572 0.205204 133.5381 )
"""


def main():
    # Make a file like object from the potable input string given above.
    potable_input_file = io.StringIO(potable_input)

    # Create a Configuration() object and read input from the input file.
    configuration = Configuration()

    # This example shows how to override and add items to potable input before it
    # is passed to the Configuration object.
    #    The tabulation target will be change to 'LAMMPS'
    #    The cutoff will be reduced to 6.5
    #    An additional pair-interaction will be given for O-O

    cp = ConfigParser(potable_input_file,
                      overrides=[
                          ConfigParserOverrideTuple(
                              "Tabulation", "target", "LAMMPS"),
                          ConfigParserOverrideTuple(
                              "Tabulation", "cutoff", "6.5")
                      ],
                      additional=[
                          ConfigParserOverrideTuple(
                              "Pair", "O-O", "as.buck 444.7686 0.402 0.0")
                      ])

    # Create the tabulation by passing the Config_Parser object to the Configuration.read_from_parser method.
    tabulation = configuration.read_from_parser(cp)

    # Now write tabulation to console
    tabulation.write(sys.stderr)


if __name__ == "__main__":
    main()