Ejemplo n.º 1
0
def _validate_compatibility(top):
    """Check compatability of topology object with GROMACS TOP format"""
    templates = PotentialTemplateLibrary()
    lennard_jones_potential = templates['LennardJonesPotential']
    harmonic_bond_potential = templates['HarmonicBondPotential']
    harmonic_angle_potential = templates['HarmonicAnglePotential']
    accepted_potentials = [lennard_jones_potential, harmonic_bond_potential, harmonic_angle_potential]
    check_compatibility(top, accepted_potentials)
Ejemplo n.º 2
0
def convert_ryckaert_to_opls(ryckaert_connection_type):
    """Convert Ryckaert-Bellemans dihedral to OPLS.

    NOTE: the conventions defining the dihedral angle are different
    for OPLS and RB torsions. OPLS torsions are defined with
    phi_cis = 0 while RB torsions are defined as phi_trans = 0.
    """
    templates = PotentialTemplateLibrary()
    ryckaert_bellemans_torsion_potential = templates[
        "RyckaertBellemansTorsionPotential"]
    opls_torsion_potential = templates["OPLSTorsionPotential"]

    valid_connection_type = False
    if (ryckaert_connection_type.independent_variables ==
            ryckaert_bellemans_torsion_potential.independent_variables):
        if (sympy.simplify(ryckaert_connection_type.expression -
                           ryckaert_bellemans_torsion_potential.expression) ==
                0):
            valid_connection_type = True
    if not valid_connection_type:
        raise GMSOError("Cannot use convert_ryckaert_to_opls "
                        "function to convert a ConnectionType that is not an "
                        "RyckaertBellemansTorsionPotential")

    c0 = ryckaert_connection_type.parameters["c0"]
    c1 = ryckaert_connection_type.parameters["c1"]
    c2 = ryckaert_connection_type.parameters["c2"]
    c3 = ryckaert_connection_type.parameters["c3"]
    c4 = ryckaert_connection_type.parameters["c4"]
    c5 = ryckaert_connection_type.parameters["c5"]

    if c5 != 0.0:
        raise GMSOError("Cannot convert Ryckaert-Bellemans dihedral "
                        "to OPLS dihedral if c5 is not equal to zero.")

    converted_params = {
        "k0": 2.0 * (c0 + c1 + c2 + c3 + c4),
        "k1": (-2.0 * c1 - (3.0 / 2.0) * c3),
        "k2": (-c2 - c4),
        "k3": ((-1.0 / 2.0) * c3),
        "k4": ((-1.0 / 4.0) * c4),
    }

    name = opls_torsion_potential.name
    expression = opls_torsion_potential.expression
    variables = opls_torsion_potential.independent_variables

    opls_connection_type = gmso.DihedralType(
        name=name,
        expression=expression,
        independent_variables=variables,
        parameters=converted_params,
    )

    return opls_connection_type
Ejemplo n.º 3
0
def convert_ryckaert_to_opls(ryckaert_connection_type):
    """Convert Ryckaert-Bellemans dihedral to OPLS

    NOTE: the conventions defining the dihedral angle are different
    for OPLS and RB torsions. OPLS torsions are defined with
    phi_cis = 0 while RB torsions are defined as phi_trans = 0.
    """
    templates = PotentialTemplateLibrary()
    ryckaert_bellemans_torsion_potential = templates[
        'RyckaertBellemansTorsionPotential']
    opls_torsion_potential = templates['OPLSTorsionPotential']

    valid_connection_type = False
    if (ryckaert_connection_type.independent_variables ==
            ryckaert_bellemans_torsion_potential.independent_variables):
        if sympy.simplify(
                ryckaert_connection_type.expression -
                ryckaert_bellemans_torsion_potential.expression) == 0:
            valid_connection_type = True
    if not valid_connection_type:
        raise GMSOError('Cannot use convert_ryckaert_to_opls '
                        'function to convert a ConnectionType that is not an '
                        'RyckaertBellemansTorsionPotential')

    c0 = ryckaert_connection_type.parameters['c0']
    c1 = ryckaert_connection_type.parameters['c1']
    c2 = ryckaert_connection_type.parameters['c2']
    c3 = ryckaert_connection_type.parameters['c3']
    c4 = ryckaert_connection_type.parameters['c4']
    c5 = ryckaert_connection_type.parameters['c5']

    if c5 != 0.0:
        raise GMSOError('Cannot convert Ryckaert-Bellemans dihedral '
                        'to OPLS dihedral if c5 is not equal to zero.')

    converted_params = {
        'k0': 2. * (c0 + c1 + c2 + c3 + c4),
        'k1': (-2. * c1 - (3. / 2.) * c3),
        'k2': (-c2 - c4),
        'k3': ((-1. / 2.) * c3),
        'k4': ((-1. / 4.) * c4)
    }

    name = opls_torsion_potential.name
    expression = opls_torsion_potential.expression
    variables = opls_torsion_potential.independent_variables

    opls_connection_type = gmso.DihedralType(name=name,
                                             expression=expression,
                                             independent_variables=variables,
                                             parameters=converted_params)

    return opls_connection_type
