This class defines an interaction as a collection of Potentials, ProductPotentials, Coordinators, and BondOrderParameters. It is a wrapper to ease the handling of complicated potentials.
The CompoundPotential class does not define a potential itself, but it defines an abstract superclass which can be used for defining particular potentials as subclasses. One such subclass is the Sutton-Chen potential, which will be used as an example here.
Sutton-Chen potential combines a simple power-law potential with a similar density-like term
where \(r_{ij}\) is the interatomic distance, and \(\varepsilon, a, c, m, n\) are parameters.
In Pysic, this can be defined by a structure like this:
>>> power_pot = pysic.Potential('power', ...)
>>> rho = pysic.BondOrderParameters('power_bond', ...)
>>> root = pysic.BondOrderParameters('sqrt_scale', ...)
>>> sqrt_rho = pysic.Coordinator([root, rho])
>>> rho_pot = pysic.Potential('constant', coordinator=sqrt_rho)
>>> calc = pysic.Pysic()
>>> calc.set_potentials([power_pot, rho_pot])
but this is already somewhat cumbersome and requires Bond order mixing. It would be much nicer to wrap the definitions in a container:
>>> sutton_chen_pot = SuttonChenPotential(...)
>>> calc = pysic.Pysic()
>>> calc.set_potentials(sutton_chen_pot)
This is the purpose of CompoundPotential and its subclasses.
The central classes such as pysic.interactions.local.Potential are imported automatically with the pysic module, which is why you can refer to them with pysic.Potential. Compound potentials are not, so you need to manually import them, for instance like this:
>>> from pysic.interactions.suttonchen import SuttonChenPotential
>>> sutton_chen_pot = SuttonChenPotential(...)
CompoundPotential inherits the interface of Potential and it is used in a similar fashion. A subclass of CompoundPotential then also inherits the interface, and so it is easy to create new potentials this way without having to care about the interface. Defining a subclass in Python is done like this:
>>> class SuttonChenPotential(CompoundPotential):
... def __init__(self, ...):
... super(SuttonChenPotential, self).__init__(...)
...
The brackets in the class definition, (CompoundPotential), tell that the class derives from another class and inherits its functionality. In the constructor, __init__, the superclass constructor is called with super(SuttonChenPotential, self).__init__(...), but it is also possible to extend the constructor with additional commands.
Compound potentials store their components in a list called self.pieces, and this is done in the method define_elements(). The components are passed to the calculator via the build() method. This is automatically called when a compound potential is given to the pysic.calculator.Pysic.add_potential() method, so that the interface is similar to that of simple potentials. For the Sutton-Chen example, the definitions could look something like this:
... def define_elements(self):
... power_pot = pysic.Potential('power', ...)
... rho = pysic.BondOrderParameters('power_bond', ...)
... root = pysic.BondOrderParameters('sqrt_scale', ...)
... sqrt_rho = pysic.Coordinator([root, rho])
... rho_pot = pysic.Potential('constant', coordinator=sqrt_rho)
... self.pieces = [power_pot, rho_pot]
...
In principle, this is the only method that a new potential has to override, since the rest is done automatically. Of course, it is possible to override other methods as well or write new ones. The potentials can be made very general, accepting free parameters and target lists, but it is also possible to hard code the parameters. The latter tends to be easier since handling arbitrary lists of parameters can be a code-intensive task.
The potentials provided with Pysic are all found in pysic.interactions.x where x is the name of the submodule containing the potential.
Below is a list of methods in CompoundPotential, grouped according to the type of functionality. Note that most methods are inherited from the Potential class.
Class representing an interaction constructed of several Potential and ProductPotential objects.
This class implements the framework for wrapping complicated potentials as Python objects. The class itself implements an empty potential. To utilize the compound potential for real calculations, subclasses should be used for defining the actual contents of the potential.
Parameters:
Constructs the potential for the calculator as a collection of elemental potentials.
The method adds all the elemental potentials it consists of one by one through the pysic.calculator.Pysic.add_potential() method.
Parameters:
Fills the compound potential with the elemental potentials it is made of.
This method just stores an empty list. Any subclass to be used as a compound potential should re-implement this method.
Prints a description of the potential on-screen.
Removes the elemental potentials this compound contains from the calculator.
The method removes all the elemental potentials it consists of one by one through the pysic.calculator.Pysic.remove_potential() method. If a match is not found in the set of potentials in the calculator, a message will be printed but the removal process continues.
Parameters:
Sets the name of the potential.
This can be used by subclasses to set the name of the potential. Since normal potentials are distinguished by their names (keywords) compound potentials should also have a name for consistency.
Parameters: