Exemple #1
0
def smirnoff_force_field() -> OFFForceField:
    from simtk import unit

    off_force_field = OFFForceField(
        '<SMIRNOFF version="0.3" aromaticity_model="OEAroModel_MDL"></SMIRNOFF>'
    )

    vdw_handler = vdWHandler(**{"version": "0.3"})
    vdw_handler.add_parameter(
        parameter_kwargs={
            "smirks": "[#6:1]",
            "epsilon": 1.0 * unit.kilojoules_per_mole,
            "sigma": 1.0 * unit.angstrom,
        })
    off_force_field.register_parameter_handler(vdw_handler)

    charge_handler = ChargeIncrementModelHandler(**{"version": "0.3"})
    charge_handler.add_parameter(
        parameter_kwargs={
            "smirks": "[#6:1]-[#6:2]",
            "charge_increment1": 1.0 * unit.elementary_charge,
            "charge_increment2": -1.0 * unit.elementary_charge,
        })
    off_force_field.register_parameter_handler(charge_handler)

    return off_force_field
def hydrogen_chloride_force_field(library_charge: bool,
                                  charge_increment: bool) -> ForceField:
    """Returns a SMIRNOFF force field which is able to parameterize hydrogen chloride."""

    # Create the FF
    force_field = ForceField()

    # Add a Vdw handler.
    vdw_handler = vdWHandler(version=0.3)
    vdw_handler.method = "cutoff"
    vdw_handler.cutoff = 6.0 * simtk_unit.angstrom
    vdw_handler.scale14 = 1.0
    vdw_handler.add_parameter({
        "smirks": "[#1:1]",
        "epsilon": 0.0 * simtk_unit.kilojoules_per_mole,
        "sigma": 1.0 * simtk_unit.angstrom,
    })
    vdw_handler.add_parameter({
        "smirks": "[#17:1]",
        "epsilon": 2.0 * simtk_unit.kilojoules_per_mole,
        "sigma": 2.0 * simtk_unit.angstrom,
    })
    force_field.register_parameter_handler(vdw_handler)

    # Add an electrostatic, a library charge and a charge increment handler.
    electrostatics_handler = ElectrostaticsHandler(version=0.3)
    electrostatics_handler.cutoff = 6.0 * simtk_unit.angstrom
    electrostatics_handler.method = "PME"
    force_field.register_parameter_handler(electrostatics_handler)

    if library_charge:

        library_charge_handler = LibraryChargeHandler(version=0.3)
        library_charge_handler.add_parameter(
            parameter_kwargs={
                "smirks": "[#1:1]",
                "charge1": 1.0 * simtk_unit.elementary_charge,
            })
        library_charge_handler.add_parameter(
            parameter_kwargs={
                "smirks": "[#17:1]",
                "charge1": -1.0 * simtk_unit.elementary_charge,
            })
        force_field.register_parameter_handler(library_charge_handler)

    if charge_increment:

        charge_increment_handler = ChargeIncrementModelHandler(version=0.3)
        charge_increment_handler.add_parameter(
            parameter_kwargs={
                "smirks": "[#1:1]-[#17:2]",
                "charge_increment1": -1.0 * simtk_unit.elementary_charge,
                "charge_increment2": 1.0 * simtk_unit.elementary_charge,
            })
        force_field.register_parameter_handler(charge_increment_handler)

    return force_field
Exemple #3
0
def system_subset(
    parameter_key: ParameterGradientKey,
    force_field: "ForceField",
    topology: "Topology",
    scale_amount: Optional[float] = None,
) -> Tuple["openmm.System", "simtk_unit.Quantity"]:
    """Produces an OpenMM system containing the minimum number of forces while
    still containing a specified force field parameter, and those other parameters
    which may interact with it (e.g. in the case of vdW parameters).

    The value of the parameter of interest may optionally be perturbed by an amount
    specified by ``scale_amount``.

    Parameters
    ----------
    parameter_key
        The parameter of interest.
    force_field
        The force field to create the system from (and optionally perturb).
    topology
        The topology of the system to apply the force field to.
    scale_amount: float, optional
        The optional amount to perturb the ``parameter`` by such that
        ``parameter = (1.0 + scale_amount) * parameter``.

    Returns
    -------
        The created system as well as the value of the specified ``parameter``.
    """

    # As this method deals mainly with the toolkit, we stick to
    # simtk units here.
    from openff.toolkit.typing.engines.smirnoff import ForceField

    # Create the force field subset.
    force_field_subset = ForceField()

    handlers_to_register = {parameter_key.tag}

    if parameter_key.tag in {"ChargeIncrementModel", "LibraryCharges"}:
        # Make sure to retain all of the electrostatic handlers when dealing with
        # charges as the applied charges will depend on which charges have been applied
        # by previous handlers.
        handlers_to_register.update(
            {"Electrostatics", "ChargeIncrementModel", "LibraryCharges"})

    registered_handlers = force_field.registered_parameter_handlers

    for handler_to_register in handlers_to_register:

        if handler_to_register not in registered_handlers:
            continue

        force_field_subset.register_parameter_handler(
            copy.deepcopy(
                force_field.get_parameter_handler(handler_to_register)))

    handler = force_field_subset.get_parameter_handler(parameter_key.tag)

    parameter = handler.parameters[parameter_key.smirks]
    parameter_value = getattr(parameter, parameter_key.attribute)

    # Optionally perturb the parameter of interest.
    if scale_amount is not None:

        if numpy.isclose(parameter_value.value_in_unit(parameter_value.unit),
                         0.0):
            # Careful thought needs to be given to this. Consider cases such as
            # epsilon or sigma where negative values are not allowed.
            parameter_value = (scale_amount if scale_amount > 0.0 else
                               0.0) * parameter_value.unit
        else:
            parameter_value *= 1.0 + scale_amount

    setattr(parameter, parameter_key.attribute, parameter_value)

    # Create the parameterized sub-system.
    system = force_field_subset.create_openmm_system(topology)
    return system, parameter_value