Ejemplo n.º 4
0
 def test_class_method(self):
     template = PotentialTemplateLibrary()['HarmonicBondPotential']
     params = {'k': 1.0 * u.dimensionless,
               'r_eq': 1.0 * u.dimensionless}
     harmonic_potential_from_template = ParametricPotential.from_template(template, params)
     harmonic_potential = ParametricPotential(name='HarmonicBondPotential',
                                              expression='0.5 * k * (r-r_eq)**2',
                                              independent_variables={'r'},
                                              parameters=params)
     assert harmonic_potential.name == harmonic_potential_from_template.name
     assert harmonic_potential.expression == harmonic_potential_from_template.expression
     assert harmonic_potential.independent_variables == harmonic_potential_from_template.independent_variables
Ejemplo n.º 5
0
    def test_noble_mie_xml(self):
        ff = ForceField(get_path('noble_mie.xml'))
        templates = PotentialTemplateLibrary()
        ref_expr = templates['MiePotential'].expression

        assert len(ff.atom_types) == 4
        assert len(ff.bond_types) == 0
        assert len(ff.angle_types) == 0
        assert len(ff.dihedral_types) == 0

        for (name, atom_type) in ff.atom_types.items():
            assert sympy.simplify(atom_type.expression - ref_expr) == 0

        assert allclose(ff.atom_types['Ne'].parameters['epsilon'],
                        0.26855713 * u.Unit('kJ/mol'))
        assert allclose(ff.atom_types['Ne'].parameters['sigma'],
                        2.794 * u.Angstrom)
        assert allclose(ff.atom_types['Ne'].parameters['n'],
                        11 * u.dimensionless)
        assert allclose(ff.atom_types['Ne'].parameters['m'],
                        6 * u.dimensionless)
        assert ff.atom_types['Ne'].charge.value == 0

        assert allclose(ff.atom_types['Ar'].parameters['epsilon'],
                        1.01519583 * u.Unit('kJ/mol'))
        assert allclose(ff.atom_types['Ar'].parameters['sigma'],
                        3.405 * u.Angstrom)
        assert allclose(ff.atom_types['Ar'].parameters['n'],
                        13 * u.dimensionless)
        assert allclose(ff.atom_types['Ar'].parameters['m'],
                        6 * u.dimensionless)
        assert ff.atom_types['Ar'].charge.value == 0

        assert allclose(ff.atom_types['Kr'].parameters['epsilon'],
                        1.46417678 * u.Unit('kJ/mol'))
        assert allclose(ff.atom_types['Kr'].parameters['sigma'],
                        3.645 * u.Angstrom)
        assert allclose(ff.atom_types['Kr'].parameters['n'],
                        14 * u.dimensionless)
        assert allclose(ff.atom_types['Kr'].parameters['m'],
                        6 * u.dimensionless)
        assert ff.atom_types['Kr'].charge.value == 0

        assert allclose(ff.atom_types['Xe'].parameters['epsilon'],
                        2.02706587 * u.Unit('kJ/mol'))
        assert allclose(ff.atom_types['Xe'].parameters['sigma'],
                        3.964 * u.Angstrom)
        assert allclose(ff.atom_types['Xe'].parameters['n'],
                        14 * u.dimensionless)
        assert allclose(ff.atom_types['Xe'].parameters['m'],
                        6 * u.dimensionless)
        assert ff.atom_types['Xe'].charge.value == 0
Ejemplo n.º 6
0
def convert_opls_to_ryckaert(opls_connection_type):
    """Convert an OPLS dihedral to Ryckaert-Bellemans dihedral.

    Equations taken/modified from:
        http://manual.gromacs.org/documentation/2019/
        reference-manual/functions/bonded-interactions.html

    NOTE: the conventions defining the dihedral angle are different
    for OPLS and RB torsions. OPLS torsions are defined with
    phi_cis = 0 while RB torsions are defined as phi_trans = 0.
    """
    templates = PotentialTemplateLibrary()
    opls_torsion_potential = templates["OPLSTorsionPotential"]
    valid_connection_type = False
    if (opls_connection_type.independent_variables ==
            opls_torsion_potential.independent_variables):
        if (sympy.simplify(opls_connection_type.expression -
                           opls_torsion_potential.expression) == 0):
            valid_connection_type = True
    if not valid_connection_type:
        raise GMSOError("Cannot use convert_opls_to_ryckaert "
                        "function to convert a ConnectionType that is not an "
                        "OPLSTorsionPotential")

    f0 = opls_connection_type.parameters["k0"]
    f1 = opls_connection_type.parameters["k1"]
    f2 = opls_connection_type.parameters["k2"]
    f3 = opls_connection_type.parameters["k3"]
    f4 = opls_connection_type.parameters["k4"]

    converted_params = {
        "c0": (f2 + 0.5 * (f0 + f1 + f3)),
        "c1": (0.5 * (-f1 + 3.0 * f3)),
        "c2": (-f2 + 4.0 * f4),
        "c3": (-2.0 * f3),
        "c4": (-4.0 * f4),
        "c5": 0.0 * u.Unit("kJ/mol"),
    }
    ryckaert_bellemans_torsion_potential = templates[
        "RyckaertBellemansTorsionPotential"]
    name = ryckaert_bellemans_torsion_potential.name
    expression = ryckaert_bellemans_torsion_potential.expression
    variables = ryckaert_bellemans_torsion_potential.independent_variables

    ryckaert_connection_type = gmso.DihedralType(
        name=name,
        expression=expression,
        independent_variables=variables,
        parameters=converted_params,
    )

    return ryckaert_connection_type
Ejemplo n.º 7
0
def convert_opls_to_ryckaert(opls_connection_type):
    """Convert an OPLS dihedral to Ryckaert-Bellemans dihedral

    Equations taken/modified from:
        http://manual.gromacs.org/documentation/2019/
        reference-manual/functions/bonded-interactions.html

    NOTE: the conventions defining the dihedral angle are different
    for OPLS and RB torsions. OPLS torsions are defined with
    phi_cis = 0 while RB torsions are defined as phi_trans = 0.
    """
    templates = PotentialTemplateLibrary()
    opls_torsion_potential = templates['OPLSTorsionPotential']
    valid_connection_type = False
    if (opls_connection_type.independent_variables ==
            opls_torsion_potential.independent_variables):
        if sympy.simplify(opls_connection_type.expression -
                          opls_torsion_potential.expression) == 0:
            valid_connection_type = True
    if not valid_connection_type:
        raise GMSOError('Cannot use convert_opls_to_ryckaert '
                        'function to convert a ConnectionType that is not an '
                        'OPLSTorsionPotential')

    f0 = opls_connection_type.parameters['k0']
    f1 = opls_connection_type.parameters['k1']
    f2 = opls_connection_type.parameters['k2']
    f3 = opls_connection_type.parameters['k3']
    f4 = opls_connection_type.parameters['k4']

    converted_params = {
        'c0': (f2 + 0.5 * (f0 + f1 + f3)),
        'c1': (0.5 * (-f1 + 3. * f3)),
        'c2': (-f2 + 4. * f4),
        'c3': (-2. * f3),
        'c4': (-4. * f4),
        'c5': 0. * u.Unit('kJ/mol')
    }
    ryckaert_bellemans_torsion_potential = templates[
        'RyckaertBellemansTorsionPotential']
    name = ryckaert_bellemans_torsion_potential.name
    expression = ryckaert_bellemans_torsion_potential.expression
    variables = ryckaert_bellemans_torsion_potential.independent_variables

    ryckaert_connection_type = gmso.DihedralType(
        name=name,
        expression=expression,
        independent_variables=variables,
        parameters=converted_params)

    return ryckaert_connection_type
Ejemplo n.º 8
0
def _accepted_potentials():
    templates = PotentialTemplateLibrary()
    lennard_jones_potential = templates['LennardJonesPotential']
    harmonic_bond_potential = templates['HarmonicBondPotential']
    harmonic_angle_potential = templates['HarmonicAnglePotential']
    periodic_torsion_potential = templates['PeriodicTorsionPotential']
    rb_torsion_potential = templates['RyckaertBellemansTorsionPotential']
    accepted_potentials = [
        lennard_jones_potential,
        harmonic_bond_potential,
        harmonic_angle_potential,
        periodic_torsion_potential,
        rb_torsion_potential,
    ]
    return accepted_potentials
Ejemplo n.º 9
0
def _accepted_potentials():
    """List of accepted potentials that GROMACS can support."""
    templates = PotentialTemplateLibrary()
    lennard_jones_potential = templates["LennardJonesPotential"]
    harmonic_bond_potential = templates["HarmonicBondPotential"]
    harmonic_angle_potential = templates["HarmonicAnglePotential"]
    periodic_torsion_potential = templates["PeriodicTorsionPotential"]
    rb_torsion_potential = templates["RyckaertBellemansTorsionPotential"]
    accepted_potentials = [
        lennard_jones_potential,
        harmonic_bond_potential,
        harmonic_angle_potential,
        periodic_torsion_potential,
        rb_torsion_potential,
    ]
    return accepted_potentials
Ejemplo n.º 10
0
 def test_class_method(self):
     template = PotentialTemplateLibrary()["HarmonicBondPotential"]
     params = {"k": 1.0 * u.dimensionless, "r_eq": 1.0 * u.dimensionless}
     harmonic_potential_from_template = ParametricPotential.from_template(
         template, params)
     harmonic_potential = ParametricPotential(
         name="HarmonicBondPotential",
         expression="0.5 * k * (r-r_eq)**2",
         independent_variables={"r"},
         parameters=params,
     )
     assert harmonic_potential.name == harmonic_potential_from_template.name
     assert (harmonic_potential.expression ==
             harmonic_potential_from_template.expression)
     assert (harmonic_potential.independent_variables ==
             harmonic_potential_from_template.independent_variables)
Ejemplo n.º 11
0
    def test_ethane_periodic(self, typed_ethane):
        from gmso.lib.potential_templates import PotentialTemplateLibrary
        per_torsion = PotentialTemplateLibrary()["PeriodicTorsionPotential"]
        params = {
            "k": 10 * u.Unit("kJ / mol"),
            "phi_eq": 15 * u.Unit("degree"),
            "n": 3 * u.Unit("dimensionless")
        }
        periodic_dihedral_type = gmso.core.potential.Potential.from_template(
            per_torsion, params)
        for dihedral in typed_ethane.dihedrals:
            dihedral.connection_type = periodic_dihedral_type

        typed_ethane.update_connection_types()

        write_top(typed_ethane, 'system.top')
        struct = pmd.load_file('system.top')
        assert len(struct.dihedrals) == 9
Ejemplo n.º 12
0
 def templates(self):
     return PotentialTemplateLibrary()
Ejemplo n.º 13
0
import datetime

import networkx as nx
import sympy
import unyt as u

from gmso import __version__
from gmso.core.topology import Topology
from gmso.lib.potential_templates import PotentialTemplateLibrary
from gmso.utils.compatibility import check_compatibility
from gmso.utils.conversions import convert_ryckaert_to_opls
from gmso.exceptions import GMSOError

__all__ = ["write_mcf"]

potential_templates = PotentialTemplateLibrary()


def write_mcf(top, filename):
    """Generate a Cassandra MCF from a gmso.core.Topology object.

    The MCF file stores the topology information for a single
    species (i.e., compound) in the Cassandra Monte Carlo software
    (https://cassandra.nd.edu). The gmso.Topology object provided to
    this function should therefore be for a single molecule with the
    relevant forcefield parameters. One MCF file will be required
    for each unique species in the system.

    Parameters
    ----------
    top : gmso.core.Topology
Ejemplo n.º 14
0
def write_lammpsdata(topology, filename, atom_style="full"):
    """Output a LAMMPS data file.

    Outputs a LAMMPS data file in the 'full' atom style format.
    Assumes use of 'real' units.
    See http://lammps.sandia.gov/doc/atom_style.html for more information on atom styles.

    Parameters
    ----------
    Topology : `Topology`
        A Topology Object
    filename : str
        Path of the output file
    atom_style : str, optional, default='full'
        Defines the style of atoms to be saved in a LAMMPS data file.
        The following atom styles are currently supported: 'full', 'atomic', 'charge', 'molecular'
        see http://lammps.sandia.gov/doc/atom_style.html for more information on atom styles.

    Notes
    -----
    See http://lammps.sandia.gov/doc/2001/data_format.html for a full description of the LAMMPS data format.
    This is a work in progress, as only atoms, masses, and atom_type information can be written out.

    Some of this function has been adopted from `mdtraj`'s support of the LAMMPSTRJ trajectory format.
    See https://github.com/mdtraj/mdtraj/blob/master/mdtraj/formats/lammpstrj.py for details.

    """
    if atom_style not in ["atomic", "charge", "molecular", "full"]:
        raise ValueError(
            'Atom style "{}" is invalid or is not currently supported'.format(
                atom_style))

    # TODO: Support various unit styles

    box = topology.box

    with open(filename, "w") as data:
        data.write("{} written by topology at {}\n\n".format(
            topology.name if topology.name is not None else "",
            str(datetime.datetime.now()),
        ))
        data.write("{:d} atoms\n".format(topology.n_sites))
        if atom_style in ["full", "molecular"]:
            if topology.n_bonds != 0:
                data.write("{:d} bonds\n".format(topology.n_bonds))
            else:
                data.write("0 bonds\n")
            if topology.n_angles != 0:
                data.write("{:d} angles\n".format(topology.n_angles))
            else:
                data.write("0 angles\n")
            if topology.n_dihedrals != 0:
                data.write("{:d} dihedrals\n\n".format(topology.n_dihedrals))
            else:
                data.write("0 dihedrals\n\n")

        data.write("\n{:d} atom types\n".format(len(topology.atom_types)))
        data.write("{:d} bond types\n".format(len(topology.bond_types)))
        data.write("{:d} angle types\n".format(len(topology.angle_types)))
        data.write("{:d} dihedral types\n".format(len(
            topology.dihedral_types)))

        data.write("\n")

        # Box data
        if allclose_units(
                box.angles,
                u.unyt_array([90, 90, 90], "degree"),
                rtol=1e-5,
                atol=1e-8,
        ):
            warnings.warn("Orthorhombic box detected")
            box.lengths.convert_to_units(u.angstrom)
            for i, dim in enumerate(["x", "y", "z"]):
                data.write("{0:.6f} {1:.6f} {2}lo {2}hi\n".format(
                    0, box.lengths.value[i], dim))
        else:
            warnings.warn("Non-orthorhombic box detected")
            box.lengths.convert_to_units(u.angstrom)
            box.angles.convert_to_units(u.radian)
            vectors = box.get_vectors()
            a, b, c = box.lengths
            alpha, beta, gamma = box.angles

            lx = a
            xy = b * np.cos(gamma)
            xz = c * np.cos(beta)
            ly = np.sqrt(b**2 - xy**2)
            yz = (b * c * np.cos(alpha) - xy * xz) / ly
            lz = np.sqrt(c**2 - xz**2 - yz**2)

            xhi = vectors[0][0]
            yhi = vectors[1][1]
            zhi = vectors[2][2]
            xy = vectors[1][0]
            xz = vectors[2][0]
            yz = vectors[2][1]
            xlo = u.unyt_array(0, xy.units)
            ylo = u.unyt_array(0, xy.units)
            zlo = u.unyt_array(0, xy.units)

            xlo_bound = xlo + u.unyt_array(np.min([0.0, xy, xz, xy + xz]),
                                           xy.units)
            xhi_bound = xhi + u.unyt_array(np.max([0.0, xy, xz, xy + xz]),
                                           xy.units)
            ylo_bound = ylo + u.unyt_array(np.min([0.0, yz]), xy.units)
            yhi_bound = yhi + u.unyt_array(np.max([0.0, yz]), xy.units)
            zlo_bound = zlo
            zhi_bound = zhi

            data.write("{0:.6f} {1:.6f} xlo xhi\n".format(
                xlo_bound.value, xhi_bound.value))
            data.write("{0:.6f} {1:.6f} ylo yhi\n".format(
                ylo_bound.value, yhi_bound.value))
            data.write("{0:.6f} {1:.6f} zlo zhi\n".format(
                zlo_bound.value, zhi_bound.value))
            data.write("{0:.6f} {1:.6f} {2:.6f} xy xz yz\n".format(
                xy.value, xz.value, yz.value))

        # TODO: Get a dictionary of indices and atom types
        if topology.is_typed():
            # Write out mass data
            data.write("\nMasses\n\n")
            for atom_type in topology.atom_types:
                data.write("{:d}\t{:.6f}\t# {}\n".format(
                    topology.atom_types.index(atom_type) + 1,
                    atom_type.mass.in_units(u.g / u.mol).value,
                    atom_type.name,
                ))

            # TODO: Modified cross-interactions
            # Pair coefficients
            data.write("\nPair Coeffs # lj\n\n")
            for idx, param in enumerate(topology.atom_types):
                data.write("{}\t{:.5f}\t{:.5f}\n".format(
                    idx + 1,
                    param.parameters["epsilon"].in_units(
                        u.Unit("kcal/mol")).value,
                    param.parameters["sigma"].in_units(u.angstrom).value,
                ))

            if topology.bonds:
                data.write("\nBond Coeffs\n\n")
                for idx, bond_type in enumerate(topology.bond_types):
                    data.write("{}\t{:.5f}\t{:.5f}\n".format(
                        idx + 1,
                        bond_type.parameters["k"].in_units(
                            u.Unit("kcal/mol/angstrom**2")).value / 2,
                        bond_type.parameters["r_eq"].in_units(
                            u.Unit("angstrom")).value,
                    ))

            if topology.angles:
                data.write("\nAngle Coeffs\n\n")
                for idx, angle_type in enumerate(topology.angle_types):
                    data.write("{}\t{:.5f}\t{:.5f}\n".format(
                        idx + 1,
                        angle_type.parameters["k"].in_units(
                            u.Unit("kcal/mol/radian**2")).value / 2,
                        angle_type.parameters["theta_eq"].in_units(
                            u.Unit("degree")).value,
                    ))

            # TODO: Write out multiple dihedral styles
            if topology.dihedrals:
                data.write("\nDihedral Coeffs\n\n")
                for idx, dihedral_type in enumerate(topology.dihedral_types):
                    rbtorsion = PotentialTemplateLibrary(
                    )["RyckaertBellemansTorsionPotential"]
                    if (dihedral_type.expression == sympify(
                            rbtorsion.expression)
                            or dihedral_type.name == rbtorsion.name):
                        dihedral_type = convert_ryckaert_to_opls(dihedral_type)
                    data.write("{}\t{:.5f}\t{:5f}\t{:5f}\t{:.5f}\n".format(
                        idx + 1,
                        dihedral_type.parameters["k1"].in_units(
                            u.Unit("kcal/mol")).value,
                        dihedral_type.parameters["k2"].in_units(
                            u.Unit("kcal/mol")).value,
                        dihedral_type.parameters["k3"].in_units(
                            u.Unit("kcal/mol")).value,
                        dihedral_type.parameters["k4"].in_units(
                            u.Unit("kcal/mol")).value,
                    ))

        # Atom data
        data.write("\nAtoms\n\n")
        if atom_style == "atomic":
            atom_line = "{index:d}\t{type_index:d}\t{x:.6f}\t{y:.6f}\t{z:.6f}\n"
        elif atom_style == "charge":
            atom_line = "{index:d}\t{type_index:d}\t{charge:.6f}\t{x:.6f}\t{y:.6f}\t{z:.6f}\n"
        elif atom_style == "molecular":
            atom_line = "{index:d}\t{zero:d}\t{type_index:d}\t{x:.6f}\t{y:.6f}\t{z:.6f}\n"
        elif atom_style == "full":
            atom_line = "{index:d}\t{zero:d}\t{type_index:d}\t{charge:.6f}\t{x:.6f}\t{y:.6f}\t{z:.6f}\n"

        for i, site in enumerate(topology.sites):
            data.write(
                atom_line.format(
                    index=topology.sites.index(site) + 1,
                    type_index=topology.atom_types.index(site.atom_type) + 1,
                    zero=0,
                    charge=site.charge.to(u.elementary_charge).value,
                    x=site.position[0].in_units(u.angstrom).value,
                    y=site.position[1].in_units(u.angstrom).value,
                    z=site.position[2].in_units(u.angstrom).value,
                ))

        if topology.bonds:
            data.write("\nBonds\n\n")
            for i, bond in enumerate(topology.bonds):
                data.write("{:d}\t{:d}\t{:d}\t{:d}\n".format(
                    i + 1,
                    topology.bond_types.index(bond.connection_type) + 1,
                    topology.sites.index(bond.connection_members[0]) + 1,
                    topology.sites.index(bond.connection_members[1]) + 1,
                ))

        if topology.angles:
            data.write("\nAngles\n\n")
            for i, angle in enumerate(topology.angles):
                data.write("{:d}\t{:d}\t{:d}\t{:d}\t{:d}\n".format(
                    i + 1,
                    topology.angle_types.index(angle.connection_type) + 1,
                    topology.sites.index(angle.connection_members[0]) + 1,
                    topology.sites.index(angle.connection_members[1]) + 1,
                    topology.sites.index(angle.connection_members[2]) + 1,
                ))

        if topology.dihedrals:
            data.write("\nDihedrals\n\n")
            for i, dihedral in enumerate(topology.dihedrals):
                data.write("{:d}\t{:d}\t{:d}\t{:d}\t{:d}\t{:d}\n".format(
                    i + 1,
                    topology.dihedral_types.index(dihedral.connection_type) +
                    1,
                    topology.sites.index(dihedral.connection_members[0]) + 1,
                    topology.sites.index(dihedral.connection_members[1]) + 1,
                    topology.sites.index(dihedral.connection_members[2]) + 1,
                    topology.sites.index(dihedral.connection_members[3]) + 1,
                ))
Ejemplo n.º 15
0
    def test_noble_mie_xml(self):
        ff = ForceField(get_path("noble_mie.xml"))
        templates = PotentialTemplateLibrary()
        ref_expr = templates["MiePotential"].expression

        assert len(ff.atom_types) == 4
        assert len(ff.bond_types) == 0
        assert len(ff.angle_types) == 0
        assert len(ff.dihedral_types) == 0

        for (name, atom_type) in ff.atom_types.items():
            assert sympy.simplify(atom_type.expression - ref_expr) == 0

        assert_allclose_units(
            ff.atom_types["Ne"].parameters["epsilon"],
            0.26855713 * u.Unit("kJ/mol"),
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ne"].parameters["sigma"],
            2.794 * u.Angstrom,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ne"].parameters["n"],
            11 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ne"].parameters["m"],
            6 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert ff.atom_types["Ne"].charge.value == 0

        assert_allclose_units(
            ff.atom_types["Ar"].parameters["epsilon"],
            1.01519583 * u.Unit("kJ/mol"),
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ar"].parameters["sigma"],
            3.405 * u.Angstrom,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ar"].parameters["n"],
            13 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Ar"].parameters["m"],
            6 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert ff.atom_types["Ar"].charge.value == 0

        assert_allclose_units(
            ff.atom_types["Kr"].parameters["epsilon"],
            1.46417678 * u.Unit("kJ/mol"),
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Kr"].parameters["sigma"],
            3.645 * u.Angstrom,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Kr"].parameters["n"],
            14 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Kr"].parameters["m"],
            6 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert ff.atom_types["Kr"].charge.value == 0

        assert_allclose_units(
            ff.atom_types["Xe"].parameters["epsilon"],
            2.02706587 * u.Unit("kJ/mol"),
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Xe"].parameters["sigma"],
            3.964 * u.Angstrom,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Xe"].parameters["n"],
            14 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert_allclose_units(
            ff.atom_types["Xe"].parameters["m"],
            6 * u.dimensionless,
            rtol=1e-5,
            atol=1e-8,
        )
        assert ff.atom_types["Xe"].charge.value == 0
Ejemplo n.º 16
0
 def test_singleton_behavior(self, templates):
     assert id(templates) == id(PotentialTemplateLibrary())
     assert id(PotentialTemplateLibrary()) == id(PotentialTemplateLibrary())