# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _openmm
else:
    import _openmm

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


class ios_base(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr
    erase_event = _openmm.ios_base_erase_event
    imbue_event = _openmm.ios_base_imbue_event
    copyfmt_event = _openmm.ios_base_copyfmt_event

    def register_callback(self, __fn, __index):
        return _openmm.ios_base_register_callback(self, __fn, __index)

    def flags(self, *args):
        return _openmm.ios_base_flags(self, *args)

    def setf(self, *args):
        return _openmm.ios_base_setf(self, *args)

    def unsetf(self, __mask):
        return _openmm.ios_base_unsetf(self, __mask)

    def precision(self, *args):
        return _openmm.ios_base_precision(self, *args)

    def width(self, *args):
        return _openmm.ios_base_width(self, *args)

    @staticmethod
    def sync_with_stdio(__sync=True):
        return _openmm.ios_base_sync_with_stdio(__sync)

    def imbue(self, __loc):
        return _openmm.ios_base_imbue(self, __loc)

    def getloc(self):
        return _openmm.ios_base_getloc(self)

    @staticmethod
    def xalloc():
        return _openmm.ios_base_xalloc()

    def iword(self, __ix):
        return _openmm.ios_base_iword(self, __ix)

    def pword(self, __ix):
        return _openmm.ios_base_pword(self, __ix)
    __swig_destroy__ = _openmm.delete_ios_base

# Register ios_base in _openmm:
_openmm.ios_base_swigregister(ios_base)
cvar = _openmm.cvar
ios_base.boolalpha = _openmm.cvar.ios_base_boolalpha
ios_base.dec = _openmm.cvar.ios_base_dec
ios_base.fixed = _openmm.cvar.ios_base_fixed
ios_base.hex = _openmm.cvar.ios_base_hex
ios_base.internal = _openmm.cvar.ios_base_internal
ios_base.left = _openmm.cvar.ios_base_left
ios_base.oct = _openmm.cvar.ios_base_oct
ios_base.right = _openmm.cvar.ios_base_right
ios_base.scientific = _openmm.cvar.ios_base_scientific
ios_base.showbase = _openmm.cvar.ios_base_showbase
ios_base.showpoint = _openmm.cvar.ios_base_showpoint
ios_base.showpos = _openmm.cvar.ios_base_showpos
ios_base.skipws = _openmm.cvar.ios_base_skipws
ios_base.unitbuf = _openmm.cvar.ios_base_unitbuf
ios_base.uppercase = _openmm.cvar.ios_base_uppercase
ios_base.adjustfield = _openmm.cvar.ios_base_adjustfield
ios_base.basefield = _openmm.cvar.ios_base_basefield
ios_base.floatfield = _openmm.cvar.ios_base_floatfield
ios_base.badbit = _openmm.cvar.ios_base_badbit
ios_base.eofbit = _openmm.cvar.ios_base_eofbit
ios_base.failbit = _openmm.cvar.ios_base_failbit
ios_base.goodbit = _openmm.cvar.ios_base_goodbit
ios_base.app = _openmm.cvar.ios_base_app
ios_base.ate = _openmm.cvar.ios_base_ate
ios_base.binary = _openmm.cvar.ios_base_binary
ios_base.ios_base_in = _openmm.cvar.ios_base_ios_base_in
ios_base.out = _openmm.cvar.ios_base_out
ios_base.trunc = _openmm.cvar.ios_base_trunc
ios_base.beg = _openmm.cvar.ios_base_beg
ios_base.cur = _openmm.cvar.ios_base_cur
ios_base.end = _openmm.cvar.ios_base_end

def ios_base_sync_with_stdio(__sync=True):
    return _openmm.ios_base_sync_with_stdio(__sync)

def ios_base_xalloc():
    return _openmm.ios_base_xalloc()

class ios(ios_base):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def rdstate(self):
        return _openmm.ios_rdstate(self)

    def clear(self, *args):
        return _openmm.ios_clear(self, *args)

    def setstate(self, __state):
        return _openmm.ios_setstate(self, __state)

    def good(self):
        return _openmm.ios_good(self)

    def eof(self):
        return _openmm.ios_eof(self)

    def fail(self):
        return _openmm.ios_fail(self)

    def bad(self):
        return _openmm.ios_bad(self)

    def exceptions(self, *args):
        return _openmm.ios_exceptions(self, *args)

    def __init__(self, __sb):
        _openmm.ios_swiginit(self, _openmm.new_ios(__sb))
    __swig_destroy__ = _openmm.delete_ios

    def tie(self, *args):
        return _openmm.ios_tie(self, *args)

    def rdbuf(self, *args):
        return _openmm.ios_rdbuf(self, *args)

    def copyfmt(self, __rhs):
        return _openmm.ios_copyfmt(self, __rhs)

    def fill(self, *args):
        return _openmm.ios_fill(self, *args)

    def imbue(self, __loc):
        return _openmm.ios_imbue(self, __loc)

    def narrow(self, __c, __dfault):
        return _openmm.ios_narrow(self, __c, __dfault)

    def widen(self, __c):
        return _openmm.ios_widen(self, __c)

# Register ios in _openmm:
_openmm.ios_swigregister(ios)

class ostream(ios):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, __sb):
        _openmm.ostream_swiginit(self, _openmm.new_ostream(__sb))
    __swig_destroy__ = _openmm.delete_ostream

    def __lshift__(self, *args):
        return _openmm.ostream___lshift__(self, *args)

    def put(self, __c):
        return _openmm.ostream_put(self, __c)

    def write(self, __s, __n):
        return _openmm.ostream_write(self, __s, __n)

    def flush(self):
        return _openmm.ostream_flush(self)

    def tellp(self):
        return _openmm.ostream_tellp(self)

    def seekp(self, *args):
        return _openmm.ostream_seekp(self, *args)

# Register ostream in _openmm:
_openmm.ostream_swigregister(ostream)
cin = cvar.cin
cout = cvar.cout
cerr = cvar.cerr
clog = cvar.clog

class istream(ios):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, __sb):
        _openmm.istream_swiginit(self, _openmm.new_istream(__sb))
    __swig_destroy__ = _openmm.delete_istream

    def __rshift__(self, *args):
        return _openmm.istream___rshift__(self, *args)

    def gcount(self):
        return _openmm.istream_gcount(self)

    def get(self, *args):
        return _openmm.istream_get(self, *args)

    def getline(self, *args):
        return _openmm.istream_getline(self, *args)

    def ignore(self, *args):
        return _openmm.istream_ignore(self, *args)

    def peek(self):
        return _openmm.istream_peek(self)

    def read(self, __s, __n):
        return _openmm.istream_read(self, __s, __n)

    def readsome(self, __s, __n):
        return _openmm.istream_readsome(self, __s, __n)

    def putback(self, __c):
        return _openmm.istream_putback(self, __c)

    def unget(self):
        return _openmm.istream_unget(self)

    def sync(self):
        return _openmm.istream_sync(self)

    def tellg(self):
        return _openmm.istream_tellg(self)

    def seekg(self, *args):
        return _openmm.istream_seekg(self, *args)

# Register istream in _openmm:
_openmm.istream_swigregister(istream)

class iostream(istream, ostream):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, __sb):
        _openmm.iostream_swiginit(self, _openmm.new_iostream(__sb))
    __swig_destroy__ = _openmm.delete_iostream

# Register iostream in _openmm:
_openmm.iostream_swigregister(iostream)

endl_cb_ptr = _openmm.endl_cb_ptr
endl = _openmm.endl
ends_cb_ptr = _openmm.ends_cb_ptr
ends = _openmm.ends
flush_cb_ptr = _openmm.flush_cb_ptr
flush = _openmm.flush
class SwigPyIterator(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_SwigPyIterator

    def value(self):
        return _openmm.SwigPyIterator_value(self)

    def incr(self, n=1):
        return _openmm.SwigPyIterator_incr(self, n)

    def decr(self, n=1):
        return _openmm.SwigPyIterator_decr(self, n)

    def distance(self, x):
        return _openmm.SwigPyIterator_distance(self, x)

    def equal(self, x):
        return _openmm.SwigPyIterator_equal(self, x)

    def copy(self):
        return _openmm.SwigPyIterator_copy(self)

    def next(self):
        return _openmm.SwigPyIterator_next(self)

    def __next__(self):
        return _openmm.SwigPyIterator___next__(self)

    def previous(self):
        return _openmm.SwigPyIterator_previous(self)

    def advance(self, n):
        return _openmm.SwigPyIterator_advance(self, n)

    def __eq__(self, x):
        return _openmm.SwigPyIterator___eq__(self, x)

    def __ne__(self, x):
        return _openmm.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n):
        return _openmm.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n):
        return _openmm.SwigPyIterator___isub__(self, n)

    def __add__(self, n):
        return _openmm.SwigPyIterator___add__(self, n)

    def __sub__(self, *args):
        return _openmm.SwigPyIterator___sub__(self, *args)
    def __iter__(self):
        return self

# Register SwigPyIterator in _openmm:
_openmm.SwigPyIterator_swigregister(SwigPyIterator)

class pairii(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _openmm.pairii_swiginit(self, _openmm.new_pairii(*args))
    first = property(_openmm.pairii_first_get, _openmm.pairii_first_set)
    second = property(_openmm.pairii_second_get, _openmm.pairii_second_set)
    def __len__(self):
        return 2
    def __repr__(self):
        return str((self.first, self.second))
    def __getitem__(self, index): 
        if not (index % 2):
            return self.first
        else:
            return self.second
    def __setitem__(self, index, val):
        if not (index % 2):
            self.first = val
        else:
            self.second = val
    __swig_destroy__ = _openmm.delete_pairii

# Register pairii in _openmm:
_openmm.pairii_swigregister(pairii)

class vectord(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectord_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectord___nonzero__(self)

    def __bool__(self):
        return _openmm.vectord___bool__(self)

    def __len__(self):
        return _openmm.vectord___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectord___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectord___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectord___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectord___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectord___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectord___setitem__(self, *args)

    def pop(self):
        return _openmm.vectord_pop(self)

    def append(self, x):
        return _openmm.vectord_append(self, x)

    def empty(self):
        return _openmm.vectord_empty(self)

    def size(self):
        return _openmm.vectord_size(self)

    def swap(self, v):
        return _openmm.vectord_swap(self, v)

    def begin(self):
        return _openmm.vectord_begin(self)

    def end(self):
        return _openmm.vectord_end(self)

    def rbegin(self):
        return _openmm.vectord_rbegin(self)

    def rend(self):
        return _openmm.vectord_rend(self)

    def clear(self):
        return _openmm.vectord_clear(self)

    def get_allocator(self):
        return _openmm.vectord_get_allocator(self)

    def pop_back(self):
        return _openmm.vectord_pop_back(self)

    def erase(self, *args):
        return _openmm.vectord_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectord_swiginit(self, _openmm.new_vectord(*args))

    def push_back(self, x):
        return _openmm.vectord_push_back(self, x)

    def front(self):
        return _openmm.vectord_front(self)

    def back(self):
        return _openmm.vectord_back(self)

    def assign(self, n, x):
        return _openmm.vectord_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectord_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectord_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectord_reserve(self, n)

    def capacity(self):
        return _openmm.vectord_capacity(self)
    __swig_destroy__ = _openmm.delete_vectord

# Register vectord in _openmm:
_openmm.vectord_swigregister(vectord)

class vectorddd(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectorddd_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectorddd___nonzero__(self)

    def __bool__(self):
        return _openmm.vectorddd___bool__(self)

    def __len__(self):
        return _openmm.vectorddd___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectorddd___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectorddd___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectorddd___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectorddd___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectorddd___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectorddd___setitem__(self, *args)

    def pop(self):
        return _openmm.vectorddd_pop(self)

    def append(self, x):
        return _openmm.vectorddd_append(self, x)

    def empty(self):
        return _openmm.vectorddd_empty(self)

    def size(self):
        return _openmm.vectorddd_size(self)

    def swap(self, v):
        return _openmm.vectorddd_swap(self, v)

    def begin(self):
        return _openmm.vectorddd_begin(self)

    def end(self):
        return _openmm.vectorddd_end(self)

    def rbegin(self):
        return _openmm.vectorddd_rbegin(self)

    def rend(self):
        return _openmm.vectorddd_rend(self)

    def clear(self):
        return _openmm.vectorddd_clear(self)

    def get_allocator(self):
        return _openmm.vectorddd_get_allocator(self)

    def pop_back(self):
        return _openmm.vectorddd_pop_back(self)

    def erase(self, *args):
        return _openmm.vectorddd_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectorddd_swiginit(self, _openmm.new_vectorddd(*args))

    def push_back(self, x):
        return _openmm.vectorddd_push_back(self, x)

    def front(self):
        return _openmm.vectorddd_front(self)

    def back(self):
        return _openmm.vectorddd_back(self)

    def assign(self, n, x):
        return _openmm.vectorddd_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectorddd_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectorddd_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectorddd_reserve(self, n)

    def capacity(self):
        return _openmm.vectorddd_capacity(self)
    __swig_destroy__ = _openmm.delete_vectorddd

# Register vectorddd in _openmm:
_openmm.vectorddd_swigregister(vectorddd)

class vectori(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectori_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectori___nonzero__(self)

    def __bool__(self):
        return _openmm.vectori___bool__(self)

    def __len__(self):
        return _openmm.vectori___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectori___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectori___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectori___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectori___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectori___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectori___setitem__(self, *args)

    def pop(self):
        return _openmm.vectori_pop(self)

    def append(self, x):
        return _openmm.vectori_append(self, x)

    def empty(self):
        return _openmm.vectori_empty(self)

    def size(self):
        return _openmm.vectori_size(self)

    def swap(self, v):
        return _openmm.vectori_swap(self, v)

    def begin(self):
        return _openmm.vectori_begin(self)

    def end(self):
        return _openmm.vectori_end(self)

    def rbegin(self):
        return _openmm.vectori_rbegin(self)

    def rend(self):
        return _openmm.vectori_rend(self)

    def clear(self):
        return _openmm.vectori_clear(self)

    def get_allocator(self):
        return _openmm.vectori_get_allocator(self)

    def pop_back(self):
        return _openmm.vectori_pop_back(self)

    def erase(self, *args):
        return _openmm.vectori_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectori_swiginit(self, _openmm.new_vectori(*args))

    def push_back(self, x):
        return _openmm.vectori_push_back(self, x)

    def front(self):
        return _openmm.vectori_front(self)

    def back(self):
        return _openmm.vectori_back(self)

    def assign(self, n, x):
        return _openmm.vectori_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectori_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectori_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectori_reserve(self, n)

    def capacity(self):
        return _openmm.vectori_capacity(self)
    __swig_destroy__ = _openmm.delete_vectori

# Register vectori in _openmm:
_openmm.vectori_swigregister(vectori)

class vectorii(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectorii_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectorii___nonzero__(self)

    def __bool__(self):
        return _openmm.vectorii___bool__(self)

    def __len__(self):
        return _openmm.vectorii___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectorii___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectorii___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectorii___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectorii___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectorii___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectorii___setitem__(self, *args)

    def pop(self):
        return _openmm.vectorii_pop(self)

    def append(self, x):
        return _openmm.vectorii_append(self, x)

    def empty(self):
        return _openmm.vectorii_empty(self)

    def size(self):
        return _openmm.vectorii_size(self)

    def swap(self, v):
        return _openmm.vectorii_swap(self, v)

    def begin(self):
        return _openmm.vectorii_begin(self)

    def end(self):
        return _openmm.vectorii_end(self)

    def rbegin(self):
        return _openmm.vectorii_rbegin(self)

    def rend(self):
        return _openmm.vectorii_rend(self)

    def clear(self):
        return _openmm.vectorii_clear(self)

    def get_allocator(self):
        return _openmm.vectorii_get_allocator(self)

    def pop_back(self):
        return _openmm.vectorii_pop_back(self)

    def erase(self, *args):
        return _openmm.vectorii_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectorii_swiginit(self, _openmm.new_vectorii(*args))

    def push_back(self, x):
        return _openmm.vectorii_push_back(self, x)

    def front(self):
        return _openmm.vectorii_front(self)

    def back(self):
        return _openmm.vectorii_back(self)

    def assign(self, n, x):
        return _openmm.vectorii_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectorii_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectorii_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectorii_reserve(self, n)

    def capacity(self):
        return _openmm.vectorii_capacity(self)
    __swig_destroy__ = _openmm.delete_vectorii

# Register vectorii in _openmm:
_openmm.vectorii_swigregister(vectorii)

class vectorpairii(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectorpairii_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectorpairii___nonzero__(self)

    def __bool__(self):
        return _openmm.vectorpairii___bool__(self)

    def __len__(self):
        return _openmm.vectorpairii___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectorpairii___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectorpairii___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectorpairii___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectorpairii___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectorpairii___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectorpairii___setitem__(self, *args)

    def pop(self):
        return _openmm.vectorpairii_pop(self)

    def append(self, x):
        return _openmm.vectorpairii_append(self, x)

    def empty(self):
        return _openmm.vectorpairii_empty(self)

    def size(self):
        return _openmm.vectorpairii_size(self)

    def swap(self, v):
        return _openmm.vectorpairii_swap(self, v)

    def begin(self):
        return _openmm.vectorpairii_begin(self)

    def end(self):
        return _openmm.vectorpairii_end(self)

    def rbegin(self):
        return _openmm.vectorpairii_rbegin(self)

    def rend(self):
        return _openmm.vectorpairii_rend(self)

    def clear(self):
        return _openmm.vectorpairii_clear(self)

    def get_allocator(self):
        return _openmm.vectorpairii_get_allocator(self)

    def pop_back(self):
        return _openmm.vectorpairii_pop_back(self)

    def erase(self, *args):
        return _openmm.vectorpairii_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectorpairii_swiginit(self, _openmm.new_vectorpairii(*args))

    def push_back(self, x):
        return _openmm.vectorpairii_push_back(self, x)

    def front(self):
        return _openmm.vectorpairii_front(self)

    def back(self):
        return _openmm.vectorpairii_back(self)

    def assign(self, n, x):
        return _openmm.vectorpairii_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectorpairii_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectorpairii_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectorpairii_reserve(self, n)

    def capacity(self):
        return _openmm.vectorpairii_capacity(self)
    __swig_destroy__ = _openmm.delete_vectorpairii

# Register vectorpairii in _openmm:
_openmm.vectorpairii_swigregister(vectorpairii)

class vectorstring(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.vectorstring_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.vectorstring___nonzero__(self)

    def __bool__(self):
        return _openmm.vectorstring___bool__(self)

    def __len__(self):
        return _openmm.vectorstring___len__(self)

    def __getslice__(self, i, j):
        return _openmm.vectorstring___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _openmm.vectorstring___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _openmm.vectorstring___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _openmm.vectorstring___delitem__(self, *args)

    def __getitem__(self, *args):
        return _openmm.vectorstring___getitem__(self, *args)

    def __setitem__(self, *args):
        return _openmm.vectorstring___setitem__(self, *args)

    def pop(self):
        return _openmm.vectorstring_pop(self)

    def append(self, x):
        return _openmm.vectorstring_append(self, x)

    def empty(self):
        return _openmm.vectorstring_empty(self)

    def size(self):
        return _openmm.vectorstring_size(self)

    def swap(self, v):
        return _openmm.vectorstring_swap(self, v)

    def begin(self):
        return _openmm.vectorstring_begin(self)

    def end(self):
        return _openmm.vectorstring_end(self)

    def rbegin(self):
        return _openmm.vectorstring_rbegin(self)

    def rend(self):
        return _openmm.vectorstring_rend(self)

    def clear(self):
        return _openmm.vectorstring_clear(self)

    def get_allocator(self):
        return _openmm.vectorstring_get_allocator(self)

    def pop_back(self):
        return _openmm.vectorstring_pop_back(self)

    def erase(self, *args):
        return _openmm.vectorstring_erase(self, *args)

    def __init__(self, *args):
        _openmm.vectorstring_swiginit(self, _openmm.new_vectorstring(*args))

    def push_back(self, x):
        return _openmm.vectorstring_push_back(self, x)

    def front(self):
        return _openmm.vectorstring_front(self)

    def back(self):
        return _openmm.vectorstring_back(self)

    def assign(self, n, x):
        return _openmm.vectorstring_assign(self, n, x)

    def resize(self, *args):
        return _openmm.vectorstring_resize(self, *args)

    def insert(self, *args):
        return _openmm.vectorstring_insert(self, *args)

    def reserve(self, n):
        return _openmm.vectorstring_reserve(self, n)

    def capacity(self):
        return _openmm.vectorstring_capacity(self)
    __swig_destroy__ = _openmm.delete_vectorstring

# Register vectorstring in _openmm:
_openmm.vectorstring_swigregister(vectorstring)

class mapstringstring(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.mapstringstring_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.mapstringstring___nonzero__(self)

    def __bool__(self):
        return _openmm.mapstringstring___bool__(self)

    def __len__(self):
        return _openmm.mapstringstring___len__(self)
    def __iter__(self):
        return self.key_iterator()
    def iterkeys(self):
        return self.key_iterator()
    def itervalues(self):
        return self.value_iterator()
    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _openmm.mapstringstring___getitem__(self, key)

    def __delitem__(self, key):
        return _openmm.mapstringstring___delitem__(self, key)

    def has_key(self, key):
        return _openmm.mapstringstring_has_key(self, key)

    def keys(self):
        return _openmm.mapstringstring_keys(self)

    def values(self):
        return _openmm.mapstringstring_values(self)

    def items(self):
        return _openmm.mapstringstring_items(self)

    def __contains__(self, key):
        return _openmm.mapstringstring___contains__(self, key)

    def key_iterator(self):
        return _openmm.mapstringstring_key_iterator(self)

    def value_iterator(self):
        return _openmm.mapstringstring_value_iterator(self)

    def __setitem__(self, *args):
        return _openmm.mapstringstring___setitem__(self, *args)

    def asdict(self):
        return _openmm.mapstringstring_asdict(self)

    def __init__(self, *args):
        _openmm.mapstringstring_swiginit(self, _openmm.new_mapstringstring(*args))

    def empty(self):
        return _openmm.mapstringstring_empty(self)

    def size(self):
        return _openmm.mapstringstring_size(self)

    def swap(self, v):
        return _openmm.mapstringstring_swap(self, v)

    def begin(self):
        return _openmm.mapstringstring_begin(self)

    def end(self):
        return _openmm.mapstringstring_end(self)

    def rbegin(self):
        return _openmm.mapstringstring_rbegin(self)

    def rend(self):
        return _openmm.mapstringstring_rend(self)

    def clear(self):
        return _openmm.mapstringstring_clear(self)

    def get_allocator(self):
        return _openmm.mapstringstring_get_allocator(self)

    def count(self, x):
        return _openmm.mapstringstring_count(self, x)

    def erase(self, *args):
        return _openmm.mapstringstring_erase(self, *args)

    def find(self, x):
        return _openmm.mapstringstring_find(self, x)

    def lower_bound(self, x):
        return _openmm.mapstringstring_lower_bound(self, x)

    def upper_bound(self, x):
        return _openmm.mapstringstring_upper_bound(self, x)
    __swig_destroy__ = _openmm.delete_mapstringstring

# Register mapstringstring in _openmm:
_openmm.mapstringstring_swigregister(mapstringstring)

class mapstringdouble(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.mapstringdouble_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.mapstringdouble___nonzero__(self)

    def __bool__(self):
        return _openmm.mapstringdouble___bool__(self)

    def __len__(self):
        return _openmm.mapstringdouble___len__(self)
    def __iter__(self):
        return self.key_iterator()
    def iterkeys(self):
        return self.key_iterator()
    def itervalues(self):
        return self.value_iterator()
    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _openmm.mapstringdouble___getitem__(self, key)

    def __delitem__(self, key):
        return _openmm.mapstringdouble___delitem__(self, key)

    def has_key(self, key):
        return _openmm.mapstringdouble_has_key(self, key)

    def keys(self):
        return _openmm.mapstringdouble_keys(self)

    def values(self):
        return _openmm.mapstringdouble_values(self)

    def items(self):
        return _openmm.mapstringdouble_items(self)

    def __contains__(self, key):
        return _openmm.mapstringdouble___contains__(self, key)

    def key_iterator(self):
        return _openmm.mapstringdouble_key_iterator(self)

    def value_iterator(self):
        return _openmm.mapstringdouble_value_iterator(self)

    def __setitem__(self, *args):
        return _openmm.mapstringdouble___setitem__(self, *args)

    def asdict(self):
        return _openmm.mapstringdouble_asdict(self)

    def __init__(self, *args):
        _openmm.mapstringdouble_swiginit(self, _openmm.new_mapstringdouble(*args))

    def empty(self):
        return _openmm.mapstringdouble_empty(self)

    def size(self):
        return _openmm.mapstringdouble_size(self)

    def swap(self, v):
        return _openmm.mapstringdouble_swap(self, v)

    def begin(self):
        return _openmm.mapstringdouble_begin(self)

    def end(self):
        return _openmm.mapstringdouble_end(self)

    def rbegin(self):
        return _openmm.mapstringdouble_rbegin(self)

    def rend(self):
        return _openmm.mapstringdouble_rend(self)

    def clear(self):
        return _openmm.mapstringdouble_clear(self)

    def get_allocator(self):
        return _openmm.mapstringdouble_get_allocator(self)

    def count(self, x):
        return _openmm.mapstringdouble_count(self, x)

    def erase(self, *args):
        return _openmm.mapstringdouble_erase(self, *args)

    def find(self, x):
        return _openmm.mapstringdouble_find(self, x)

    def lower_bound(self, x):
        return _openmm.mapstringdouble_lower_bound(self, x)

    def upper_bound(self, x):
        return _openmm.mapstringdouble_upper_bound(self, x)
    __swig_destroy__ = _openmm.delete_mapstringdouble

# Register mapstringdouble in _openmm:
_openmm.mapstringdouble_swigregister(mapstringdouble)

class mapii(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.mapii_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.mapii___nonzero__(self)

    def __bool__(self):
        return _openmm.mapii___bool__(self)

    def __len__(self):
        return _openmm.mapii___len__(self)
    def __iter__(self):
        return self.key_iterator()
    def iterkeys(self):
        return self.key_iterator()
    def itervalues(self):
        return self.value_iterator()
    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _openmm.mapii___getitem__(self, key)

    def __delitem__(self, key):
        return _openmm.mapii___delitem__(self, key)

    def has_key(self, key):
        return _openmm.mapii_has_key(self, key)

    def keys(self):
        return _openmm.mapii_keys(self)

    def values(self):
        return _openmm.mapii_values(self)

    def items(self):
        return _openmm.mapii_items(self)

    def __contains__(self, key):
        return _openmm.mapii___contains__(self, key)

    def key_iterator(self):
        return _openmm.mapii_key_iterator(self)

    def value_iterator(self):
        return _openmm.mapii_value_iterator(self)

    def __setitem__(self, *args):
        return _openmm.mapii___setitem__(self, *args)

    def asdict(self):
        return _openmm.mapii_asdict(self)

    def __init__(self, *args):
        _openmm.mapii_swiginit(self, _openmm.new_mapii(*args))

    def empty(self):
        return _openmm.mapii_empty(self)

    def size(self):
        return _openmm.mapii_size(self)

    def swap(self, v):
        return _openmm.mapii_swap(self, v)

    def begin(self):
        return _openmm.mapii_begin(self)

    def end(self):
        return _openmm.mapii_end(self)

    def rbegin(self):
        return _openmm.mapii_rbegin(self)

    def rend(self):
        return _openmm.mapii_rend(self)

    def clear(self):
        return _openmm.mapii_clear(self)

    def get_allocator(self):
        return _openmm.mapii_get_allocator(self)

    def count(self, x):
        return _openmm.mapii_count(self, x)

    def erase(self, *args):
        return _openmm.mapii_erase(self, *args)

    def find(self, x):
        return _openmm.mapii_find(self, x)

    def lower_bound(self, x):
        return _openmm.mapii_lower_bound(self, x)

    def upper_bound(self, x):
        return _openmm.mapii_upper_bound(self, x)
    __swig_destroy__ = _openmm.delete_mapii

# Register mapii in _openmm:
_openmm.mapii_swigregister(mapii)

class seti(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _openmm.seti_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _openmm.seti___nonzero__(self)

    def __bool__(self):
        return _openmm.seti___bool__(self)

    def __len__(self):
        return _openmm.seti___len__(self)

    def append(self, x):
        return _openmm.seti_append(self, x)

    def __contains__(self, x):
        return _openmm.seti___contains__(self, x)

    def __getitem__(self, i):
        return _openmm.seti___getitem__(self, i)

    def add(self, x):
        return _openmm.seti_add(self, x)

    def discard(self, x):
        return _openmm.seti_discard(self, x)

    def __init__(self, *args):
        _openmm.seti_swiginit(self, _openmm.new_seti(*args))

    def empty(self):
        return _openmm.seti_empty(self)

    def size(self):
        return _openmm.seti_size(self)

    def clear(self):
        return _openmm.seti_clear(self)

    def swap(self, v):
        return _openmm.seti_swap(self, v)

    def count(self, x):
        return _openmm.seti_count(self, x)

    def begin(self):
        return _openmm.seti_begin(self)

    def end(self):
        return _openmm.seti_end(self)

    def rbegin(self):
        return _openmm.seti_rbegin(self)

    def rend(self):
        return _openmm.seti_rend(self)

    def erase(self, *args):
        return _openmm.seti_erase(self, *args)

    def find(self, x):
        return _openmm.seti_find(self, x)

    def lower_bound(self, x):
        return _openmm.seti_lower_bound(self, x)

    def upper_bound(self, x):
        return _openmm.seti_upper_bound(self, x)

    def equal_range(self, x):
        return _openmm.seti_equal_range(self, x)

    def insert(self, __x):
        return _openmm.seti_insert(self, __x)
    __swig_destroy__ = _openmm.delete_seti

# Register seti in _openmm:
_openmm.seti_swigregister(seti)



try:
    import numpy
except ImportError:
    numpy = None

import copy
import sys
import math
import functools
import operator
RMIN_PER_SIGMA=math.pow(2, 1/6.0)
RVDW_PER_SIGMA=math.pow(2, 1/6.0)/2.0
if sys.version_info[0] == 2:
    _string_types = (basestring,)
else:
    _string_types = (bytes, str)

import simtk.unit as unit
from simtk.openmm.vec3 import Vec3



class Force(object):
    r"""
    Force objects apply forces to the particles in a System, or alter their behavior in other ways. This is an abstract class. Subclasses define particular forces.

    More specifically, a Force object can do any or all of the following:

     - Add a contribution to the force on each particle
     - Add a contribution to the potential energy of the System
     - Modify the positions and velocities of particles at the start of each time step
     - Define parameters which are stored in the Context and can be modified by the user
     - Change the values of parameters defined by other Force objects at the start of each time step

    Forces may be organized into "force groups". This is used for multiple time step integration, and allows subsets of the Forces in a System to be evaluated at different times. By default, all Forces are in group 0. Call setForceGroup() to change this. Some Force subclasses may provide additional methods to further split their computations into multiple groups. Be aware that particular Platforms may place restrictions on the use of force groups, such as requiring all nonbonded forces to be in the same group.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_Force

    def getForceGroup(self):
        r"""
        getForceGroup(self) -> int
        Get the force group this Force belongs to.
        """
        return _openmm.Force_getForceGroup(self)

    def setForceGroup(self, group):
        r"""
        setForceGroup(self, group)
        Set the force group this Force belongs to.

        Parameters
        ----------
        group : int
            the group index. Legal values are between 0 and 31 (inclusive).
        """
        return _openmm.Force_setForceGroup(self, group)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions. This method should be overridden for all Force subclasses, or a OpenMM::OpenMMException will be thrown

        Returns
        -------
        bool
            true if Force uses periodic boundaries or false if it does not
        """
        return _openmm.Force_usesPeriodicBoundaryConditions(self)

    def __getstate__(self):
        serializationString = XmlSerializer.serialize(self)
        return serializationString

    def __setstate__(self, serializationString):
        system = XmlSerializer.deserialize(serializationString)
        self.this = system.this

    def __deepcopy__(self, memo):
        return self.__copy__()


    def __copy__(self):
        r"""__copy__(self) -> Force"""
        return _openmm.Force___copy__(self)

# Register Force in _openmm:
_openmm.Force_swigregister(Force)
NmPerAngstrom = cvar.NmPerAngstrom
AngstromsPerNm = cvar.AngstromsPerNm
PsPerFs = cvar.PsPerFs
FsPerPs = cvar.FsPerPs
KJPerKcal = cvar.KJPerKcal
KcalPerKJ = cvar.KcalPerKJ
RadiansPerDegree = cvar.RadiansPerDegree
DegreesPerRadian = cvar.DegreesPerRadian
SigmaPerVdwRadius = cvar.SigmaPerVdwRadius
VdwRadiusPerSigma = cvar.VdwRadiusPerSigma

class AmoebaAngleForce(Force):
    r"""
    This class implements an interaction between triplets of particles that varies with the angle between them. The interaction is defined by a 6th order polynomial. Only the quadratic term is set per-angle. The coefficients of the higher order terms each have a single value that is set globally.

    To use it, create an AmoebaAngleForce object then call addAngle() once for each angle. After an angle has been added, you can modify its force field parameters by calling setAngleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumAngles(self):
        r"""
        getNumAngles(self) -> int
        Get the number of angle stretch terms in the potential function
        """
        return _openmm.AmoebaAngleForce_getNumAngles(self)

    def setAmoebaGlobalAngleCubic(self, cubicK):
        r"""
        setAmoebaGlobalAngleCubic(self, cubicK)
        Set the global cubic term

        Parameters
        ----------
        cubicK : double
            the cubic force constant for the angle
        """
        return _openmm.AmoebaAngleForce_setAmoebaGlobalAngleCubic(self, cubicK)

    def getAmoebaGlobalAngleCubic(self):
        r"""
        getAmoebaGlobalAngleCubic(self) -> double
        Get the global cubic term

        Returns
        -------
        double
            global cubicK term
        """
        val = _openmm.AmoebaAngleForce_getAmoebaGlobalAngleCubic(self)

        val=unit.Quantity(val, 1/unit.radian)


        return val


    def setAmoebaGlobalAngleQuartic(self, quarticK):
        r"""
        setAmoebaGlobalAngleQuartic(self, quarticK)
        Set the global quartic term

        Parameters
        ----------
        quarticK : double
            the quartic force constant for the angle
        """
        return _openmm.AmoebaAngleForce_setAmoebaGlobalAngleQuartic(self, quarticK)

    def getAmoebaGlobalAngleQuartic(self):
        r"""
        getAmoebaGlobalAngleQuartic(self) -> double
        Get the global quartic term

        Returns
        -------
        double
            global quartic term
        """
        val = _openmm.AmoebaAngleForce_getAmoebaGlobalAngleQuartic(self)

        val=unit.Quantity(val, 1/unit.radian**2)


        return val


    def setAmoebaGlobalAnglePentic(self, penticK):
        r"""
        setAmoebaGlobalAnglePentic(self, penticK)
        Set the global pentic term

        Parameters
        ----------
        penticK : double
            the pentic force constant for the angle
        """
        return _openmm.AmoebaAngleForce_setAmoebaGlobalAnglePentic(self, penticK)

    def getAmoebaGlobalAnglePentic(self):
        r"""
        getAmoebaGlobalAnglePentic(self) -> double
        Get the global pentic term

        Returns
        -------
        double
            global penticK term
        """
        val = _openmm.AmoebaAngleForce_getAmoebaGlobalAnglePentic(self)

        val=unit.Quantity(val, 1/unit.radian**3)


        return val


    def setAmoebaGlobalAngleSextic(self, sexticK):
        r"""
        setAmoebaGlobalAngleSextic(self, sexticK)
        Set the global sextic term

        Parameters
        ----------
        sexticK : double
            the sextic force constant for the angle
        """
        return _openmm.AmoebaAngleForce_setAmoebaGlobalAngleSextic(self, sexticK)

    def getAmoebaGlobalAngleSextic(self):
        r"""
        getAmoebaGlobalAngleSextic(self) -> double
        Get the global sextic term

        Returns
        -------
        double
            global sextic term
        """
        val = _openmm.AmoebaAngleForce_getAmoebaGlobalAngleSextic(self)

        val=unit.Quantity(val, 1/unit.radian**4)


        return val


    def addAngle(self, particle1, particle2, particle3, length, quadraticK):
        r"""
        addAngle(self, particle1, particle2, particle3, length, quadraticK) -> int
        Add an angle term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        length : double
            the equilibrium angle, measured in degrees
        quadraticK : double
            the quadratic force constant for the angle, measured in kJ/mol/radian^2

        Returns
        -------
        int
            the index of the angle that was added
        """

        try:
            length = args[3]
            if isinstance(args, tuple):
                args = list(args)
        except (NameError, UnboundLocalError):
            if unit.is_quantity(length):
                length = length.value_in_unit(unit.degree)
        else:
            if unit.is_quantity(length):
                args[3] = length.value_in_unit(unit.degree)


        return _openmm.AmoebaAngleForce_addAngle(self, particle1, particle2, particle3, length, quadraticK)


    def getAngleParameters(self, index):
        r"""
        getAngleParameters(self, index)
        Get the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        length : double
            the equilibrium angle, measured in degrees
        quadraticK : double
            the quadratic force constant for the angle, measured in kJ/mol/radian^2
        """
        val = _openmm.AmoebaAngleForce_getAngleParameters(self, index)

        val[3]=unit.Quantity(val[3], unit.degree)
        val[4]=unit.Quantity(val[4], unit.kilojoule_per_mole/(unit.radian*unit.radian))


        return val


    def setAngleParameters(self, index, particle1, particle2, particle3, length, quadraticK):
        r"""
        setAngleParameters(self, index, particle1, particle2, particle3, length, quadraticK)
        Set the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to set parameters
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        length : double
            the equilibrium angle, measured in degrees
        quadraticK : double
            the quadratic force constant for the angle, measured in kJ/mol/radian^2
        """

        try:
            length = args[4]
            if isinstance(args, tuple):
                args = list(args)
        except (NameError, UnboundLocalError):
            if unit.is_quantity(length):
                length = length.value_in_unit(unit.degree)
        else:
            if unit.is_quantity(length):
                args[4] = length.value_in_unit(unit.degree)


        return _openmm.AmoebaAngleForce_setAngleParameters(self, index, particle1, particle2, particle3, length, quadraticK)


    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-angle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-angle parameters. The set of particles involved in an angle cannot be changed, nor can new angles be added.
        """
        return _openmm.AmoebaAngleForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaAngleForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaAngleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaAngleForce
        __init__(self, other) -> AmoebaAngleForce
        Create an AmoebaAngleForce.
        """
        _openmm.AmoebaAngleForce_swiginit(self, _openmm.new_AmoebaAngleForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaAngleForce

# Register AmoebaAngleForce in _openmm:
_openmm.AmoebaAngleForce_swigregister(AmoebaAngleForce)

class AmoebaBondForce(Force):
    r"""
    This class implements an interaction between pairs of particles that varies with the distance between them. The interaction is defined by a 4th order polynomial. Only the quadratic term is set per-bond. The coefficients of the higher order terms each have a single value that is set globally.

    To use it, create an AmoebaBondForce object then call addBond() once for each bond. After a bond has been added, you can modify its force field parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumBonds(self):
        r"""
        getNumBonds(self) -> int
        Get the number of bond stretch terms in the potential function
        """
        return _openmm.AmoebaBondForce_getNumBonds(self)

    def setAmoebaGlobalBondCubic(self, cubicK):
        r"""
        setAmoebaGlobalBondCubic(self, cubicK)
        Set the global cubic term

        Parameters
        ----------
        cubicK : double
            the cubic force constant for the bond
        """
        return _openmm.AmoebaBondForce_setAmoebaGlobalBondCubic(self, cubicK)

    def getAmoebaGlobalBondCubic(self):
        r"""
        getAmoebaGlobalBondCubic(self) -> double
        Get the global cubic term

        Returns
        -------
        double
            global cubicK term
        """
        val = _openmm.AmoebaBondForce_getAmoebaGlobalBondCubic(self)

        val=unit.Quantity(val, 1/unit.nanometer)


        return val


    def setAmoebaGlobalBondQuartic(self, quarticK):
        r"""
        setAmoebaGlobalBondQuartic(self, quarticK)
        Set the global quartic term

        Parameters
        ----------
        quarticK : double
            the quartic force constant for the bond
        """
        return _openmm.AmoebaBondForce_setAmoebaGlobalBondQuartic(self, quarticK)

    def getAmoebaGlobalBondQuartic(self):
        r"""
        getAmoebaGlobalBondQuartic(self) -> double
        Get the global quartic term

        Returns
        -------
        double
            global quartic term
        """
        val = _openmm.AmoebaBondForce_getAmoebaGlobalBondQuartic(self)

        val=unit.Quantity(val, 1/unit.nanometer**2)


        return val


    def addBond(self, particle1, particle2, length, quadraticK):
        r"""
        addBond(self, particle1, particle2, length, quadraticK) -> int
        Add a bond term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        quadraticK : double
            the quadratic force constant for the bond

        Returns
        -------
        int
            the index of the bond that was added
        """
        return _openmm.AmoebaBondForce_addBond(self, particle1, particle2, length, quadraticK)

    def getBondParameters(self, index):
        r"""
        getBondParameters(self, index)
        Get the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        quadraticK : double
            the quadratic force constant for the bond
        """
        val = _openmm.AmoebaBondForce_getBondParameters(self, index)

        val[2]=unit.Quantity(val[2], unit.nanometer)
        val[3]=unit.Quantity(val[3], unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer))


        return val


    def setBondParameters(self, index, particle1, particle2, length, quadraticK):
        r"""
        setBondParameters(self, index, particle1, particle2, length, quadraticK)
        Set the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to set parameters
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        quadraticK : double
            the quadratic force constant for the bond
        """
        return _openmm.AmoebaBondForce_setBondParameters(self, index, particle1, particle2, length, quadraticK)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bond parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-bond parameters. The set of particles involved in a bond cannot be changed, nor can new bonds be added.
        """
        return _openmm.AmoebaBondForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaBondForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaBondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaBondForce
        __init__(self, other) -> AmoebaBondForce
        Create an AmoebaBondForce.
        """
        _openmm.AmoebaBondForce_swiginit(self, _openmm.new_AmoebaBondForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaBondForce

# Register AmoebaBondForce in _openmm:
_openmm.AmoebaBondForce_swigregister(AmoebaBondForce)

class AmoebaGeneralizedKirkwoodForce(Force):
    r"""
    This class implements an implicit solvation force using the generalized Kirkwood/Grycuk model. 

    To use this class, create an AmoebaGeneralizedKirkwoodForce object, then call addParticle() once for each particle in the System to define its parameters. The number of particles for which you define parameters must be equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles in the system.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getNumParticles(self)

    def addParticle(self, charge, radius, scalingFactor):
        r"""
        addParticle(self, charge, radius, scalingFactor) -> int
        Add the parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the atomic radius of the particle, measured in nm
        scalingFactor : double
            the scaling factor for the particle

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_addParticle(self, charge, radius, scalingFactor)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the force field parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the atomic radius of the particle, measured in nm
        scalingFactor : double
            the scaling factor for the particle
        """
        val = _openmm.AmoebaGeneralizedKirkwoodForce_getParticleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.elementary_charge)
        val[1]=unit.Quantity(val[1], unit.nanometer)


        return val


    def setParticleParameters(self, index, charge, radius, scalingFactor):
        r"""
        setParticleParameters(self, index, charge, radius, scalingFactor)
        Set the force field parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the atomic radius of the particle, measured in nm
        scalingFactor : double
            the scaling factor for the particle
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setParticleParameters(self, index, charge, radius, scalingFactor)

    def getSolventDielectric(self):
        r"""
        getSolventDielectric(self) -> double
        Get the dielectric constant for the solvent.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getSolventDielectric(self)

    def setSolventDielectric(self, dielectric):
        r"""
        setSolventDielectric(self, dielectric)
        Set the dielectric constant for the solvent.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setSolventDielectric(self, dielectric)

    def getSoluteDielectric(self):
        r"""
        getSoluteDielectric(self) -> double
        Get the dielectric constant for the solute.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getSoluteDielectric(self)

    def setSoluteDielectric(self, dielectric):
        r"""
        setSoluteDielectric(self, dielectric)
        Set the dielectric constant for the solute.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setSoluteDielectric(self, dielectric)

    def getIncludeCavityTerm(self):
        r"""
        getIncludeCavityTerm(self) -> int
        Get the flag signaling whether the cavity term should be included
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getIncludeCavityTerm(self)

    def setIncludeCavityTerm(self, includeCavityTerm):
        r"""
        setIncludeCavityTerm(self, includeCavityTerm)
        Set the flag signaling whether the cavity term should be included
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setIncludeCavityTerm(self, includeCavityTerm)

    def getProbeRadius(self):
        r"""
        getProbeRadius(self) -> double
        Get the probe radius (nm) used in SASA contribution
        """
        val = _openmm.AmoebaGeneralizedKirkwoodForce_getProbeRadius(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setProbeRadius(self, probeRadius):
        r"""
        setProbeRadius(self, probeRadius)
        Set the probe radius (nm) used in SASA contribution
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setProbeRadius(self, probeRadius)

    def getSurfaceAreaFactor(self):
        r"""
        getSurfaceAreaFactor(self) -> double
        Get the surface area factor kJ/(nm*nm) used in SASA contribution
        """
        val = _openmm.AmoebaGeneralizedKirkwoodForce_getSurfaceAreaFactor(self)

        val=unit.Quantity(val, unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer))


        return val


    def setSurfaceAreaFactor(self, surfaceAreaFactor):
        r"""
        setSurfaceAreaFactor(self, surfaceAreaFactor)
        Set the surface area factor kJ/(nm*nm) used in SASA contribution
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setSurfaceAreaFactor(self, surfaceAreaFactor)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-particle parameters. All other aspects of the Force (the probe radius, the surface area factor, etc.) are unaffected and can only be changed by reinitializing the Context.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaGeneralizedKirkwoodForce
        __init__(self, other) -> AmoebaGeneralizedKirkwoodForce
        This class implements an implicit solvation force using the generalized Kirkwood/Grycuk model. 

        To use this class, create an AmoebaGeneralizedKirkwoodForce object, then call addParticle() once for each particle in the System to define its parameters. The number of particles for which you define parameters must be equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
        """
        _openmm.AmoebaGeneralizedKirkwoodForce_swiginit(self, _openmm.new_AmoebaGeneralizedKirkwoodForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaGeneralizedKirkwoodForce

# Register AmoebaGeneralizedKirkwoodForce in _openmm:
_openmm.AmoebaGeneralizedKirkwoodForce_swigregister(AmoebaGeneralizedKirkwoodForce)

class AmoebaInPlaneAngleForce(Force):
    r"""
    This class implements an interaction at trigonal centers corresponding to the projected in-plane angle bend energy between four particles. The interaction is defined by a 6th order polynomial in the angle between them. Only the quadratic term is set per-angle. The coefficients of the higher order terms each have a single value that is set globally.

    To use it, create an AmoebaInPlaneAngleForce object then call addAngle() once for each angle. After an angle has been added, you can modify its force field parameters by calling setAngleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumAngles(self):
        r"""
        getNumAngles(self) -> int
        Get the number of in-plane angle terms in the potential function
        """
        return _openmm.AmoebaInPlaneAngleForce_getNumAngles(self)

    def setAmoebaGlobalInPlaneAngleCubic(self, cubicK):
        r"""
        setAmoebaGlobalInPlaneAngleCubic(self, cubicK)
        Set the global cubic term

        Parameters
        ----------
        cubicK : double
            the cubic force constant for the angle
        """
        return _openmm.AmoebaInPlaneAngleForce_setAmoebaGlobalInPlaneAngleCubic(self, cubicK)

    def getAmoebaGlobalInPlaneAngleCubic(self):
        r"""
        getAmoebaGlobalInPlaneAngleCubic(self) -> double
        Get the global cubic term

        Returns
        -------
        double
            global cubicK term
        """
        val = _openmm.AmoebaInPlaneAngleForce_getAmoebaGlobalInPlaneAngleCubic(self)

        val=unit.Quantity(val, 1/unit.radian)


        return val


    def setAmoebaGlobalInPlaneAngleQuartic(self, quarticK):
        r"""
        setAmoebaGlobalInPlaneAngleQuartic(self, quarticK)
        Set the global quartic term

        Parameters
        ----------
        quarticK : double
            the quartic force constant for the angle
        """
        return _openmm.AmoebaInPlaneAngleForce_setAmoebaGlobalInPlaneAngleQuartic(self, quarticK)

    def getAmoebaGlobalInPlaneAngleQuartic(self):
        r"""
        getAmoebaGlobalInPlaneAngleQuartic(self) -> double
        Get the global quartic term

        Returns
        -------
        double
            global quartic term
        """
        val = _openmm.AmoebaInPlaneAngleForce_getAmoebaGlobalInPlaneAngleQuartic(self)

        val=unit.Quantity(val, 1/unit.radian**2)


        return val


    def setAmoebaGlobalInPlaneAnglePentic(self, penticK):
        r"""
        setAmoebaGlobalInPlaneAnglePentic(self, penticK)
        Set the global pentic term

        Parameters
        ----------
        penticK : double
            the pentic force constant for the angle
        """
        return _openmm.AmoebaInPlaneAngleForce_setAmoebaGlobalInPlaneAnglePentic(self, penticK)

    def getAmoebaGlobalInPlaneAnglePentic(self):
        r"""
        getAmoebaGlobalInPlaneAnglePentic(self) -> double
        Get the global pentic term

        Returns
        -------
        double
            global penticK term
        """
        val = _openmm.AmoebaInPlaneAngleForce_getAmoebaGlobalInPlaneAnglePentic(self)

        val=unit.Quantity(val, 1/unit.radian**3)


        return val


    def setAmoebaGlobalInPlaneAngleSextic(self, sexticK):
        r"""
        setAmoebaGlobalInPlaneAngleSextic(self, sexticK)
        Set the global sextic term

        Parameters
        ----------
        sexticK : double
            the sextic force constant for the angle
        """
        return _openmm.AmoebaInPlaneAngleForce_setAmoebaGlobalInPlaneAngleSextic(self, sexticK)

    def getAmoebaGlobalInPlaneAngleSextic(self):
        r"""
        getAmoebaGlobalInPlaneAngleSextic(self) -> double
        Get the global sextic term

        Returns
        -------
        double
            global sextic term
        """
        val = _openmm.AmoebaInPlaneAngleForce_getAmoebaGlobalInPlaneAngleSextic(self)

        val=unit.Quantity(val, 1/unit.radian**4)


        return val


    def addAngle(self, particle1, particle2, particle3, particle4, length, quadraticK):
        r"""
        addAngle(self, particle1, particle2, particle3, particle4, length, quadraticK) -> int
        Add an angle term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        particle4 : int
            the index of the fourth particle connected by the angle
        length : double
            the equilibrium angle, measured in radians
        quadraticK : double
            the quadratic force constant for the angle measured in kJ/mol/radian^2

        Returns
        -------
        int
            the index of the angle that was added
        """
        return _openmm.AmoebaInPlaneAngleForce_addAngle(self, particle1, particle2, particle3, particle4, length, quadraticK)

    def getAngleParameters(self, index):
        r"""
        getAngleParameters(self, index)
        Get the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        particle4 : int
            the index of the fourth particle connected by the angle
        length : double
            the equilibrium angle, measured in radians
        quadraticK : double
            the quadratic force constant for the angle measured in kJ/mol/radian^2
        """
        val = _openmm.AmoebaInPlaneAngleForce_getAngleParameters(self, index)

        val[4]=unit.Quantity(val[4], unit.radian)
        val[5]=unit.Quantity(val[5], unit.kilojoule_per_mole/(unit.radian*unit.radian))


        return val


    def setAngleParameters(self, index, particle1, particle2, particle3, particle4, length, quadraticK):
        r"""
        setAngleParameters(self, index, particle1, particle2, particle3, particle4, length, quadraticK)
        Set the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to set parameters
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        particle4 : int
            the index of the fourth particle connected by the angle
        length : double
            the equilibrium angle, measured in radians
        quadraticK : double
            the quadratic force constant for the angle, measured in kJ/mol/radian^2
        """
        return _openmm.AmoebaInPlaneAngleForce_setAngleParameters(self, index, particle1, particle2, particle3, particle4, length, quadraticK)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-angle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-angle parameters. The set of particles involved in an angle cannot be changed, nor can new angles be added.
        """
        return _openmm.AmoebaInPlaneAngleForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaInPlaneAngleForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaInPlaneAngleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaInPlaneAngleForce
        __init__(self, other) -> AmoebaInPlaneAngleForce
        Create an AmoebaAngleForce.
        """
        _openmm.AmoebaInPlaneAngleForce_swiginit(self, _openmm.new_AmoebaInPlaneAngleForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaInPlaneAngleForce

# Register AmoebaInPlaneAngleForce in _openmm:
_openmm.AmoebaInPlaneAngleForce_swigregister(AmoebaInPlaneAngleForce)

class AmoebaMultipoleForce(Force):
    r"""
    This class implements the Amoeba multipole interaction.

    To use it, create an AmoebaMultipoleForce object then call addMultipole() once for each atom. After an entry has been added, you can modify its force field parameters by calling setMultipoleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.AmoebaMultipoleForce_NoCutoff
    
    PME = _openmm.AmoebaMultipoleForce_PME
    
    Mutual = _openmm.AmoebaMultipoleForce_Mutual
    
    Direct = _openmm.AmoebaMultipoleForce_Direct
    
    Extrapolated = _openmm.AmoebaMultipoleForce_Extrapolated
    
    ZThenX = _openmm.AmoebaMultipoleForce_ZThenX
    
    Bisector = _openmm.AmoebaMultipoleForce_Bisector
    
    ZBisect = _openmm.AmoebaMultipoleForce_ZBisect
    
    ThreeFold = _openmm.AmoebaMultipoleForce_ThreeFold
    
    ZOnly = _openmm.AmoebaMultipoleForce_ZOnly
    
    NoAxisType = _openmm.AmoebaMultipoleForce_NoAxisType
    
    LastAxisTypeIndex = _openmm.AmoebaMultipoleForce_LastAxisTypeIndex
    
    Covalent12 = _openmm.AmoebaMultipoleForce_Covalent12
    
    Covalent13 = _openmm.AmoebaMultipoleForce_Covalent13
    
    Covalent14 = _openmm.AmoebaMultipoleForce_Covalent14
    
    Covalent15 = _openmm.AmoebaMultipoleForce_Covalent15
    
    PolarizationCovalent11 = _openmm.AmoebaMultipoleForce_PolarizationCovalent11
    
    PolarizationCovalent12 = _openmm.AmoebaMultipoleForce_PolarizationCovalent12
    
    PolarizationCovalent13 = _openmm.AmoebaMultipoleForce_PolarizationCovalent13
    
    PolarizationCovalent14 = _openmm.AmoebaMultipoleForce_PolarizationCovalent14
    
    CovalentEnd = _openmm.AmoebaMultipoleForce_CovalentEnd
    

    def getNumMultipoles(self):
        r"""
        getNumMultipoles(self) -> int
        Get the number of particles in the potential function
        """
        return _openmm.AmoebaMultipoleForce_getNumMultipoles(self)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::AmoebaMultipoleForce::NonbondedMethod
        Get the method used for handling long-range nonbonded interactions.
        """
        return _openmm.AmoebaMultipoleForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long-range nonbonded interactions.
        """
        return _openmm.AmoebaMultipoleForce_setNonbondedMethod(self, method)

    def getPolarizationType(self):
        r"""
        getPolarizationType(self) -> OpenMM::AmoebaMultipoleForce::PolarizationType
        Get polarization type
        """
        return _openmm.AmoebaMultipoleForce_getPolarizationType(self)

    def setPolarizationType(self, type):
        r"""
        setPolarizationType(self, type)
        Set the polarization type
        """
        return _openmm.AmoebaMultipoleForce_setPolarizationType(self, type)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.AmoebaMultipoleForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.AmoebaMultipoleForce_setCutoffDistance(self, distance)

    def getPMEParameters(self):
        r"""
        getPMEParameters(self)
        Get the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.AmoebaMultipoleForce_getPMEParameters(self)

    def setPMEParameters(self, alpha, nx, ny, nz):
        r"""
        setPMEParameters(self, alpha, nx, ny, nz)
        Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Parameters
        ----------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.AmoebaMultipoleForce_setPMEParameters(self, alpha, nx, ny, nz)

    def getAEwald(self):
        r"""
        getAEwald(self) -> double
        Get the Ewald alpha parameter. If this is 0 (the default), a value is chosen automatically based on the Ewald error tolerance.

         @deprecated This method exists only for backward compatibility. Use getPMEParameters() instead.

        Returns
        -------
        double
            the Ewald alpha parameter
        """
        val = _openmm.AmoebaMultipoleForce_getAEwald(self)

        val=unit.Quantity(val, 1/unit.nanometer)


        return val


    def setAEwald(self, aewald):
        r"""
        setAEwald(self, aewald)
        Set the Ewald alpha parameter. If this is 0 (the default), a value is chosen automatically based on the Ewald error tolerance.

         @deprecated This method exists only for backward compatibility. Use setPMEParameters() instead.

        Parameters
        ----------
        aewald : double
            alpha parameter
        """
        return _openmm.AmoebaMultipoleForce_setAEwald(self, aewald)

    def getPmeBSplineOrder(self):
        r"""
        getPmeBSplineOrder(self) -> int
        Get the B-spline order to use for PME charge spreading

        Returns
        -------
        int
            the B-spline order
        """
        return _openmm.AmoebaMultipoleForce_getPmeBSplineOrder(self)

    def getPmeGridDimensions(self):
        r"""
        getPmeGridDimensions(self)
        Get the PME grid dimensions. If Ewald alpha is 0 (the default), this is ignored and grid dimensions are chosen automatically based on the Ewald error tolerance.

         @deprecated This method exists only for backward compatibility. Use getPMEParameters() instead.

        Returns
        -------
        void
            the PME grid dimensions
        """
        return _openmm.AmoebaMultipoleForce_getPmeGridDimensions(self)

    def setPmeGridDimensions(self, gridDimension):
        r"""
        setPmeGridDimensions(self, gridDimension)
        Set the PME grid dimensions. If Ewald alpha is 0 (the default), this is ignored and grid dimensions are chosen automatically based on the Ewald error tolerance.

         @deprecated This method exists only for backward compatibility. Use setPMEParameters() instead.

        Parameters
        ----------
        gridDimension : vector< int >
            the PME grid dimensions
        """
        return _openmm.AmoebaMultipoleForce_setPmeGridDimensions(self, gridDimension)

    def getPMEParametersInContext(self, context):
        r"""
        getPMEParametersInContext(self, context)
        Get the parameters being used for PME in a particular Context. Because some platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different from those specified with setPmeGridDimensions(), or the standard values calculated based on the Ewald error tolerance. See the manual for details.

        Parameters
        ----------
        context : Context
            the Context for which to get the parameters

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.AmoebaMultipoleForce_getPMEParametersInContext(self, context)

    def addMultipole(self, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity):
        r"""
        addMultipole(self, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity) -> int
        Add multipole-related info for a particle

        Parameters
        ----------
        charge : double
            the particle's charge
        molecularDipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        molecularQuadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in constructing lab<->molecular frames
        multipoleAtomX : int
            index of second atom used in constructing lab<->molecular frames
        multipoleAtomY : int
            index of second atom used in constructing lab<->molecular frames
        thole : double
            Thole parameter
        dampingFactor : double
            dampingFactor parameter
        polarity : double
            polarity parameter

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.AmoebaMultipoleForce_addMultipole(self, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)

    def getMultipoleParameters(self, index):
        r"""
        getMultipoleParameters(self, index)
        Get the multipole parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the atom for which to get parameters

        Returns
        -------
        charge : double
            the particle's charge
        molecularDipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        molecularQuadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in constructing lab<->molecular frames
        multipoleAtomX : int
            index of second atom used in constructing lab<->molecular frames
        multipoleAtomY : int
            index of second atom used in constructing lab<->molecular frames
        thole : double
            Thole parameter
        dampingFactor : double
            dampingFactor parameter
        polarity : double
            polarity parameter
        """
        val = _openmm.AmoebaMultipoleForce_getMultipoleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.elementary_charge)
        val[1]=unit.Quantity(val[1], unit.elementary_charge*unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.elementary_charge*unit.nanometer**2)
        val[9]=unit.Quantity(val[9], unit.nanometer**3)


        return val


    def setMultipoleParameters(self, index, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity):
        r"""
        setMultipoleParameters(self, index, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)
        Set the multipole parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the atom for which to set parameters
        charge : double
            the particle's charge
        molecularDipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        molecularQuadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in constructing lab<->molecular frames
        multipoleAtomX : int
            index of second atom used in constructing lab<->molecular frames
        multipoleAtomY : int
            index of second atom used in constructing lab<->molecular frames
        thole : double
            thole parameter
        dampingFactor : double
            damping factor parameter
        polarity : double
            polarity parameter
        """
        return _openmm.AmoebaMultipoleForce_setMultipoleParameters(self, index, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)

    def setCovalentMap(self, index, typeId, covalentAtoms):
        r"""
        setCovalentMap(self, index, typeId, covalentAtoms)
        Set the CovalentMap for an atom

        Parameters
        ----------
        index : int
            the index of the atom for which to set parameters
        typeId : CovalentType
            CovalentTypes type
        covalentAtoms : vector< int >
            vector of covalent atoms associated w/ the specfied CovalentType
        """
        return _openmm.AmoebaMultipoleForce_setCovalentMap(self, index, typeId, covalentAtoms)

    def getCovalentMap(self, index, typeId):
        r"""
        getCovalentMap(self, index, typeId)
        Get the CovalentMap for an atom

        Parameters
        ----------
        index : int
            the index of the atom for which to set parameters
        typeId : CovalentType
            CovalentTypes type

        Returns
        -------
        covalentAtoms : vector< int >
            output vector of covalent atoms associated w/ the specfied CovalentType
        """
        return _openmm.AmoebaMultipoleForce_getCovalentMap(self, index, typeId)

    def getCovalentMaps(self, index):
        r"""
        getCovalentMaps(self, index)
        Get the CovalentMap for an atom

        Parameters
        ----------
        index : int
            the index of the atom for which to set parameters

        Returns
        -------
        covalentLists : vector< std::vector< int > >
            output vector of covalent lists of atoms
        """
        return _openmm.AmoebaMultipoleForce_getCovalentMaps(self, index)

    def getMutualInducedMaxIterations(self):
        r"""
        getMutualInducedMaxIterations(self) -> int
        Get the max number of iterations to be used in calculating the mutual induced dipoles

        Returns
        -------
        int
            max number of iterations
        """
        return _openmm.AmoebaMultipoleForce_getMutualInducedMaxIterations(self)

    def setMutualInducedMaxIterations(self, inputMutualInducedMaxIterations):
        r"""
        setMutualInducedMaxIterations(self, inputMutualInducedMaxIterations)
        Set the max number of iterations to be used in calculating the mutual induced dipoles

        Parameters
        ----------
        inputMutualInducedMaxIterations : int
            number of iterations
        """
        return _openmm.AmoebaMultipoleForce_setMutualInducedMaxIterations(self, inputMutualInducedMaxIterations)

    def getMutualInducedTargetEpsilon(self):
        r"""
        getMutualInducedTargetEpsilon(self) -> double
        Get the target epsilon to be used to test for convergence of iterative method used in calculating the mutual induced dipoles

        Returns
        -------
        double
            target epsilon
        """
        return _openmm.AmoebaMultipoleForce_getMutualInducedTargetEpsilon(self)

    def setMutualInducedTargetEpsilon(self, inputMutualInducedTargetEpsilon):
        r"""
        setMutualInducedTargetEpsilon(self, inputMutualInducedTargetEpsilon)
        Set the target epsilon to be used to test for convergence of iterative method used in calculating the mutual induced dipoles

        Parameters
        ----------
        inputMutualInducedTargetEpsilon : double
            target epsilon
        """
        return _openmm.AmoebaMultipoleForce_setMutualInducedTargetEpsilon(self, inputMutualInducedTargetEpsilon)

    def setExtrapolationCoefficients(self, coefficients):
        r"""
        setExtrapolationCoefficients(self, coefficients)
        Set the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the extrapolation algorithm for induced dipoles.

        Parameters
        ----------
        coefficients : vector< double >
            a vector whose mth entry specifies the coefficient for mu_m. The length of this vector determines how many iterations are performed.
        """
        return _openmm.AmoebaMultipoleForce_setExtrapolationCoefficients(self, coefficients)

    def getExtrapolationCoefficients(self):
        r"""
        getExtrapolationCoefficients(self) -> vectord
        Get the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the extrapolation algorithm for induced dipoles. In this release, the default values for the coefficients are [-0.154, 0.017, 0.658, 0.474], but be aware that those may change in a future release.
        """
        return _openmm.AmoebaMultipoleForce_getExtrapolationCoefficients(self)

    def getEwaldErrorTolerance(self):
        r"""
        getEwaldErrorTolerance(self) -> double
        Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the grid dimensions and separation (alpha) parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        This can be overridden by explicitly setting an alpha parameter and grid dimensions to use.
        """
        return _openmm.AmoebaMultipoleForce_getEwaldErrorTolerance(self)

    def setEwaldErrorTolerance(self, tol):
        r"""
        setEwaldErrorTolerance(self, tol)
        Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the grid dimensions and separation (alpha) parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        This can be overridden by explicitly setting an alpha parameter and grid dimensions to use.
        """
        return _openmm.AmoebaMultipoleForce_setEwaldErrorTolerance(self, tol)

    def getLabFramePermanentDipoles(self, context):
        r"""
        getLabFramePermanentDipoles(self, context)
        Get the fixed dipole moments of all particles in the global reference frame.

        Parameters
        ----------
        context : Context
            the Context for which to get the fixed dipoles

        Returns
        -------
        dipoles : vector< Vec3 >
            the fixed dipole moment of particle i is stored into the i'th element
        """
        return _openmm.AmoebaMultipoleForce_getLabFramePermanentDipoles(self, context)

    def getInducedDipoles(self, context):
        r"""
        getInducedDipoles(self, context)
        Get the induced dipole moments of all particles.

        Parameters
        ----------
        context : Context
            the Context for which to get the induced dipoles

        Returns
        -------
        dipoles : vector< Vec3 >
            the induced dipole moment of particle i is stored into the i'th element
        """
        return _openmm.AmoebaMultipoleForce_getInducedDipoles(self, context)

    def getTotalDipoles(self, context):
        r"""
        getTotalDipoles(self, context)
        Get the total dipole moments (fixed plus induced) of all particles.

        Parameters
        ----------
        context : Context
            the Context for which to get the total dipoles

        Returns
        -------
        dipoles : vector< Vec3 >
            the total dipole moment of particle i is stored into the i'th element
        """
        return _openmm.AmoebaMultipoleForce_getTotalDipoles(self, context)

    def getElectrostaticPotential(self, inputGrid, context):
        r"""
        getElectrostaticPotential(self, inputGrid, context)
        Get the electrostatic potential.

        Parameters
        ----------
        inputGrid : vector< Vec3 >
            input grid points over which the potential is to be evaluated
        context : Context
            context

        Returns
        -------
        outputElectrostaticPotential : vector< double >
            output potential
        """
        return _openmm.AmoebaMultipoleForce_getElectrostaticPotential(self, inputGrid, context)

    def getSystemMultipoleMoments(self, context):
        r"""
        getSystemMultipoleMoments(self, context)
        Get the system multipole moments.

        This method is most useful for non-periodic systems. When called for a periodic system, only the <i>lowest nonvanishing moment</i> has a well defined value. This means that if the system has a net nonzero charge, the dipole and quadrupole moments are not well defined and should be ignored. If the net charge is zero, the dipole moment is well defined (and really represents a dipole density), but the quadrupole moment is still undefined and should be ignored.

        Parameters
        ----------
        context : Context
            context

        Returns
        -------
        outputMultipoleMoments : vector< double >
            (charge, dipole_x, dipole_y, dipole_z, quadrupole_xx, quadrupole_xy, quadrupole_xz, quadrupole_yx, quadrupole_yy, quadrupole_yz, quadrupole_zx, quadrupole_zy, quadrupole_zz)
        """
        return _openmm.AmoebaMultipoleForce_getSystemMultipoleMoments(self, context)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the multipole parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setMultipoleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the parameters of multipoles. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Furthermore, this method cannot be used to add new multipoles, only to change the parameters of existing ones.
        """
        return _openmm.AmoebaMultipoleForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.AmoebaMultipoleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaMultipoleForce
        __init__(self, other) -> AmoebaMultipoleForce
        Create an AmoebaMultipoleForce.
        """
        _openmm.AmoebaMultipoleForce_swiginit(self, _openmm.new_AmoebaMultipoleForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaMultipoleForce

# Register AmoebaMultipoleForce in _openmm:
_openmm.AmoebaMultipoleForce_swigregister(AmoebaMultipoleForce)

class AmoebaOutOfPlaneBendForce(Force):
    r"""
    This class implements the Amoeba out-of-plane bend interaction.

    To use it, create an OutOfPlaneBendForce object then call addOutOfPlaneBend() once for each outOfPlaneBend. After an out-of-plane bend has been added, you can modify its force field parameters by calling setOutOfPlaneBendParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumOutOfPlaneBends(self):
        r"""
        getNumOutOfPlaneBends(self) -> int
        Get the number of out-of-plane bend terms in the potential function
        """
        return _openmm.AmoebaOutOfPlaneBendForce_getNumOutOfPlaneBends(self)

    def setAmoebaGlobalOutOfPlaneBendCubic(self, cubicK):
        r"""
        setAmoebaGlobalOutOfPlaneBendCubic(self, cubicK)
        Set the global cubic term

        Parameters
        ----------
        cubicK : double
            the cubic force constant for the angle
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setAmoebaGlobalOutOfPlaneBendCubic(self, cubicK)

    def getAmoebaGlobalOutOfPlaneBendCubic(self):
        r"""
        getAmoebaGlobalOutOfPlaneBendCubic(self) -> double
        Get the global cubic term

        Returns
        -------
        double
            global cubicK term
        """
        val = _openmm.AmoebaOutOfPlaneBendForce_getAmoebaGlobalOutOfPlaneBendCubic(self)

        val=unit.Quantity(val, 1/unit.radian)


        return val


    def setAmoebaGlobalOutOfPlaneBendQuartic(self, quarticK):
        r"""
        setAmoebaGlobalOutOfPlaneBendQuartic(self, quarticK)
        Set the global cubic term

        Parameters
        ----------
        quarticK : double
            the quartic force constant for the angle
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setAmoebaGlobalOutOfPlaneBendQuartic(self, quarticK)

    def getAmoebaGlobalOutOfPlaneBendQuartic(self):
        r"""
        getAmoebaGlobalOutOfPlaneBendQuartic(self) -> double
        Get the global quartic term

        Returns
        -------
        double
            global quartic term
        """
        val = _openmm.AmoebaOutOfPlaneBendForce_getAmoebaGlobalOutOfPlaneBendQuartic(self)

        val=unit.Quantity(val, 1/unit.radian**2)


        return val


    def setAmoebaGlobalOutOfPlaneBendPentic(self, penticK):
        r"""
        setAmoebaGlobalOutOfPlaneBendPentic(self, penticK)
        Set the global pentic term

        Parameters
        ----------
        penticK : double
            the pentic force constant for the angle
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setAmoebaGlobalOutOfPlaneBendPentic(self, penticK)

    def getAmoebaGlobalOutOfPlaneBendPentic(self):
        r"""
        getAmoebaGlobalOutOfPlaneBendPentic(self) -> double
        Get the global pentic term

        Returns
        -------
        double
            global penticK term
        """
        val = _openmm.AmoebaOutOfPlaneBendForce_getAmoebaGlobalOutOfPlaneBendPentic(self)

        val=unit.Quantity(val, 1/unit.radian**3)


        return val


    def setAmoebaGlobalOutOfPlaneBendSextic(self, sexticK):
        r"""
        setAmoebaGlobalOutOfPlaneBendSextic(self, sexticK)
        Set the global sextic term

        Parameters
        ----------
        sexticK : double
            the sextic force constant for the angle
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setAmoebaGlobalOutOfPlaneBendSextic(self, sexticK)

    def getAmoebaGlobalOutOfPlaneBendSextic(self):
        r"""
        getAmoebaGlobalOutOfPlaneBendSextic(self) -> double
        Get the global sextic term

        Returns
        -------
        double
            global sexticK term
        """
        val = _openmm.AmoebaOutOfPlaneBendForce_getAmoebaGlobalOutOfPlaneBendSextic(self)

        val=unit.Quantity(val, 1/unit.radian**4)


        return val


    def addOutOfPlaneBend(self, particle1, particle2, particle3, particle4, k):
        r"""
        addOutOfPlaneBend(self, particle1, particle2, particle3, particle4, k) -> int
        Add an out-of-plane bend term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the outOfPlaneBend
        particle2 : int
            the index of the second particle connected by the outOfPlaneBend
        particle3 : int
            the index of the third particle connected by the outOfPlaneBend
        particle4 : int
            the index of the fourth particle connected by the outOfPlaneBend
        k : double
            the force constant for the out-of-plane bend

        Returns
        -------
        int
            the index of the out-of-plane bend that was added
        """
        return _openmm.AmoebaOutOfPlaneBendForce_addOutOfPlaneBend(self, particle1, particle2, particle3, particle4, k)

    def getOutOfPlaneBendParameters(self, index):
        r"""
        getOutOfPlaneBendParameters(self, index)
        Get the force field parameters for an out-of-plane bend term.

        Parameters
        ----------
        index : int
            the index of the outOfPlaneBend for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the outOfPlaneBend
        particle2 : int
            the index of the second particle connected by the outOfPlaneBend
        particle3 : int
            the index of the third particle connected by the outOfPlaneBend
        particle4 : int
            the index of the fourth particle connected by the outOfPlaneBend
        k : double
            the force constant for the out-of-plane bend
        """
        val = _openmm.AmoebaOutOfPlaneBendForce_getOutOfPlaneBendParameters(self, index)

        val[4]=unit.Quantity(val[4], unit.kilojoule_per_mole/unit.radians**2)


        return val


    def setOutOfPlaneBendParameters(self, index, particle1, particle2, particle3, particle4, k):
        r"""
        setOutOfPlaneBendParameters(self, index, particle1, particle2, particle3, particle4, k)
        Set the force field parameters for an out-of-plane bend term.

        Parameters
        ----------
        index : int
            the index of the outOfPlaneBend for which to set parameters
        particle1 : int
            the index of the first particle connected by the outOfPlaneBend
        particle2 : int
            the index of the second particle connected by the outOfPlaneBend
        particle3 : int
            the index of the third particle connected by the outOfPlaneBend
        particle4 : int
            the index of the fourth particle connected by the outOfPlaneBend
        k : double
            the force constant for the out-of-plane bend
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setOutOfPlaneBendParameters(self, index, particle1, particle2, particle3, particle4, k)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bend term parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setOutOfPlaneBendParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-bend term parameters. The set of particles involved in a term cannot be changed, nor can new terms be added.
        """
        return _openmm.AmoebaOutOfPlaneBendForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaOutOfPlaneBendForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaOutOfPlaneBendForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaOutOfPlaneBendForce
        __init__(self, other) -> AmoebaOutOfPlaneBendForce
        Create an AmoebaOutOfPlaneBendForce.
        """
        _openmm.AmoebaOutOfPlaneBendForce_swiginit(self, _openmm.new_AmoebaOutOfPlaneBendForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaOutOfPlaneBendForce

# Register AmoebaOutOfPlaneBendForce in _openmm:
_openmm.AmoebaOutOfPlaneBendForce_swigregister(AmoebaOutOfPlaneBendForce)

class AmoebaPiTorsionForce(Force):
    r"""
    This class implements the Amoeba pi-torsion interaction.

    To use it, create an AmoebaPiTorsionForce object then call addPiTorsion() once for each torsion. After a torsion has been added, you can modify its force field parameters by calling setPiTorsionParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumPiTorsions(self):
        r"""
        getNumPiTorsions(self) -> int
        Get the number of pi torsion terms in the potential function
        """
        return _openmm.AmoebaPiTorsionForce_getNumPiTorsions(self)

    def addPiTorsion(self, particle1, particle2, particle3, particle4, particle5, particle6, k):
        r"""
        addPiTorsion(self, particle1, particle2, particle3, particle4, particle5, particle6, k) -> int
        Add a torsion term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        particle5 : int
            the index of the fifth particle connected by the torsion
        particle6 : int
            the index of the sixth particle connected by the torsion
        k : double
            the force constant for the torsion

        Returns
        -------
        int
            the index of the torsion that was added
        """
        return _openmm.AmoebaPiTorsionForce_addPiTorsion(self, particle1, particle2, particle3, particle4, particle5, particle6, k)

    def getPiTorsionParameters(self, index):
        r"""
        getPiTorsionParameters(self, index)
        Get the force field parameters for a torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        particle5 : int
            the index of the fifth particle connected by the torsion
        particle6 : int
            the index of the sixth particle connected by the torsion
        k : double
            the force constant for the torsion
        """
        val = _openmm.AmoebaPiTorsionForce_getPiTorsionParameters(self, index)

        val[6]=unit.Quantity(val[6], unit.kilojoule_per_mole)


        return val


    def setPiTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, particle6, k):
        r"""
        setPiTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, particle6, k)
        Set the force field parameters for a pi torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to set parameters
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        particle5 : int
            the index of the fifth particle connected by the torsion
        particle6 : int
            the index of the sixth particle connected by the torsion
        k : double
            the force constant for the torsion
        """
        return _openmm.AmoebaPiTorsionForce_setPiTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, particle6, k)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setPiTorsionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-torsion parameters. The set of particles involved in a torsion cannot be changed, nor can new torsions be added.
        """
        return _openmm.AmoebaPiTorsionForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaPiTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaPiTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaPiTorsionForce
        __init__(self, other) -> AmoebaPiTorsionForce
        Create an AmoebaPiTorsionForce.
        """
        _openmm.AmoebaPiTorsionForce_swiginit(self, _openmm.new_AmoebaPiTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaPiTorsionForce

# Register AmoebaPiTorsionForce in _openmm:
_openmm.AmoebaPiTorsionForce_swigregister(AmoebaPiTorsionForce)

class AmoebaStretchBendForce(Force):
    r"""
    This class implements the Amoeba stretch-bend interaction.

    To use it, create a StretchBendForce object then call addStretchBend() once for each stretch-bend. After a stretch-bend has been added, you can modify its force field parameters by calling setStretchBendParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumStretchBends(self):
        r"""
        getNumStretchBends(self) -> int
        Get the number of stretch-bend terms in the potential function
        """
        return _openmm.AmoebaStretchBendForce_getNumStretchBends(self)

    def addStretchBend(self, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2):
        r"""
        addStretchBend(self, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2) -> int
        Add a stretch-bend term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the stretch-bend
        particle2 : int
            the index of the second particle connected by the stretch-bend
        particle3 : int
            the index of the third particle connected by the stretch-bend
        lengthAB : double
            the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
        lengthCB : double
            the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
        angle : double
            the equilibrium angle in radians
        k1 : double
            the force constant of the product of bond ab and angle a-b-c
        k2 : double
            the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1)

        Returns
        -------
        int
            the index of the stretch-bend that was added
        """
        return _openmm.AmoebaStretchBendForce_addStretchBend(self, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)

    def getStretchBendParameters(self, index):
        r"""
        getStretchBendParameters(self, index)
        Get the force field parameters for a stretch-bend term.

        Parameters
        ----------
        index : int
            the index of the stretch-bend for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the stretch-bend
        particle2 : int
            the index of the second particle connected by the stretch-bend
        particle3 : int
            the index of the third particle connected by the stretch-bend
        lengthAB : double
            the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
        lengthCB : double
            the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
        angle : double
            the equilibrium angle in radians
        k1 : double
            the force constant of the product of bond ab and angle a-b-c
        k2 : double
            the force constant of the product of bond bc and angle a-b-c
        """
        val = _openmm.AmoebaStretchBendForce_getStretchBendParameters(self, index)

        val[3]=unit.Quantity(val[3], unit.nanometer)
        val[4]=unit.Quantity(val[4], unit.nanometer)
        val[5]=unit.Quantity(val[5], unit.radian)
        val[6]=unit.Quantity(val[6], unit.kilojoule_per_mole/unit.nanometer/unit.radian)
        val[7]=unit.Quantity(val[7], unit.kilojoule_per_mole/unit.nanometer/unit.radian)


        return val


    def setStretchBendParameters(self, index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2):
        r"""
        setStretchBendParameters(self, index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)
        Set the force field parameters for a stretch-bend term.

        Parameters
        ----------
        index : int
            the index of the stretch-bend for which to set parameters
        particle1 : int
            the index of the first particle connected by the stretch-bend
        particle2 : int
            the index of the second particle connected by the stretch-bend
        particle3 : int
            the index of the third particle connected by the stretch-bend
        lengthAB : double
            the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
        lengthCB : double
            the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
        angle : double
            the equilibrium angle in radians
        k1 : double
            the force constant of the product of bond ab and angle a-b-c
        k2 : double
            the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1)
        """
        return _openmm.AmoebaStretchBendForce_setStretchBendParameters(self, index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setStretchBendParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-stretch-bend term parameters. The set of particles involved in a term cannot be changed, nor can new terms be added.
        """
        return _openmm.AmoebaStretchBendForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaStretchBendForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaStretchBendForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaStretchBendForce
        __init__(self, other) -> AmoebaStretchBendForce
        Create an AmoebaStretchBendForce.
        """
        _openmm.AmoebaStretchBendForce_swiginit(self, _openmm.new_AmoebaStretchBendForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaStretchBendForce

# Register AmoebaStretchBendForce in _openmm:
_openmm.AmoebaStretchBendForce_swigregister(AmoebaStretchBendForce)

class AmoebaTorsionTorsionForce(Force):
    r"""
    This class implements the Amoeba torsion-torsion interaction.

    To use it, create an AmoebaTorsionTorsionForce object then call addTorsionTorsion() once for each torsion-torsion. After a torsion-torsion has been added, you can modify its force field parameters by calling setTorsionTorsionParameters().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumTorsionTorsions(self):
        r"""
        getNumTorsionTorsions(self) -> int
        Get the number of torsion-torsion terms in the potential function
        """
        return _openmm.AmoebaTorsionTorsionForce_getNumTorsionTorsions(self)

    def getNumTorsionTorsionGrids(self):
        r"""
        getNumTorsionTorsionGrids(self) -> int
        Get the number of torsion-torsion grids
        """
        return _openmm.AmoebaTorsionTorsionForce_getNumTorsionTorsionGrids(self)

    def addTorsionTorsion(self, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex):
        r"""
        addTorsionTorsion(self, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex) -> int
        Add a torsion-torsion term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the torsion-torsion
        particle2 : int
            the index of the second particle connected by the torsion-torsion
        particle3 : int
            the index of the third particle connected by the torsion-torsion
        particle4 : int
            the index of the fourth particle connected by the torsion-torsion
        particle5 : int
            the index of the fifth particle connected by the torsion-torsion
        chiralCheckAtomIndex : int
            the index of the particle connected to particle3, but not particle2 or particle4 to be used in chirality check
        gridIndex : int
            the index to the grid to be used

        Returns
        -------
        int
            the index of the torsion-torsion that was added
        """
        return _openmm.AmoebaTorsionTorsionForce_addTorsionTorsion(self, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex)

    def getTorsionTorsionParameters(self, index):
        r"""
        getTorsionTorsionParameters(self, index)
        Get the force field parameters for a torsion-torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion-torsion for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the torsion-torsion
        particle2 : int
            the index of the second particle connected by the torsion-torsion
        particle3 : int
            the index of the third particle connected by the torsion-torsion
        particle4 : int
            the index of the fourth particle connected by the torsion-torsion
        particle5 : int
            the index of the fifth particle connected by the torsion-torsion
        chiralCheckAtomIndex : int
            the index of the particle connected to particle3, but not particle2 or particle4 to be used in chirality check
        gridIndex : int
            the grid index
        """
        return _openmm.AmoebaTorsionTorsionForce_getTorsionTorsionParameters(self, index)

    def setTorsionTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex):
        r"""
        setTorsionTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex)
        Set the force field parameters for a torsion-torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion-torsion for which to set parameters
        particle1 : int
            the index of the first particle connected by the torsion-torsion
        particle2 : int
            the index of the second particle connected by the torsion-torsion
        particle3 : int
            the index of the third particle connected by the torsion-torsion
        particle4 : int
            the index of the fourth particle connected by the torsion-torsion
        particle5 : int
            the index of the fifth particle connected by the torsion-torsion
        chiralCheckAtomIndex : int
            the index of the particle connected to particle3, but not particle2 or particle4 to be used in chirality check
        gridIndex : int
            the grid index
        """
        return _openmm.AmoebaTorsionTorsionForce_setTorsionTorsionParameters(self, index, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex)

    def getTorsionTorsionGrid(self, index):
        r"""
        getTorsionTorsionGrid(self, index) -> vectorddd
        Get the torsion-torsion grid at the specified index

        Parameters
        ----------
        index : int
            the grid index

        Returns
        -------
        vector< std::vector< std::vector< double > > >
            grid return grid reference
        """
        return _openmm.AmoebaTorsionTorsionForce_getTorsionTorsionGrid(self, index)

    def setTorsionTorsionGrid(self, index, grid):
        r"""
        setTorsionTorsionGrid(self, index, grid)
        Set the torsion-torsion grid at the specified index

        Parameters
        ----------
        index : int
            the index of the torsion-torsion for which to get parameters
        grid : vector< std::vector< std::vector< double > > >
            either 3 or 6 values may be specified per grid point. If the derivatives are omitted, they are calculated automatically by fitting a 2D spline to the energies. grid[x][y][0] = x value grid[x][y][1] = y value grid[x][y][2] = energy grid[x][y][3] = dEdx value grid[x][y][4] = dEdy value grid[x][y][5] = dEd(xy) value
        """

        def deunitize_grid(grid):
            if isinstance(grid, tuple):
                grid = list(grid)
            for i, row in enumerate(grid):
                if isinstance(row, tuple):
                    row = list(row)
                    grid[i] = row
                for i, column in enumerate(row):
                    if isinstance(column, tuple):
                        column = list(column)
                        row[i] = column
        # Data is angle, angle, energy, de/dang1, de/dang2, d^2e/dang1dang2
                    if unit.is_quantity(column[0]):
                        column[0] = column[0].value_in_unit(unit.degree)
                    if unit.is_quantity(column[1]):
                        column[1] = column[1].value_in_unit(unit.degree)
                    if unit.is_quantity(column[2]):
                        column[2] = column[2].value_in_unit(unit.kilojoule_per_mole)
                    if len(column) > 3 and unit.is_quantity(column[3]):
                        column[3] = column[3].value_in_unit(unit.kilojoule_per_mole/unit.radians)
                    if len(column) > 4 and unit.is_quantity(column[4]):
                        column[4] = column[4].value_in_unit(unit.kilojoule_per_mole/unit.radians)
                    if len(column) > 5 and unit.is_quantity(column[5]):
                        column[5] = column[5].value_in_unit(unit.kilojoule_per_mole/unit.radians**2)
            return grid
        try:
            grid = copy.deepcopy(args[1])
            if isinstance(args, tuple):
                args = list(args)
        except (NameError, UnboundLocalError):
            try:
        # Support numpy arrays
                grid = grid.tolist()
            except AttributeError:
                grid = copy.deepcopy(grid)
            grid = deunitize_grid(grid)
        else:
            args[1] = deunitize_grid(grid)


        return _openmm.AmoebaTorsionTorsionForce_setTorsionTorsionGrid(self, index, grid)


    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.AmoebaTorsionTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AmoebaTorsionTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaTorsionTorsionForce
        __init__(self, other) -> AmoebaTorsionTorsionForce
        Create an AmoebaTorsionTorsionForce.
        """
        _openmm.AmoebaTorsionTorsionForce_swiginit(self, _openmm.new_AmoebaTorsionTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaTorsionTorsionForce

# Register AmoebaTorsionTorsionForce in _openmm:
_openmm.AmoebaTorsionTorsionForce_swigregister(AmoebaTorsionTorsionForce)

class AmoebaVdwForce(Force):
    r"""
    This class models van der Waals forces in the AMOEBA force field. It can use either buffered 14-7 potential or a Lennard-Jones 12-6 potential.

    This class can operate in two different modes. In one mode, force field parameters are defined for each particle. When two particles interact, a combining rule is used to calculate the interaction parameters based on the parameters for the two particles. To use the class in this mode, call the version of addParticle() that takes sigma and epsilon values. It should be called once for each particle in the System.

    In the other mode, each particle has a type index, and parameters are specified for each type rather than each individual particle. By default this mode also uses a combining rule, but you can override it by defining alternate parameters to use for specific pairs of particle types. To use the class in this mode, call the version of addParticle() that takes a type index. It should be called once for each particle in the System. You also must call addParticleType() once for each type. If you wish to override the combining for particular pairs of types, do so by calling addTypePair().

    A unique feature of this class is that the interaction site for a particle does not need to be exactly at the particle's location. Instead, it can be placed a fraction of the distance from that particle to another one. This is typically done for hydrogens to place the interaction site slightly closer to the parent atom. The fraction is known as the "reduction factor", since it reduces the distance from the parent atom to the interaction site.

    Support is also available for softcore interactions based on setting a per particle alchemical flag and setting the AmoebaVdwForce to use an "AlchemicalMethod"  either Decouple or Annihilate. For Decouple, two alchemical atoms interact normally. For Annihilate, all interactions involving an alchemical atom are influenced. The softcore state is specified by setting a single Context parameter "AmoebaVdwLambda" between 0.0 and 1.0.

    The softcore functional form can be modified by setting the softcore power (default of 5) and the softcore alpha (default of 0,7). For more information on the softcore functional form see Eq. 2 from: Jiao, D.; Golubkov, P. A.; Darden, T. A.; Ren, P., Calculation of protein-ligand binding free energy by using a polarizable potential. Proc. Natl. Acad. Sci. U.S.A. 2008, 105 (17), 6290-6295. .
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.AmoebaVdwForce_NoCutoff
    
    CutoffPeriodic = _openmm.AmoebaVdwForce_CutoffPeriodic
    
    Buffered147 = _openmm.AmoebaVdwForce_Buffered147
    
    LennardJones = _openmm.AmoebaVdwForce_LennardJones
    
    _None = _openmm.AmoebaVdwForce__None
    
    Decouple = _openmm.AmoebaVdwForce_Decouple
    
    Annihilate = _openmm.AmoebaVdwForce_Annihilate
    

    @staticmethod
    def Lambda():
        r"""
        Lambda() -> std::string const &
        This is the name of the parameter which stores the current Amoeba vdW lambda value.
        """
        return _openmm.AmoebaVdwForce_Lambda()

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles
        """
        return _openmm.AmoebaVdwForce_getNumParticles(self)

    def getNumParticleTypes(self):
        r"""
        getNumParticleTypes(self) -> int
        Get the number of particle types.
        """
        return _openmm.AmoebaVdwForce_getNumParticleTypes(self)

    def getNumTypePairs(self):
        r"""
        getNumTypePairs(self) -> int
        Get the number of type pairs.
        """
        return _openmm.AmoebaVdwForce_getNumTypePairs(self)

    def setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor, isAlchemical=False, typeIndex=-1):
        r"""
        setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor, isAlchemical=False, typeIndex=-1)
        Set the force field parameters for a vdw particle.

        Parameters
        ----------
        particleIndex : int
            the particle index
        parentIndex : int
            the index of the parent particle
        sigma : double
            vdw sigma
        epsilon : double
            vdw epsilon
        reductionFactor : double
            the fraction of the distance along the line from the parent particle to this particle at which the interaction site should be placed
        isAlchemical : bool
            if true, this vdW particle is undergoing an alchemical change.
        typeIndex : int
            the index of the particle type for this particle
        """
        return _openmm.AmoebaVdwForce_setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor, isAlchemical, typeIndex)

    def getParticleParameters(self, particleIndex):
        r"""
        getParticleParameters(self, particleIndex)
        Get the force field parameters for a vdw particle.

        Parameters
        ----------
        particleIndex : int
            the particle index

        Returns
        -------
        parentIndex : int
            the index of the parent particle
        sigma : double
            vdw sigma
        epsilon : double
            vdw epsilon
        reductionFactor : double
            the fraction of the distance along the line from the parent particle to this particle at which the interaction site should be placed
        isAlchemical : bool
            if true, this vdW particle is undergoing an alchemical change.
        typeIndex : int
            the index of the particle type for this particle
        """
        val = _openmm.AmoebaVdwForce_getParticleParameters(self, particleIndex)

        val[1]=unit.Quantity(val[1], unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.kilojoule_per_mole)


        return val


    def addParticle(self, *args):
        r"""
        addParticle(self, parentIndex, sigma, epsilon, reductionFactor, isAlchemical=False) -> int
        addParticle(self, parentIndex, typeIndex, reductionFactor, isAlchemical=False) -> int
        Add the force field parameters for a vdw particle. This version is used when parameters are defined by particle type.

        Parameters
        ----------
        parentIndex : int
            the index of the parent particle
        typeIndex : int
            the index of the particle type for this particle
        reductionFactor : double
            the fraction of the distance along the line from the parent particle to this particle at which the interaction site should be placed
        isAlchemical : bool
            if true, this vdW particle is undergoing an alchemical change.

        Returns
        -------
        int
            index of added particle
        """
        return _openmm.AmoebaVdwForce_addParticle(self, *args)

    def addParticleType(self, sigma, epsilon):
        r"""
        addParticleType(self, sigma, epsilon) -> int
        Add a particle type.

        Parameters
        ----------
        sigma : double
            the sigma value for particles of this type
        epsilon : double
            the epsilon value for particles of this type

        Returns
        -------
        int
            the index of the particle type that was just added.
        """
        return _openmm.AmoebaVdwForce_addParticleType(self, sigma, epsilon)

    def getParticleTypeParameters(self, typeIndex):
        r"""
        getParticleTypeParameters(self, typeIndex)
        Get the force field parameters for a particle type.

        Parameters
        ----------
        typeIndex : int
            the index of the particle type

        Returns
        -------
        sigma : double
            the sigma value for particles of this type
        epsilon : double
            the epsilon value for particles of this type
        """
        val = _openmm.AmoebaVdwForce_getParticleTypeParameters(self, typeIndex)

        val[1]=unit.Quantity(val[1], unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.kilojoule_per_mole)


        return val


    def setParticleTypeParameters(self, typeIndex, sigma, epsilon):
        r"""
        setParticleTypeParameters(self, typeIndex, sigma, epsilon)
        Set the force field parameters for a particle type.

        Parameters
        ----------
        typeIndex : int
            the index of the particle type
        sigma : double
            the sigma value for particles of this type
        epsilon : double
            the epsilon value for particles of this type
        """
        return _openmm.AmoebaVdwForce_setParticleTypeParameters(self, typeIndex, sigma, epsilon)

    def addTypePair(self, type1, type2, sigma, epsilon):
        r"""
        addTypePair(self, type1, type2, sigma, epsilon) -> int
        Add a type pair. This overrides the standard combining rule for interactions between particles of two particular types.

        Parameters
        ----------
        type1 : int
            the index of the first particle type
        type2 : int
            the index of the second particle type
        sigma : double
            the sigma value for interactions between particles of these two types
        epsilon : double
            the epsilon value for interactions between particles of these two types

        Returns
        -------
        int
            the index of the type pair that was just added.
        """
        return _openmm.AmoebaVdwForce_addTypePair(self, type1, type2, sigma, epsilon)

    def getTypePairParameters(self, pairIndex):
        r"""
        getTypePairParameters(self, pairIndex)
        Get the force field parameters for a type pair. This overrides the standard combining rule for interactions between particles of two particular types.

        Parameters
        ----------
        pairIndex : int
            the index of the type pair

        Returns
        -------
        type1 : int
            the index of the first particle type
        type2 : int
            the index of the second particle type
        sigma : double
            the sigma value for interactions between particles of these two types
        epsilon : double
            the epsilon value for interactions between particles of these two types
        """
        val = _openmm.AmoebaVdwForce_getTypePairParameters(self, pairIndex)

        val[3]=unit.Quantity(val[3], unit.nanometer)
        val[4]=unit.Quantity(val[4], unit.kilojoule_per_mole)


        return val


    def setTypePairParameters(self, pairIndex, type1, type2, sigma, epsilon):
        r"""
        setTypePairParameters(self, pairIndex, type1, type2, sigma, epsilon)
        Set the force field parameters for a type pair. This overrides the standard combining rule for interactions between particles of two particular types.

        Parameters
        ----------
        pairIndex : int
            the index of the type pair
        type1 : int
            the index of the first particle type
        type2 : int
            the index of the second particle type
        sigma : double
            the sigma value for interactions between particles of these two types
        epsilon : double
            the epsilon value for interactions between particles of these two types
        """
        return _openmm.AmoebaVdwForce_setTypePairParameters(self, pairIndex, type1, type2, sigma, epsilon)

    def setSigmaCombiningRule(self, sigmaCombiningRule):
        r"""
        setSigmaCombiningRule(self, sigmaCombiningRule)
        Set sigma combining rule

        Parameters
        ----------
        sigmaCombiningRule : string
            sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN'
        """
        return _openmm.AmoebaVdwForce_setSigmaCombiningRule(self, sigmaCombiningRule)

    def getSigmaCombiningRule(self):
        r"""
        getSigmaCombiningRule(self) -> std::string const &
        Get sigma combining rule

        Returns
        -------
        string
            sigmaCombiningRule sigma combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'CUBIC-MEAN'
        """
        return _openmm.AmoebaVdwForce_getSigmaCombiningRule(self)

    def setEpsilonCombiningRule(self, epsilonCombiningRule):
        r"""
        setEpsilonCombiningRule(self, epsilonCombiningRule)
        Set epsilon combining rule

        Parameters
        ----------
        epsilonCombiningRule : string
            epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'W-H', 'HHG'
        """
        return _openmm.AmoebaVdwForce_setEpsilonCombiningRule(self, epsilonCombiningRule)

    def getEpsilonCombiningRule(self):
        r"""
        getEpsilonCombiningRule(self) -> std::string const &
        Get epsilon combining rule

        Returns
        -------
        string
            epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'W-H', 'HHG'
        """
        return _openmm.AmoebaVdwForce_getEpsilonCombiningRule(self)

    def getUseDispersionCorrection(self):
        r"""
        getUseDispersionCorrection(self) -> bool
        Get whether to add a contribution to the energy that approximately represents the effect of VdW interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding this contribution can improve the quality of results.
        """
        return _openmm.AmoebaVdwForce_getUseDispersionCorrection(self)

    def setUseDispersionCorrection(self, useCorrection):
        r"""
        setUseDispersionCorrection(self, useCorrection)
        Set whether to add a contribution to the energy that approximately represents the effect of VdW interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding this contribution can improve the quality of results.
        """
        return _openmm.AmoebaVdwForce_setUseDispersionCorrection(self, useCorrection)

    def getUseParticleTypes(self):
        r"""
        getUseParticleTypes(self) -> bool
        Get whether parameters were specified by particle or by particle type.
        """
        return _openmm.AmoebaVdwForce_getUseParticleTypes(self)

    def setParticleExclusions(self, particleIndex, exclusions):
        r"""
        setParticleExclusions(self, particleIndex, exclusions)
        Set exclusions for specified particle

        Parameters
        ----------
        particleIndex : int
            particle index
        exclusions : vector< int >
            vector of exclusions
        """
        return _openmm.AmoebaVdwForce_setParticleExclusions(self, particleIndex, exclusions)

    def getParticleExclusions(self, particleIndex):
        r"""
        getParticleExclusions(self, particleIndex)
        Get exclusions for specified particle

        Parameters
        ----------
        particleIndex : int
            particle index

        Returns
        -------
        exclusions : vector< int >
            vector of exclusions
        """
        return _openmm.AmoebaVdwForce_getParticleExclusions(self, particleIndex)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.AmoebaVdwForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.AmoebaVdwForce_setCutoffDistance(self, distance)

    def setCutoff(self, cutoff):
        r"""
        setCutoff(self, cutoff)
        Set the cutoff distance.

         @deprecated This method exists only for backward compatibility. Use setCutoffDistance() instead.
        """
        return _openmm.AmoebaVdwForce_setCutoff(self, cutoff)

    def getCutoff(self):
        r"""
        getCutoff(self) -> double
        Get the cutoff distance.

         @deprecated This method exists only for backward compatibility. Use getCutoffDistance() instead.
        """
        val = _openmm.AmoebaVdwForce_getCutoff(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::AmoebaVdwForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.AmoebaVdwForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.AmoebaVdwForce_setNonbondedMethod(self, method)

    def getPotentialFunction(self):
        r"""
        getPotentialFunction(self) -> OpenMM::AmoebaVdwForce::PotentialFunction
        Get the potential function to use.
        """
        return _openmm.AmoebaVdwForce_getPotentialFunction(self)

    def setPotentialFunction(self, potential):
        r"""
        setPotentialFunction(self, potential)
        Set the potential function to use.
        """
        return _openmm.AmoebaVdwForce_setPotentialFunction(self, potential)

    def setSoftcorePower(self, n):
        r"""
        setSoftcorePower(self, n)
        Set the softcore power on lambda (default = 5).
        """
        return _openmm.AmoebaVdwForce_setSoftcorePower(self, n)

    def getSoftcorePower(self):
        r"""
        getSoftcorePower(self) -> int
        Get the softcore power on lambda.
        """
        return _openmm.AmoebaVdwForce_getSoftcorePower(self)

    def setSoftcoreAlpha(self, alpha):
        r"""
        setSoftcoreAlpha(self, alpha)
        Set the softcore alpha value (default = 0.7).
        """
        return _openmm.AmoebaVdwForce_setSoftcoreAlpha(self, alpha)

    def getSoftcoreAlpha(self):
        r"""
        getSoftcoreAlpha(self) -> double
        Get the softcore alpha value.
        """
        return _openmm.AmoebaVdwForce_getSoftcoreAlpha(self)

    def getAlchemicalMethod(self):
        r"""
        getAlchemicalMethod(self) -> OpenMM::AmoebaVdwForce::AlchemicalMethod
        Get the method used for alchemical interactions.
        """
        return _openmm.AmoebaVdwForce_getAlchemicalMethod(self)

    def setAlchemicalMethod(self, method):
        r"""
        setAlchemicalMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.AmoebaVdwForce_setAlchemicalMethod(self, method)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-particle parameters. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context.
        """
        return _openmm.AmoebaVdwForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.AmoebaVdwForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaVdwForce
        __init__(self, other) -> AmoebaVdwForce
        Create an Amoeba VdwForce.
        """
        _openmm.AmoebaVdwForce_swiginit(self, _openmm.new_AmoebaVdwForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaVdwForce

# Register AmoebaVdwForce in _openmm:
_openmm.AmoebaVdwForce_swigregister(AmoebaVdwForce)

def AmoebaVdwForce_Lambda():
    r"""
    AmoebaVdwForce_Lambda() -> std::string const &
    This is the name of the parameter which stores the current Amoeba vdW lambda value.
    """
    return _openmm.AmoebaVdwForce_Lambda()

class AmoebaWcaDispersionForce(Force):
    r"""
    This class implements a nonbonded interaction between pairs of particles typically used along with AmoebaGeneralizedKirkwoodForce as part of an implicit solvent model.

    To use it, create an AmoebaWcaDispersionForce object then call addParticle() once for each particle. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles
        """
        return _openmm.AmoebaWcaDispersionForce_getNumParticles(self)

    def setParticleParameters(self, particleIndex, radius, epsilon):
        r"""
        setParticleParameters(self, particleIndex, radius, epsilon)
        Set the force field parameters for a WCA dispersion particle.

        Parameters
        ----------
        particleIndex : int
            the particle index
        radius : double
            radius
        epsilon : double
            epsilon
        """
        return _openmm.AmoebaWcaDispersionForce_setParticleParameters(self, particleIndex, radius, epsilon)

    def getParticleParameters(self, particleIndex):
        r"""
        getParticleParameters(self, particleIndex)
        Get the force field parameters for a WCA dispersion particle.

        Parameters
        ----------
        particleIndex : int
            the particle index

        Returns
        -------
        radius : double
            radius
        epsilon : double
            epsilon
        """
        val = _openmm.AmoebaWcaDispersionForce_getParticleParameters(self, particleIndex)

        val[0]=unit.Quantity(val[0], unit.nanometer)
        val[1]=unit.Quantity(val[1], unit.kilojoule_per_mole)


        return val


    def addParticle(self, radius, epsilon):
        r"""
        addParticle(self, radius, epsilon) -> int
        Set the force field parameters for a WCA dispersion particle.

        Parameters
        ----------
        radius : double
            radius
        epsilon : double
            epsilon

        Returns
        -------
        int
            index of added particle
        """
        return _openmm.AmoebaWcaDispersionForce_addParticle(self, radius, epsilon)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-particle parameters. All other aspects of the Force are unaffected and can only be changed by reinitializing the Context.
        """
        return _openmm.AmoebaWcaDispersionForce_updateParametersInContext(self, context)

    def getEpso(self):
        r"""getEpso(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getEpso(self)

        val=unit.Quantity(val, unit.kilojoule_per_mole)


        return val


    def getEpsh(self):
        r"""getEpsh(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getEpsh(self)

        val=unit.Quantity(val, unit.kilojoule_per_mole)


        return val


    def getRmino(self):
        r"""getRmino(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getRmino(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def getRminh(self):
        r"""getRminh(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getRminh(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def getAwater(self):
        r"""getAwater(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getAwater(self)

        val=unit.Quantity(val, 1/(unit.nanometer*unit.nanometer*unit.nanometer))


        return val


    def getShctd(self):
        r"""getShctd(self) -> double"""
        return _openmm.AmoebaWcaDispersionForce_getShctd(self)

    def getDispoff(self):
        r"""getDispoff(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getDispoff(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def getSlevy(self):
        r"""getSlevy(self) -> double"""
        return _openmm.AmoebaWcaDispersionForce_getSlevy(self)

    def setEpso(self, inputValue):
        r"""setEpso(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setEpso(self, inputValue)

    def setEpsh(self, inputValue):
        r"""setEpsh(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setEpsh(self, inputValue)

    def setRmino(self, inputValue):
        r"""setRmino(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setRmino(self, inputValue)

    def setRminh(self, inputValue):
        r"""setRminh(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setRminh(self, inputValue)

    def setAwater(self, inputValue):
        r"""setAwater(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setAwater(self, inputValue)

    def setShctd(self, inputValue):
        r"""setShctd(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setShctd(self, inputValue)

    def setDispoff(self, inputValue):
        r"""setDispoff(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setDispoff(self, inputValue)

    def setSlevy(self, inputValue):
        r"""setSlevy(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setSlevy(self, inputValue)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.AmoebaWcaDispersionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> AmoebaWcaDispersionForce
        __init__(self, other) -> AmoebaWcaDispersionForce
        Create an AmoebaWcaDispersionForce.
        """
        _openmm.AmoebaWcaDispersionForce_swiginit(self, _openmm.new_AmoebaWcaDispersionForce(*args))
    __swig_destroy__ = _openmm.delete_AmoebaWcaDispersionForce

# Register AmoebaWcaDispersionForce in _openmm:
_openmm.AmoebaWcaDispersionForce_swigregister(AmoebaWcaDispersionForce)

class AndersenThermostat(Force):
    r"""This class uses the Andersen method to maintain constant temperature."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    @staticmethod
    def Temperature():
        r"""
        Temperature() -> std::string const &
        This is the name of the parameter which stores the current temperature of the heat bath (in Kelvin).
        """
        return _openmm.AndersenThermostat_Temperature()

    @staticmethod
    def CollisionFrequency():
        r"""
        CollisionFrequency() -> std::string const &
        This is the name of the parameter which store the current collision frequency (in 1/ps).
        """
        return _openmm.AndersenThermostat_CollisionFrequency()

    def getDefaultTemperature(self):
        r"""
        getDefaultTemperature(self) -> double
        Get the default temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the default temperature of the heat bath, measured in Kelvin.
        """
        val = _openmm.AndersenThermostat_getDefaultTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setDefaultTemperature(self, temperature):
        r"""
        setDefaultTemperature(self, temperature)
        Set the default temperature of the heat bath. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temperature : double
            the default temperature of the heat bath (in Kelvin)
        """

        if unit.is_quantity(temperature):
            temperature = temperature.value_in_unit(unit.kelvin)


        return _openmm.AndersenThermostat_setDefaultTemperature(self, temperature)


    def getDefaultCollisionFrequency(self):
        r"""
        getDefaultCollisionFrequency(self) -> double
        Get the default collision frequency (in 1/ps).

        Returns
        -------
        double
            the default collision frequency, measured in 1/ps.
        """
        val = _openmm.AndersenThermostat_getDefaultCollisionFrequency(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setDefaultCollisionFrequency(self, frequency):
        r"""
        setDefaultCollisionFrequency(self, frequency)
        Set the default collision frequency. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        frequency : double
            the default collision frequency (in 1/ps)
        """
        return _openmm.AndersenThermostat_setDefaultCollisionFrequency(self, frequency)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.AndersenThermostat_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of collisions will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.AndersenThermostat_setRandomNumberSeed(self, seed)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.AndersenThermostat_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, defaultTemperature, defaultCollisionFrequency) -> AndersenThermostat
        __init__(self, other) -> AndersenThermostat
        Create an AndersenThermostat.

        Parameters
        ----------
        defaultTemperature : double
            the default temperature of the heat bath (in Kelvin)
        defaultCollisionFrequency : double
            the default collision frequency (in 1/ps)
        """
        _openmm.AndersenThermostat_swiginit(self, _openmm.new_AndersenThermostat(*args))
    __swig_destroy__ = _openmm.delete_AndersenThermostat

# Register AndersenThermostat in _openmm:
_openmm.AndersenThermostat_swigregister(AndersenThermostat)

def AndersenThermostat_Temperature():
    r"""
    AndersenThermostat_Temperature() -> std::string const &
    This is the name of the parameter which stores the current temperature of the heat bath (in Kelvin).
    """
    return _openmm.AndersenThermostat_Temperature()

def AndersenThermostat_CollisionFrequency():
    r"""
    AndersenThermostat_CollisionFrequency() -> std::string const &
    This is the name of the parameter which store the current collision frequency (in 1/ps).
    """
    return _openmm.AndersenThermostat_CollisionFrequency()

class Integrator(object):
    r"""
    An Integrator defines a method for simulating a System by integrating the equations of motion. This is an abstract class. Subclasses define particular integration methods.

    Each Integrator object is bound to a particular Context which it integrates. This connection is specified by passing the Integrator as an argument to the constructor of the Context.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_Integrator

    def getStepSize(self):
        r"""
        getStepSize(self) -> double
        Get the size of each time step, in picoseconds. If this integrator uses variable time steps, the size of the most recent step is returned.

        Returns
        -------
        double
            the step size, measured in ps
        """
        val = _openmm.Integrator_getStepSize(self)

        val=unit.Quantity(val, unit.picosecond)


        return val


    def setStepSize(self, size):
        r"""
        setStepSize(self, size)
        Set the size of each time step, in picoseconds. If this integrator uses variable time steps, the effect of calling this method is undefined, and it may simply be ignored.

        Parameters
        ----------
        size : double
            the step size, measured in ps
        """
        return _openmm.Integrator_setStepSize(self, size)

    def getConstraintTolerance(self):
        r"""
        getConstraintTolerance(self) -> double
        Get the distance tolerance within which constraints are maintained, as a fraction of the constrained distance.
        """
        return _openmm.Integrator_getConstraintTolerance(self)

    def setConstraintTolerance(self, tol):
        r"""
        setConstraintTolerance(self, tol)
        Set the distance tolerance within which constraints are maintained, as a fraction of the constrained distance.
        """
        return _openmm.Integrator_setConstraintTolerance(self, tol)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.Integrator_step(self, steps)

    def getIntegrationForceGroups(self):
        r"""
        getIntegrationForceGroups(self) -> int
        Get which force groups to use for integration. By default, all force groups are included. This is interpreted as a set of bit flags: the forces from group i will be included if (groups&(1<<i)) != 0.
        """
        return _openmm.Integrator_getIntegrationForceGroups(self)

    def setIntegrationForceGroups(self, groups):
        r"""
        setIntegrationForceGroups(self, groups)
        Set which force groups to use for integration. By default, all force groups are included. This is interpreted as a set of bit flags: the forces from group i will be included if (groups&(1<<i)) != 0.
        """
        return _openmm.Integrator_setIntegrationForceGroups(self, groups)

    def setIntegrationForceGroups(self, groups):
        """Set which force groups to use for integration.  By default, all force groups are included.

        Parameters
        ----------
        groups : set or int
            a set of indices for which force groups to include when integrating the equations of motion.
            Alternatively, the groups can be passed as a single unsigned integer interpreted as a bitmask,
            in which case group i will be included if (groups&(1<<i)) != 0.
        """
        try:
    # is the input integer-like?
            groups_mask = int(groups)
        except TypeError:
            if isinstance(groups, set):
                groups_mask = functools.reduce(operator.or_,
                        ((1<<x) & 0xffffffff for x in groups))
            else:
                raise TypeError('%s is neither an int nor set' % groups)
        if groups_mask >= 0x80000000:
            groups_mask -= 0x100000000
        _openmm.Integrator_setIntegrationForceGroups(self, groups_mask)


    def __getstate__(self):
        serializationString = XmlSerializer.serialize(self)
        return serializationString

    def __setstate__(self, serializationString):
        system = XmlSerializer.deserialize(serializationString)
        self.this = system.this

    def __deepcopy__(self, memo):
        return self.__copy__()


    def __copy__(self):
        r"""__copy__(self) -> Integrator"""
        return _openmm.Integrator___copy__(self)

# Register Integrator in _openmm:
_openmm.Integrator_swigregister(Integrator)

class BrownianIntegrator(Integrator):
    r"""This is an Integrator which simulates a System using Brownian dynamics."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath (in Kelvin).
        """
        val = _openmm.BrownianIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin.
        """
        return _openmm.BrownianIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.BrownianIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.BrownianIntegrator_setFriction(self, coeff)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.BrownianIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.BrownianIntegrator_setRandomNumberSeed(self, seed)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.BrownianIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, frictionCoeff, stepSize) -> BrownianIntegrator
        __init__(self, other) -> BrownianIntegrator
        Create a BrownianIntegrator.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the heat bath, measured in 1/ps
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        """
        _openmm.BrownianIntegrator_swiginit(self, _openmm.new_BrownianIntegrator(*args))
    __swig_destroy__ = _openmm.delete_BrownianIntegrator

# Register BrownianIntegrator in _openmm:
_openmm.BrownianIntegrator_swigregister(BrownianIntegrator)

class CMAPTorsionForce(Force):
    r"""
    This class implements an interaction between pairs of dihedral angles. The interaction energy is defined by an "energy correction map" (CMAP), which is simply a set of tabulated energy values on a regular grid of (phi, psi) angles. Natural cubic spline interpolation is used to compute forces and energies at arbitrary values of the two angles.

    To use this class, first create one or more energy correction maps by calling addMap(). For each one, you provide an array of energies at uniformly spaced values of the two angles. Next, add interactions by calling addTorsion(). For each one, you specify the sequence of particles used to calculate each of the two dihedral angles, and the index of the map used to calculate their interaction energy.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumMaps(self):
        r"""
        getNumMaps(self) -> int
        Get the number of maps that have been defined.
        """
        return _openmm.CMAPTorsionForce_getNumMaps(self)

    def getNumTorsions(self):
        r"""
        getNumTorsions(self) -> int
        Get the number of CMAP torsion terms in the potential function
        """
        return _openmm.CMAPTorsionForce_getNumTorsions(self)

    def addMap(self, size, energy):
        r"""
        addMap(self, size, energy) -> int
        Create a new map that can be used for torsion pairs.

        Parameters
        ----------
        size : int
            the size of the map along each dimension
        energy : vector< double >
            the energy values for the map. This must be of length size*size. The element energy[i+size*j] contains the energy when the first torsion angle equals i*2*PI/size and the second torsion angle equals j*2*PI/size.

        Returns
        -------
        int
            the index of the map that was added
        """
        return _openmm.CMAPTorsionForce_addMap(self, size, energy)

    def getMapParameters(self, index):
        r"""
        getMapParameters(self, index)
        Get the energy values of a map.

        Parameters
        ----------
        index : int
            the index of the map for which to get energy values

        Returns
        -------
        size : int
            the size of the map along each dimension
        energy : vector< double >
            the energy values for the map. This must be of length size*size. The element energy[i+size*j] contains the energy when the first torsion angle equals i*2*PI/size and the second torsion angle equals j*2*PI/size.
        """
        val = _openmm.CMAPTorsionForce_getMapParameters(self, index)

        val[1]=unit.Quantity(val[1], unit.kilojoule_per_mole)


        return val


    def setMapParameters(self, index, size, energy):
        r"""
        setMapParameters(self, index, size, energy)
        Set the energy values of a map.

        Parameters
        ----------
        index : int
            the index of the map for which to set energy values
        size : int
            the size of the map along each dimension
        energy : vector< double >
            the energy values for the map. This must be of length size*size. The element energy[i+size*j] contains the energy when the first torsion angle equals i*2*PI/size and the second torsion angle equals j*2*PI/size.
        """
        return _openmm.CMAPTorsionForce_setMapParameters(self, index, size, energy)

    def addTorsion(self, map, a1, a2, a3, a4, b1, b2, b3, b4):
        r"""
        addTorsion(self, map, a1, a2, a3, a4, b1, b2, b3, b4) -> int
        Add a CMAP torsion term to the force field.

        Parameters
        ----------
        map : int
            the index of the map to use for this term
        a1 : int
            the index of the first particle forming the first torsion
        a2 : int
            the index of the second particle forming the first torsion
        a3 : int
            the index of the third particle forming the first torsion
        a4 : int
            the index of the fourth particle forming the first torsion
        b1 : int
            the index of the first particle forming the second torsion
        b2 : int
            the index of the second particle forming the second torsion
        b3 : int
            the index of the third particle forming the second torsion
        b4 : int
            the index of the fourth particle forming the second torsion

        Returns
        -------
        int
            the index of the torsion that was added
        """
        return _openmm.CMAPTorsionForce_addTorsion(self, map, a1, a2, a3, a4, b1, b2, b3, b4)

    def getTorsionParameters(self, index):
        r"""
        getTorsionParameters(self, index)
        Get the force field parameters for a CMAP torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to get parameters

        Returns
        -------
        map : int
            the index of the map to use for this term
        a1 : int
            the index of the first particle forming the first torsion
        a2 : int
            the index of the second particle forming the first torsion
        a3 : int
            the index of the third particle forming the first torsion
        a4 : int
            the index of the fourth particle forming the first torsion
        b1 : int
            the index of the first particle forming the second torsion
        b2 : int
            the index of the second particle forming the second torsion
        b3 : int
            the index of the third particle forming the second torsion
        b4 : int
            the index of the fourth particle forming the second torsion
        """
        return _openmm.CMAPTorsionForce_getTorsionParameters(self, index)

    def setTorsionParameters(self, index, map, a1, a2, a3, a4, b1, b2, b3, b4):
        r"""
        setTorsionParameters(self, index, map, a1, a2, a3, a4, b1, b2, b3, b4)
        Set the force field parameters for a CMAP torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to set parameters
        map : int
            the index of the map to use for this term
        a1 : int
            the index of the first particle forming the first torsion
        a2 : int
            the index of the second particle forming the first torsion
        a3 : int
            the index of the third particle forming the first torsion
        a4 : int
            the index of the fourth particle forming the first torsion
        b1 : int
            the index of the first particle forming the second torsion
        b2 : int
            the index of the second particle forming the second torsion
        b3 : int
            the index of the third particle forming the second torsion
        b4 : int
            the index of the fourth particle forming the second torsion
        """
        return _openmm.CMAPTorsionForce_setTorsionParameters(self, index, map, a1, a2, a3, a4, b1, b2, b3, b4)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the map and torsion parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setMapParameters() and setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information that can be updated with this method is the energy values for a map, and the map index for a torsion. The size of a map and the set of particles involved in a torsion cannot be changed. Also, new bonds and torsions cannot be added.
        """
        return _openmm.CMAPTorsionForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CMAPTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CMAPTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> CMAPTorsionForce
        __init__(self, other) -> CMAPTorsionForce
        Create a CMAPTorsionForce.
        """
        _openmm.CMAPTorsionForce_swiginit(self, _openmm.new_CMAPTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_CMAPTorsionForce

# Register CMAPTorsionForce in _openmm:
_openmm.CMAPTorsionForce_swigregister(CMAPTorsionForce)

class CMMotionRemover(Force):
    r"""This class prevents the center of mass of a System from drifting. At each time step, it calculates the center of mass momentum, then adjusts the individual particle velocities to make it zero."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getFrequency(self):
        r"""
        getFrequency(self) -> int
        Get the frequency (in time steps) at which center of mass motion should be removed
        """
        return _openmm.CMMotionRemover_getFrequency(self)

    def setFrequency(self, freq):
        r"""
        setFrequency(self, freq)
        Set the frequency (in time steps) at which center of mass motion should be removed
        """
        return _openmm.CMMotionRemover_setFrequency(self, freq)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CMMotionRemover_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, frequency=1) -> CMMotionRemover
        __init__(self, other) -> CMMotionRemover
        Create a CMMotionRemover.
        """
        _openmm.CMMotionRemover_swiginit(self, _openmm.new_CMMotionRemover(*args))
    __swig_destroy__ = _openmm.delete_CMMotionRemover

# Register CMMotionRemover in _openmm:
_openmm.CMMotionRemover_swigregister(CMMotionRemover)

class CompoundIntegrator(Integrator):
    r"""
    This class allows you to use multiple integration algorithms within a single simulation, switching back and forth between them. To use it, create whatever other Integrators you need, then add all of them to a CustomIntegrator:

    <tt><pre>
    CompoundIntegrator compoundIntegrator;
    compoundIntegrator.addIntegrator(new VerletIntegrator(0.001));
    compoundIntegrator.addIntegrator(new LangevinIntegrator(300.0, 1.0, 0.001));
    </pre></tt>

    Next create a Context, specifying the CompoundIntegrator as the Integrator to use for the Context:

    <tt><pre>
    Context context(system, compoundIntegrator);
    </pre></tt>

    Finally, call setCurrentIntegrator() to set which Integrator is active. That one will be used for all calls to step() until the next time you change it.

    <tt><pre>
    compoundIntegrator.setCurrentIntegrator(0);
    compoundIntegrator.step(1000); // Take 1000 steps of Verlet dynamics
    compoundIntegrator.setCurrentIntegrator(1);
    compoundIntegrator.step(1000); // Take 1000 steps of Langevin dynamics
    </pre></tt>

    When switching between integrators, it is important to make sure they are compatible with each other, and that they will interpret the positions and velocities in the same way. Remember that leapfrog style integrators assume the positions and velocities are offset from each other by half a time step. When switching between a leapfrog and non-leapfrog integrator, you must first adjust the velocities to avoid introducing error. This is also true when switching between two leapfrog integrators that use different step sizes, since they will interpret the velocities as corresponding to different times.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CompoundIntegrator

    def getNumIntegrators(self):
        r"""
        getNumIntegrators(self) -> int
        Get the number of Integrators that have been added to this CompoundIntegrator.
        """
        return _openmm.CompoundIntegrator_getNumIntegrators(self)

    def addIntegrator(self, integrator):
        r"""
        addIntegrator(self, integrator) -> int
        Add an Integrator to this CompoundIntegrator. The Integrator object should have been created on the heap with the "new" operator. The CompoundIntegrator takes over ownership of it, and deletes it when the CompoundIntegrator itself is deleted. All Integrators must be added before the Context is created.

        Parameters
        ----------
        integrator : Integrator *
            the Integrator to add

        Returns
        -------
        int
            the index of the Integrator that was added
        """

        if not integrator.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CompoundIntegrator_addIntegrator(self, integrator)

        integrator.thisown=0


        return val


    def getIntegrator(self, *args):
        r"""
        getIntegrator(self, index) -> Integrator
        getIntegrator(self, index) -> Integrator
        Get a const reference to one of the Integrators that have been added to this CompoundIntegrator.

        Parameters
        ----------
        index : int
            the index of the Integrator to get
        """
        return _openmm.CompoundIntegrator_getIntegrator(self, *args)

    def getCurrentIntegrator(self):
        r"""
        getCurrentIntegrator(self) -> int
        Get the index of the current Integrator.
        """
        return _openmm.CompoundIntegrator_getCurrentIntegrator(self)

    def setCurrentIntegrator(self, index):
        r"""
        setCurrentIntegrator(self, index)
        Set the current Integrator.

        Parameters
        ----------
        index : int
            the index of the Integrator to use
        """
        return _openmm.CompoundIntegrator_setCurrentIntegrator(self, index)

    def getStepSize(self):
        r"""
        getStepSize(self) -> double
        Get the size of each time step, in picoseconds. This method calls getStepSize() on whichever Integrator has been set as current.

        Returns
        -------
        double
            the step size, measured in ps
        """
        val = _openmm.CompoundIntegrator_getStepSize(self)

        val=unit.Quantity(val, unit.picosecond)


        return val


    def setStepSize(self, size):
        r"""
        setStepSize(self, size)
        Set the size of each time step, in picoseconds. This method calls setStepSize() on whichever Integrator has been set as current.

        Parameters
        ----------
        size : double
            the step size, measured in ps
        """
        return _openmm.CompoundIntegrator_setStepSize(self, size)

    def getConstraintTolerance(self):
        r"""
        getConstraintTolerance(self) -> double
        Get the distance tolerance within which constraints are maintained, as a fraction of the constrained distance. This method calls getConstraintTolerance() on whichever Integrator has been set as current.
        """
        return _openmm.CompoundIntegrator_getConstraintTolerance(self)

    def setConstraintTolerance(self, tol):
        r"""
        setConstraintTolerance(self, tol)
        Set the distance tolerance within which constraints are maintained, as a fraction of the constrained distance. This method calls setConstraintTolerance() on whichever Integrator has been set as current.
        """
        return _openmm.CompoundIntegrator_setConstraintTolerance(self, tol)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps. This method calls step() on whichever Integrator has been set as current.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.CompoundIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self) -> CompoundIntegrator
        __init__(self, other) -> CompoundIntegrator
        Create a CompoundIntegrator.
        """
        _openmm.CompoundIntegrator_swiginit(self, _openmm.new_CompoundIntegrator(*args))

# Register CompoundIntegrator in _openmm:
_openmm.CompoundIntegrator_swigregister(CompoundIntegrator)

class Context(object):
    r"""
    A Context stores the complete state of a simulation. More specifically, it includes:

     - The current time
     - The position of each particle
     - The velocity of each particle
     - The values of configurable parameters defined by Force objects in the System

    You can retrieve a snapshot of the current state at any time by calling getState(). This allows you to record the state of the simulation at various points, either for analysis or for checkpointing. getState() can also be used to retrieve the current forces on each particle and the current energy of the System.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_Context

    def getSystem(self):
        r"""
        getSystem(self) -> System
        Get System being simulated in this context.
        """
        return _openmm.Context_getSystem(self)

    def getPlatform(self, *args):
        r"""
        getPlatform(self) -> Platform
        getPlatform(self) -> Platform
        Get the Platform being used for calculations.
        """
        return _openmm.Context_getPlatform(self, *args)

    def getState(self, *args):
        r"""
        getState(self, types, enforcePeriodicBox=False, groups=0xFFFFFFFF) -> State
        Get a State object recording the current state information stored in this context.

        Parameters
        ----------
        types : int
            the set of data types which should be stored in the State object. This should be a union of DataType values, e.g. (State::Positions | State::Velocities).
        enforcePeriodicBox : bool
            if false, the position of each particle will be whatever position is stored in the Context, regardless of periodic boundary conditions. If true, particle positions will be translated so the center of every molecule lies in the same periodic box.
        groups : int
            a set of bit flags for which force groups to include when computing forces and energies. Group i will be included if (groups&(1<<i)) != 0. The default value includes all groups.
        """
        return _openmm.Context_getState(self, *args)

    def setState(self, state):
        r"""
        setState(self, state)
        Copy information from a State object into this Context. This restores the Context to approximately the same state it was in when the State was created. If the State does not include a piece of information (e.g. positions or velocities), that aspect of the Context is left unchanged.

        Even when all possible information is included in the State, the effect of calling this method is still less complete than loadCheckpoint(). For example, it does not restore the internal states of random number generators. On the other hand, it has the advantage of not being hardware specific.
        """
        return _openmm.Context_setState(self, state)

    def setTime(self, time):
        r"""
        setTime(self, time)
        Set the current time of the simulation (in picoseconds).
        """
        return _openmm.Context_setTime(self, time)

    def setPositions(self, positions):
        r"""
        setPositions(self, positions)
        Set the positions of all particles in the System (measured in nm). This method simply sets the positions without checking to see whether they satisfy distance constraints. If you want constraints to be enforced, call applyConstraints() after setting the positions.

        Parameters
        ----------
        positions : vector< Vec3 >
            a vector whose length equals the number of particles in the System. The i'th element contains the position of the i'th particle.
        """
        return _openmm.Context_setPositions(self, positions)

    def setVelocities(self, velocities):
        r"""
        setVelocities(self, velocities)
        Set the velocities of all particles in the System (measured in nm/picosecond).

        Parameters
        ----------
        velocities : vector< Vec3 >
            a vector whose length equals the number of particles in the System. The i'th element contains the velocity of the i'th particle.
        """
        return _openmm.Context_setVelocities(self, velocities)

    def setVelocitiesToTemperature(self, *args):
        r"""
        setVelocitiesToTemperature(self, temperature, randomSeed=osrngseed())
        Set the velocities of all particles in the System to random values chosen from a Boltzmann distribution at a given temperature.

        Parameters
        ----------
        temperature : double
            the temperature for which to select the velocities (measured in Kelvin)
        randomSeed : int
            the random number seed to use when selecting velocities
        """
        return _openmm.Context_setVelocitiesToTemperature(self, *args)

    def getParameters(self):
        r"""
        getParameters(self) -> mapstringdouble
        Get all adjustable parameters that have been defined by Force objects in the System, along with their current values.
        """
        return _openmm.Context_getParameters(self)

    def getParameter(self, name):
        r"""
        getParameter(self, name) -> double
        Get the value of an adjustable parameter defined by a Force object in the System.

        Parameters
        ----------
        name : string
            the name of the parameter to get
        """
        return _openmm.Context_getParameter(self, name)

    def setParameter(self, name, value):
        r"""
        setParameter(self, name, value)
        Set the value of an adjustable parameter defined by a Force object in the System.

        Parameters
        ----------
        name : string
            the name of the parameter to set
        value : double
            the value of the parameter
        """
        return _openmm.Context_setParameter(self, name, value)

    def setPeriodicBoxVectors(self, a, b, c):
        r"""
        setPeriodicBoxVectors(self, a, b, c)
        Set the vectors defining the axes of the periodic box (measured in nm). They will affect any Force that uses periodic boundary conditions.

        Triclinic boxes are supported, but the vectors must satisfy certain requirements. In particular, a must point in the x direction, b must point "mostly" in the y direction, and c must point "mostly" in the z direction. See the documentation for details.

        Parameters
        ----------
        a : Vec3
            the vector defining the first edge of the periodic box
        b : Vec3
            the vector defining the second edge of the periodic box
        c : Vec3
            the vector defining the third edge of the periodic box
        """
        return _openmm.Context_setPeriodicBoxVectors(self, a, b, c)

    def applyConstraints(self, tol):
        r"""
        applyConstraints(self, tol)
        Update the positions of particles so that all distance constraints are satisfied. This also recomputes the locations of all virtual sites.

        Parameters
        ----------
        tol : double
            the distance tolerance within which constraints must be satisfied.
        """
        return _openmm.Context_applyConstraints(self, tol)

    def applyVelocityConstraints(self, tol):
        r"""
        applyVelocityConstraints(self, tol)
        Update the velocities of particles so the net velocity of each constrained distance is zero.

        Parameters
        ----------
        tol : double
            the velocity tolerance within which constraints must be satisfied.
        """
        return _openmm.Context_applyVelocityConstraints(self, tol)

    def computeVirtualSites(self):
        r"""
        computeVirtualSites(self)
        Recompute the locations of all virtual sites. There is rarely a reason to call this, since virtual sites are also updated by applyConstraints(). This is only for the rare situations when you want to enforce virtual sites but <i>not</i> constraints.
        """
        return _openmm.Context_computeVirtualSites(self)

    def reinitialize(self, preserveState=False):
        r"""
        reinitialize(self, preserveState=False)
        When a Context is created, it caches information about the System being simulated and the Force objects contained in it. This means that, if the System or Forces are then modified, the Context does not see the changes. Call reinitialize() to force the Context to rebuild its internal representation of the System and pick up any changes that have been made.

        This is an expensive operation, so you should try to avoid calling it too frequently. Most Force classes have an updateParametersInContext() method that provides a less expensive way of updating certain types of information. However, this method is the only way to make some types of changes, so it is sometimes necessary to call it.

        By default, reinitializing a Context causes all state information (positions, velocities, etc.) to be discarded. You can optionally tell it to try to preserve state information. It does this by internally creating a checkpoint, then reinitializing the Context, then loading the checkpoint. Be aware that if the System has changed in a way that prevents the checkpoint from being loaded (such as changing the number of particles), this will throw an exception and the state information will be lost.
        """
        return _openmm.Context_reinitialize(self, preserveState)

    def getMolecules(self):
        r"""
        getMolecules(self) -> vectorii
        Get a description of how the particles in the system are grouped into molecules. Two particles are in the same molecule if they are connected by constraints or bonds, where every Force object can define bonds in whatever way are appropriate to that force.

        Each element lists the indices of all particles in a single molecule. Every particle is guaranteed to belong to exactly one molecule.
        """
        return _openmm.Context_getMolecules(self)

    def getIntegrator(self):
        return self._integrator

    def getState(self, getPositions=False, getVelocities=False,
                 getForces=False, getEnergy=False, getParameters=False,
                 getParameterDerivatives=False, getIntegratorParameters=False,
                 enforcePeriodicBox=False, groups=-1):
        """Get a State object recording the current state information stored in this context.

        Parameters
        ----------
        getPositions : bool=False
            whether to store particle positions in the State
        getVelocities : bool=False
            whether to store particle velocities in the State
        getForces : bool=False
            whether to store the forces acting on particles in the State
        getEnergy : bool=False
            whether to store potential and kinetic energy in the State
        getParameters : bool=False
            whether to store context parameters in the State
        getParameterDerivatives : bool=False
            whether to store parameter derivatives in the State
        getIntegratorParameters : bool=False
            whether to store integrator parameters in the State
        enforcePeriodicBox : bool=False
            if false, the position of each particle will be whatever position
            is stored in the Context, regardless of periodic boundary conditions.
            If true, particle positions will be translated so the center of
            every molecule lies in the same periodic box.
        groups : set={0,1,2,...,31}
            a set of indices for which force groups to include when computing
            forces and energies. The default value includes all groups. groups
            can also be passed as an unsigned integer interpreted as a bitmask,
            in which case group i will be included if (groups&(1<<i)) != 0.
        """
        try:
    # is the input integer-like?
            groups_mask = int(groups)
        except TypeError:
            if isinstance(groups, set):
    # nope, okay, then it should be an set
                groups_mask = functools.reduce(operator.or_,
                        ((1<<x) & 0xffffffff for x in groups))
            else:
                raise TypeError('%s is neither an int nor set' % groups)
        if groups_mask >= 0x80000000:
            groups_mask -= 0x100000000
        types = 0
        if getPositions:
            types += State.Positions
        if getVelocities:
            types += State.Velocities
        if getForces:
            types += State.Forces
        if getEnergy:
            types += State.Energy
        if getParameters:
            types += State.Parameters
        if getParameterDerivatives:
            types += State.ParameterDerivatives
        if getIntegratorParameters:
            types += State.IntegratorParameters
        state = _openmm.Context_getState(self, types, enforcePeriodicBox, groups_mask)
        return state



    def createCheckpoint(self):
        r"""
        createCheckpoint(self) -> std::string
        Create a checkpoint recording the current state of the Context.
        This should be treated as an opaque block of binary data.  See loadCheckpoint() for more details.

        Returns: a string containing the checkpoint data

        """
        return _openmm.Context_createCheckpoint(self)

    def loadCheckpoint(self, checkpoint):
        r"""
        loadCheckpoint(self, checkpoint)
        Load a checkpoint that was written by createCheckpoint().

        A checkpoint contains not only publicly visible data such as the particle positions and
        velocities, but also internal data such as the states of random number generators.  Ideally,
        loading a checkpoint should restore the Context to an identical state to when it was written,
        such that continuing the simulation will produce an identical trajectory.  This is not strictly
        guaranteed to be true, however, and should not be relied on.  For most purposes, however, the
        internal state should be close enough to be reasonably considered equivalent.

        A checkpoint contains data that is highly specific to the Context from which it was created.
        It depends on the details of the System, the Platform being used, and the hardware and software
        of the computer it was created on.  If you try to load it on a computer with different hardware,
        or for a System that is different in any way, loading is likely to fail.  Checkpoints created
        with different versions of OpenMM are also often incompatible.  If a checkpoint cannot be loaded,
        that is signaled by throwing an exception.

        Parameters:
         - checkpoint (string) the checkpoint data to load

        """
        return _openmm.Context_loadCheckpoint(self, checkpoint)

    def __init__(self, *args):
        r"""
        __init__(self, system, integrator) -> Context
        __init__(self, system, integrator, platform) -> Context
        __init__(self, system, integrator, platform, properties) -> Context
        __init__(self, other) -> Context
        Construct a new Context in which to run a simulation, explicitly specifying what Platform should be used to perform calculations and the values of platform-specific properties.

        Parameters
        ----------
        system : System
            the System which will be simulated
        integrator : Integrator
            the Integrator which will be used to simulate the System
        platform : Platform
            the Platform to use for calculations
        properties : map< std::string, std::string >
            a set of values for platform-specific properties. Keys are the property names.
        """
        _openmm.Context_swiginit(self, _openmm.new_Context(*args))

        self._system = args[0]
        self._integrator = args[1]




# Register Context in _openmm:
_openmm.Context_swigregister(Context)

class TabulatedFunction(object):
    r"""
    A TabulatedFunction uses a set of tabulated values to define a mathematical function. It can be used by various custom forces.

    TabulatedFunction is an abstract class with concrete subclasses for more specific types of functions. There are subclasses for:

     - 1, 2, and 3 dimensional functions. The dimensionality of a function means the number of input arguments it takes.
     - Continuous and discrete functions. A continuous function is interpolated by fitting a natural cubic spline to the tabulated values. A discrete function is only defined for integer values of its arguments (that is, at the tabulated points), and does not try to interpolate between them. Discrete function can be evaluated more quickly than continuous ones.


    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_TabulatedFunction

    def Copy(self):
        r"""
        Copy(self) -> TabulatedFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.TabulatedFunction_Copy(self)

    def getPeriodic(self):
        r"""
        getPeriodic(self) -> bool
        Get the periodicity status of the tabulated function.
        """
        return _openmm.TabulatedFunction_getPeriodic(self)

    def __getstate__(self):
        serializationString = XmlSerializer.serialize(self)
        return serializationString

    def __setstate__(self, serializationString):
        system = XmlSerializer.deserialize(serializationString)
        self.this = system.this

    def __deepcopy__(self, memo):
        return self.__copy__()


    def __copy__(self):
        r"""__copy__(self) -> TabulatedFunction"""
        return _openmm.TabulatedFunction___copy__(self)

# Register TabulatedFunction in _openmm:
_openmm.TabulatedFunction_swigregister(TabulatedFunction)

class Continuous1DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a continuous one dimensional function."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, values, min, max, periodic=False):
        r"""
        __init__(self, values, min, max, periodic=False) -> Continuous1DFunction
        This is a TabulatedFunction that computes a continuous one dimensional function.
        """
        _openmm.Continuous1DFunction_swiginit(self, _openmm.new_Continuous1DFunction(values, min, max, periodic))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Continuous1DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, values, min, max):
        r"""setFunctionParameters(self, values, min, max)"""
        return _openmm.Continuous1DFunction_setFunctionParameters(self, values, min, max)

    def Copy(self):
        r"""
        Copy(self) -> Continuous1DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Continuous1DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Continuous1DFunction

# Register Continuous1DFunction in _openmm:
_openmm.Continuous1DFunction_swigregister(Continuous1DFunction)

class Continuous2DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a continuous two dimensional function."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, values, xmin, xmax, ymin, ymax, periodic=False):
        r"""
        __init__(self, xsize, ysize, values, xmin, xmax, ymin, ymax, periodic=False) -> Continuous2DFunction
        This is a TabulatedFunction that computes a continuous two dimensional function.
        """
        _openmm.Continuous2DFunction_swiginit(self, _openmm.new_Continuous2DFunction(xsize, ysize, values, xmin, xmax, ymin, ymax, periodic))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Continuous2DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax):
        r"""setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax)"""
        return _openmm.Continuous2DFunction_setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax)

    def Copy(self):
        r"""
        Copy(self) -> Continuous2DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Continuous2DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Continuous2DFunction

# Register Continuous2DFunction in _openmm:
_openmm.Continuous2DFunction_swigregister(Continuous2DFunction)

class Continuous3DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a continuous three dimensional function."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax, periodic=False):
        r"""
        __init__(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax, periodic=False) -> Continuous3DFunction
        This is a TabulatedFunction that computes a continuous three dimensional function.
        """
        _openmm.Continuous3DFunction_swiginit(self, _openmm.new_Continuous3DFunction(xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax, periodic))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Continuous3DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax):
        r"""setFunctionParameters(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax)"""
        return _openmm.Continuous3DFunction_setFunctionParameters(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax)

    def Copy(self):
        r"""
        Copy(self) -> Continuous3DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Continuous3DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Continuous3DFunction

# Register Continuous3DFunction in _openmm:
_openmm.Continuous3DFunction_swigregister(Continuous3DFunction)

class CustomAngleForce(Force):
    r"""
    This class implements interactions between sets of three particles that depend on the angle between them. Unlike HarmonicAngleForce, the functional form of the interaction is completely customizable, and may involve arbitrary algebraic expressions. In addition to the angle formed by the particles, it may depend on arbitrary global and per-angle parameters.

    To use this class, create a CustomAngleForce object, passing an algebraic expression to the constructor that defines the interaction energy between each set of particles. The expression may depend on theta, the angle formed by the particles, as well as on any parameters you choose. Then call addPerAngleParameter() to define per-angle parameters, and addGlobalParameter() to define global parameters. The values of per-angle parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter(). Finally, call addAngle() once for each angle. After an angle has been added, you can modify its parameters by calling setAngleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    As an example, the following code creates a CustomAngleForce that implements a harmonic potential:

    <tt>CustomAngleForce* force = new CustomAngleForce("0.5*k*(theta-theta0)^2");</tt>

    This force depends on two parameters: the spring constant k and equilibrium angle theta0. The following code defines these parameters:

    <tt><pre>
    force->addPerAngleParameter("k");
    force->addPerAngleParameter("theta0");
    </pre></tt>

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumAngles(self):
        r"""
        getNumAngles(self) -> int
        Get the number of angles for which force field parameters have been defined.
        """
        return _openmm.CustomAngleForce_getNumAngles(self)

    def getNumPerAngleParameters(self):
        r"""
        getNumPerAngleParameters(self) -> int
        Get the number of per-angle parameters that the interaction depends on.
        """
        return _openmm.CustomAngleForce_getNumPerAngleParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomAngleForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomAngleForce_getNumEnergyParameterDerivatives(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy for each angle
        """
        return _openmm.CustomAngleForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy for each angle
        """
        return _openmm.CustomAngleForce_setEnergyFunction(self, energy)

    def addPerAngleParameter(self, name):
        r"""
        addPerAngleParameter(self, name) -> int
        Add a new per-angle parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomAngleForce_addPerAngleParameter(self, name)

    def getPerAngleParameterName(self, index):
        r"""
        getPerAngleParameterName(self, index) -> std::string const &
        Get the name of a per-angle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomAngleForce_getPerAngleParameterName(self, index)

    def setPerAngleParameterName(self, index, name):
        r"""
        setPerAngleParameterName(self, index, name)
        Set the name of a per-angle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomAngleForce_setPerAngleParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomAngleForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomAngleForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomAngleForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomAngleForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomAngleForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomAngleForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomAngleForce_getEnergyParameterDerivativeName(self, index)

    def addAngle(self, *args):
        r"""
        addAngle(self, particle1, particle2, particle3, parameters=std::vector< double >()) -> int
        Add an angle term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        parameters : vector< double >
            the list of parameters for the new angle

        Returns
        -------
        int
            the index of the angle that was added
        """
        return _openmm.CustomAngleForce_addAngle(self, *args)

    def getAngleParameters(self, index):
        r"""
        getAngleParameters(self, index)
        Get the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        parameters : vector< double >
            the list of parameters for the angle
        """
        return _openmm.CustomAngleForce_getAngleParameters(self, index)

    def setAngleParameters(self, *args):
        r"""
        setAngleParameters(self, index, particle1, particle2, particle3, parameters=std::vector< double >())
        Set the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to set parameters
        particle1 : int
            the index of the first particle connected by the angle
        particle2 : int
            the index of the second particle connected by the angle
        particle3 : int
            the index of the third particle connected by the angle
        parameters : vector< double >
            the list of parameters for the angle
        """
        return _openmm.CustomAngleForce_setAngleParameters(self, *args)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-angle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-angle parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. The set of particles involved in a angle cannot be changed, nor can new angles be added.
        """
        return _openmm.CustomAngleForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CustomAngleForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomAngleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomAngleForce
        __init__(self, other) -> CustomAngleForce
        Create a CustomAngleForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the interaction energy between three particles as a function of theta, the angle between them
        """
        _openmm.CustomAngleForce_swiginit(self, _openmm.new_CustomAngleForce(*args))
    __swig_destroy__ = _openmm.delete_CustomAngleForce

# Register CustomAngleForce in _openmm:
_openmm.CustomAngleForce_swigregister(CustomAngleForce)

class CustomBondForce(Force):
    r"""
    This class implements bonded interactions between pairs of particles. Unlike HarmonicBondForce, the functional form of the interaction is completely customizable, and may involve arbitrary algebraic expressions. It may depend on the distance between particles, as well as on arbitrary global and per-bond parameters.

    To use this class, create a CustomBondForce object, passing an algebraic expression to the constructor that defines the interaction energy between each pair of bonded particles. The expression may depend on r, the distance between the particles, as well as on any parameters you choose. Then call addPerBondParameter() to define per-bond parameters, and addGlobalParameter() to define global parameters. The values of per-bond parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter(). Finally, call addBond() once for each bond. After a bond has been added, you can modify its parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    As an example, the following code creates a CustomBondForce that implements a harmonic potential:

    <tt>CustomBondForce* force = new CustomBondForce("0.5*k*(r-r0)^2");</tt>

    This force depends on two parameters: the spring constant k and equilibrium distance r0. The following code defines these parameters:

    <tt><pre>
    force->addPerBondParameter("k");
    force->addPerBondParameter("r0");
    </pre></tt>

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumBonds(self):
        r"""
        getNumBonds(self) -> int
        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomBondForce_getNumBonds(self)

    def getNumPerBondParameters(self):
        r"""
        getNumPerBondParameters(self) -> int
        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomBondForce_getNumPerBondParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomBondForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomBondForce_getNumEnergyParameterDerivatives(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy for each bond
        """
        return _openmm.CustomBondForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy for each bond
        """
        return _openmm.CustomBondForce_setEnergyFunction(self, energy)

    def addPerBondParameter(self, name):
        r"""
        addPerBondParameter(self, name) -> int
        Add a new per-bond parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomBondForce_addPerBondParameter(self, name)

    def getPerBondParameterName(self, index):
        r"""
        getPerBondParameterName(self, index) -> std::string const &
        Get the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomBondForce_getPerBondParameterName(self, index)

    def setPerBondParameterName(self, index, name):
        r"""
        setPerBondParameterName(self, index, name)
        Set the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomBondForce_setPerBondParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomBondForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomBondForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomBondForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomBondForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomBondForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomBondForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomBondForce_getEnergyParameterDerivativeName(self, index)

    def addBond(self, *args):
        r"""
        addBond(self, particle1, particle2, parameters=std::vector< double >()) -> int
        Add a bond term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        parameters : vector< double >
            the list of parameters for the new bond

        Returns
        -------
        int
            the index of the bond that was added
        """
        return _openmm.CustomBondForce_addBond(self, *args)

    def getBondParameters(self, index):
        r"""
        getBondParameters(self, index)
        Get the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        parameters : vector< double >
            the list of parameters for the bond
        """
        return _openmm.CustomBondForce_getBondParameters(self, index)

    def setBondParameters(self, *args):
        r"""
        setBondParameters(self, index, particle1, particle2, parameters=std::vector< double >())
        Set the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to set parameters
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        parameters : vector< double >
            the list of parameters for the bond
        """
        return _openmm.CustomBondForce_setBondParameters(self, *args)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bond parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-bond parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. The set of particles involved in a bond cannot be changed, nor can new bonds be added.
        """
        return _openmm.CustomBondForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CustomBondForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomBondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomBondForce
        __init__(self, other) -> CustomBondForce
        Create a CustomBondForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the interaction energy between two bonded particles as a function of r, the distance between them
        """
        _openmm.CustomBondForce_swiginit(self, _openmm.new_CustomBondForce(*args))
    __swig_destroy__ = _openmm.delete_CustomBondForce

# Register CustomBondForce in _openmm:
_openmm.CustomBondForce_swigregister(CustomBondForce)

class CustomCentroidBondForce(Force):
    r"""
    This class is similar to CustomCompoundBondForce, but instead of applying forces between individual particles, it applies them between the centers of groups of particles. This is useful for a variety of purposes, such as restraints to keep two molecules from moving too far apart.

    When using this class, you define groups of particles, and the center of each group is calculated as a weighted average of the particle positions. By default, the particle masses are used as weights, so the center position is the center of mass. You can optionally specify different weights to use. You then add bonds just as with CustomCompoundBondForce, but instead of specifying the particles that make up a bond, you specify the groups.

    When creating a CustomCentroidBondForce, you specify the number of groups involved in a bond, and an expression for the energy of each bond. It may depend on the center positions of individual groups, the distances between the centers of pairs of groups, the angles formed by sets of three groups, and the dihedral angles formed by sets of four groups.

    We refer to the groups in a bond as g1, g2, g3, etc. For each bond, CustomCentroidBondForce evaluates a user supplied algebraic expression to determine the interaction energy. The expression may depend on the following variables and functions:

     - x1, y1, z1, x2, y2, z2, etc.: The x, y, and z coordinates of the centers of the groups. For example, x1 is the x coordinate of the center of group g1, and y3 is the y coordinate of the center of group g3.
     - distance(g1, g2): the distance between the centers of groups g1 and g2 (where "g1" and "g2" may be replaced by the names of whichever groups you want to calculate the distance between).
     - angle(g1, g2, g3): the angle formed by the centers of the three specified groups.
     - dihedral(g1, g2, g3, g4): the dihedral angle formed by the centers of the four specified groups.

    The expression also may involve tabulated functions, and may depend on arbitrary global and per-bond parameters.

    To use this class, create a CustomCentroidBondForce object, passing an algebraic expression to the constructor that defines the interaction energy of each bond. Then call addPerBondParameter() to define per-bond parameters and addGlobalParameter() to define global parameters. The values of per-bond parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().

    Next call addGroup() to define the particle groups. Each group is specified by the particles it contains, and the weights to use when computing the center position.

    Then call addBond() to define bonds and specify their parameter values. After a bond has been added, you can modify its parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    As an example, the following code creates a CustomCentroidBondForce that implements a harmonic force between the centers of mass of two groups of particles.

    <tt><pre>
    CustomCentroidBondForce* force = new CustomCentroidBondForce(2, "0.5*k*distance(g1,g2)^2");
    force->addPerBondParameter("k");
    force->addGroup(particles1);
    force->addGroup(particles2);
    vector<int> bondGroups;
    bondGroups.push_back(0);
    bondGroups.push_back(1);
    vector<double> bondParameters;
    bondParameters.push_back(k);
    force->addBond(bondGroups, bondParameters);
    </pre></tt>

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CustomCentroidBondForce

    def getNumGroupsPerBond(self):
        r"""
        getNumGroupsPerBond(self) -> int
        Get the number of groups used to define each bond.
        """
        return _openmm.CustomCentroidBondForce_getNumGroupsPerBond(self)

    def getNumGroups(self):
        r"""
        getNumGroups(self) -> int
        Get the number of particle groups that have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumGroups(self)

    def getNumBonds(self):
        r"""
        getNumBonds(self) -> int
        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumBonds(self)

    def getNumPerBondParameters(self):
        r"""
        getNumPerBondParameters(self) -> int
        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomCentroidBondForce_getNumPerBondParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomCentroidBondForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomCentroidBondForce_getNumEnergyParameterDerivatives(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumTabulatedFunctions(self)

    def getNumFunctions(self):
        r"""
        getNumFunctions(self) -> int
        Get the number of tabulated functions that have been defined.

         @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
        """
        return _openmm.CustomCentroidBondForce_getNumFunctions(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomCentroidBondForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomCentroidBondForce_setEnergyFunction(self, energy)

    def addPerBondParameter(self, name):
        r"""
        addPerBondParameter(self, name) -> int
        Add a new per-bond parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomCentroidBondForce_addPerBondParameter(self, name)

    def getPerBondParameterName(self, index):
        r"""
        getPerBondParameterName(self, index) -> std::string const &
        Get the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCentroidBondForce_getPerBondParameterName(self, index)

    def setPerBondParameterName(self, index, name):
        r"""
        setPerBondParameterName(self, index, name)
        Set the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomCentroidBondForce_setPerBondParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomCentroidBondForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCentroidBondForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomCentroidBondForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomCentroidBondForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomCentroidBondForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomCentroidBondForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCentroidBondForce_getEnergyParameterDerivativeName(self, index)

    def addGroup(self, *args):
        r"""
        addGroup(self, particles, weights=std::vector< double >()) -> int
        Add a particle group.

        Parameters
        ----------
        particles : vector< int >
            the indices of the particles to include in the group
        weights : vector< double >
            the weight to use for each particle when computing the center position. If this is omitted, then particle masses will be used as weights.

        Returns
        -------
        int
            the index of the group that was added
        """
        return _openmm.CustomCentroidBondForce_addGroup(self, *args)

    def getGroupParameters(self, index):
        r"""
        getGroupParameters(self, index)
        Get the properties of a group.

        Parameters
        ----------
        index : int
            the index of the group to get

        Returns
        -------
        particles : vector< int >
            the indices of the particles in the group
        weights : vector< double >
            the weight used for each particle when computing the center position. If no weights were specified, this vector will be empty indicating that particle masses should be used as weights.
        """
        return _openmm.CustomCentroidBondForce_getGroupParameters(self, index)

    def setGroupParameters(self, *args):
        r"""
        setGroupParameters(self, index, particles, weights=std::vector< double >())
        Set the properties of a group.

        Parameters
        ----------
        index : int
            the index of the group to set
        particles : vector< int >
            the indices of the particles in the group
        weights : vector< double >
            the weight to use for each particle when computing the center position. If this is omitted, then particle masses will be used as weights.
        """
        return _openmm.CustomCentroidBondForce_setGroupParameters(self, *args)

    def addBond(self, *args):
        r"""
        addBond(self, groups, parameters=std::vector< double >()) -> int
        Add a bond to the force

        Parameters
        ----------
        groups : vector< int >
            the indices of the groups the bond depends on
        parameters : vector< double >
            the list of per-bond parameter values for the new bond

        Returns
        -------
        int
            the index of the bond that was added
        """
        return _openmm.CustomCentroidBondForce_addBond(self, *args)

    def getBondParameters(self, index):
        r"""
        getBondParameters(self, index)
        Get the properties of a bond.

        Parameters
        ----------
        index : int
            the index of the bond to get

        Returns
        -------
        groups : vector< int >
            the indices of the groups in the bond
        parameters : vector< double >
            the list of per-bond parameter values for the bond
        """
        return _openmm.CustomCentroidBondForce_getBondParameters(self, index)

    def setBondParameters(self, *args):
        r"""
        setBondParameters(self, index, groups, parameters=std::vector< double >())
        Set the properties of a bond.

        Parameters
        ----------
        index : int
            the index of the bond to set
        groups : vector< int >
            the indices of the groups in the bond
        parameters : vector< double >
            the list of per-bond parameter values for the bond
        """
        return _openmm.CustomCentroidBondForce_setBondParameters(self, *args)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """
        return _openmm.CustomCentroidBondForce_addTabulatedFunction(self, name, function)

    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomCentroidBondForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomCentroidBondForce_getTabulatedFunctionName(self, index)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bond parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-bond parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. Neither the definitions of groups nor the set of groups involved in a bond can be changed, nor can new bonds be added.
        """
        return _openmm.CustomCentroidBondForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CustomCentroidBondForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomCentroidBondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, numGroups, energy) -> CustomCentroidBondForce
        __init__(self, other) -> CustomCentroidBondForce
        Create a CustomCentroidBondForce.

        Parameters
        ----------
        numGroups : int
            the number of groups used to define each bond
        energy : string
            an algebraic expression giving the interaction energy of each bond as a function of particle positions, inter-particle distances, angles, and dihedrals, and any global and per-bond parameters
        """
        _openmm.CustomCentroidBondForce_swiginit(self, _openmm.new_CustomCentroidBondForce(*args))

# Register CustomCentroidBondForce in _openmm:
_openmm.CustomCentroidBondForce_swigregister(CustomCentroidBondForce)

class CustomCompoundBondForce(Force):
    r"""
    This class supports a wide variety of bonded interactions. It defines a "bond" as a single energy term that depends on the positions of a fixed set of particles. The number of particles involved in a bond, and how the energy depends on their positions, is configurable. It may depend on the positions of individual particles, the distances between pairs of particles, the angles formed by sets of three particles, and the dihedral angles formed by sets of four particles.

    We refer to the particles in a bond as p1, p2, p3, etc. For each bond, CustomCompoundBondForce evaluates a user supplied algebraic expression to determine the interaction energy. The expression may depend on the following variables and functions:

     - x1, y1, z1, x2, y2, z2, etc.: The x, y, and z coordinates of the particle positions. For example, x1 is the x coordinate of particle p1, and y3 is the y coordinate of particle p3.
     - distance(p1, p2): the distance between particles p1 and p2 (where "p1" and "p2" may be replaced by the names of whichever particles you want to calculate the distance between).
     - angle(p1, p2, p3): the angle formed by the three specified particles.
     - dihedral(p1, p2, p3, p4): the dihedral angle formed by the four specified particles, guaranteed to be in the range [-pi,+pi].

    The expression also may involve tabulated functions, and may depend on arbitrary global and per-bond parameters.

    To use this class, create a CustomCompoundBondForce object, passing an algebraic expression to the constructor that defines the interaction energy of each bond. Then call addPerBondParameter() to define per-bond parameters and addGlobalParameter() to define global parameters. The values of per-bond parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().

    Next, call addBond() to define bonds and specify their parameter values. After a bond has been added, you can modify its parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    As an example, the following code creates a CustomCompoundBondForce that implements a Urey-Bradley potential. This is an interaction between three particles that depends on the angle formed by p1-p2-p3, and on the distance between p1 and p3.

    <tt>CustomCompoundBondForce* force = new CustomCompoundBondForce(3, "0.5*(kangle*(angle(p1,p2,p3)-theta0)^2+kbond*(distance(p1,p3)-r0)^2)");</tt>

    This force depends on four parameters: kangle, kbond, theta0, and r0. The following code defines these as per-bond parameters:

    <tt><pre>
    force->addPerBondParameter("kangle");
    force->addPerBondParameter("kbond");
    force->addPerBondParameter("theta0");
    force->addPerBondParameter("r0");
    </pre></tt>

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CustomCompoundBondForce

    def getNumParticlesPerBond(self):
        r"""
        getNumParticlesPerBond(self) -> int
        Get the number of particles used to define each bond.
        """
        return _openmm.CustomCompoundBondForce_getNumParticlesPerBond(self)

    def getNumBonds(self):
        r"""
        getNumBonds(self) -> int
        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomCompoundBondForce_getNumBonds(self)

    def getNumPerBondParameters(self):
        r"""
        getNumPerBondParameters(self) -> int
        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomCompoundBondForce_getNumPerBondParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomCompoundBondForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomCompoundBondForce_getNumEnergyParameterDerivatives(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCompoundBondForce_getNumTabulatedFunctions(self)

    def getNumFunctions(self):
        r"""
        getNumFunctions(self) -> int
        Get the number of tabulated functions that have been defined.

         @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
        """
        return _openmm.CustomCompoundBondForce_getNumFunctions(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomCompoundBondForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomCompoundBondForce_setEnergyFunction(self, energy)

    def addPerBondParameter(self, name):
        r"""
        addPerBondParameter(self, name) -> int
        Add a new per-bond parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomCompoundBondForce_addPerBondParameter(self, name)

    def getPerBondParameterName(self, index):
        r"""
        getPerBondParameterName(self, index) -> std::string const &
        Get the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCompoundBondForce_getPerBondParameterName(self, index)

    def setPerBondParameterName(self, index, name):
        r"""
        setPerBondParameterName(self, index, name)
        Set the name of a per-bond parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomCompoundBondForce_setPerBondParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomCompoundBondForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCompoundBondForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomCompoundBondForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomCompoundBondForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomCompoundBondForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomCompoundBondForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCompoundBondForce_getEnergyParameterDerivativeName(self, index)

    def addBond(self, *args):
        r"""
        addBond(self, particles, parameters=std::vector< double >()) -> int
        Add a bond to the force

        Parameters
        ----------
        particles : vector< int >
            the indices of the particles the bond depends on
        parameters : vector< double >
            the list of per-bond parameter values for the new bond

        Returns
        -------
        int
            the index of the bond that was added
        """
        return _openmm.CustomCompoundBondForce_addBond(self, *args)

    def getBondParameters(self, index):
        r"""
        getBondParameters(self, index)
        Get the properties of a bond.

        Parameters
        ----------
        index : int
            the index of the bond to get

        Returns
        -------
        particles : vector< int >
            the indices of the particles in the bond
        parameters : vector< double >
            the list of per-bond parameter values for the bond
        """
        return _openmm.CustomCompoundBondForce_getBondParameters(self, index)

    def setBondParameters(self, *args):
        r"""
        setBondParameters(self, index, particles, parameters=std::vector< double >())
        Set the properties of a bond.

        Parameters
        ----------
        index : int
            the index of the bond to set
        particles : vector< int >
            the indices of the particles in the bond
        parameters : vector< double >
            the list of per-bond parameter values for the bond
        """
        return _openmm.CustomCompoundBondForce_setBondParameters(self, *args)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomCompoundBondForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomCompoundBondForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomCompoundBondForce_getTabulatedFunctionName(self, index)

    def addFunction(self, name, values, min, max):
        r"""
        addFunction(self, name, values, min, max) -> int
        Add a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use addTabulatedFunction() instead.
        """
        return _openmm.CustomCompoundBondForce_addFunction(self, name, values, min, max)

    def getFunctionParameters(self, index):
        r"""
        getFunctionParameters(self, index)
        Get the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use getTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomCompoundBondForce_getFunctionParameters(self, index)

    def setFunctionParameters(self, index, name, values, min, max):
        r"""
        setFunctionParameters(self, index, name, values, min, max)
        Set the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use setTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomCompoundBondForce_setFunctionParameters(self, index, name, values, min, max)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bond parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-bond parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. The set of particles involved in a bond cannot be changed, nor can new bonds be added.
        """
        return _openmm.CustomCompoundBondForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CustomCompoundBondForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomCompoundBondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, numParticles, energy) -> CustomCompoundBondForce
        __init__(self, other) -> CustomCompoundBondForce
        Create a CustomCompoundBondForce.

        Parameters
        ----------
        numParticles : int
            the number of particles used to define each bond
        energy : string
            an algebraic expression giving the interaction energy of each bond as a function of particle positions, inter-particle distances, angles, and dihedrals, and any global and per-bond parameters
        """
        _openmm.CustomCompoundBondForce_swiginit(self, _openmm.new_CustomCompoundBondForce(*args))

# Register CustomCompoundBondForce in _openmm:
_openmm.CustomCompoundBondForce_swigregister(CustomCompoundBondForce)

class CustomCVForce(Force):
    r"""
    This class supports energy functions that depend on collective variables. To use it, you define a set of collective variables (scalar valued functions that depend on the particle positions), and an algebraic expression for the energy as a function of the collective variables. The expression also may involve tabulated functions, and may depend on arbitrary global parameters.

    Each collective variable is defined by a Force object. The Force's potential energy is computed, and that becomes the value of the variable. This provides enormous flexibility in defining collective variables, especially by using custom forces. Anything that can be computed as a potential function can also be used as a collective variable.

    To use this class, create a CustomCVForce object, passing an algebraic expression to the constructor that defines the potential energy. Then call addCollectiveVariable() to define collective variables and addGlobalParameter() to define global parameters. The values of global parameters may be modified during a simulation by calling Context::setParameter().

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CustomCVForce

    def getNumCollectiveVariables(self):
        r"""
        getNumCollectiveVariables(self) -> int
        Get the number of collective variables that the interaction depends on.
        """
        return _openmm.CustomCVForce_getNumCollectiveVariables(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomCVForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomCVForce_getNumEnergyParameterDerivatives(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCVForce_getNumTabulatedFunctions(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the energy of the system
        """
        return _openmm.CustomCVForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the energy of the system
        """
        return _openmm.CustomCVForce_setEnergyFunction(self, energy)

    def addCollectiveVariable(self, name, variable):
        r"""
        addCollectiveVariable(self, name, variable) -> int
        Add a collective variable that the force may depend on. The collective variable is represented by a Force object, which should have been created on the heap with the "new" operator. The CustomCVForce takes over ownership of it, and deletes the Force when the CustomCVForce itself is deleted.

        Parameters
        ----------
        name : string
            the name of the collective variable, as it will appear in the energy expression
        variable : Force *
            the collective variable, represented by a Force object. The value of the variable is the energy computed by the Force.

        Returns
        -------
        int
            the index within the Force of the variable that was added
        """

        if not variable.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomCVForce_addCollectiveVariable(self, name, variable)

        variable.thisown=0


        return val


    def getCollectiveVariableName(self, index):
        r"""
        getCollectiveVariableName(self, index) -> std::string const &
        Get the name of a collective variable.

        Parameters
        ----------
        index : int
            the index of the collective variable for which to get the name

        Returns
        -------
        string
            the variable name
        """
        return _openmm.CustomCVForce_getCollectiveVariableName(self, index)

    def getCollectiveVariable(self, *args):
        r"""
        getCollectiveVariable(self, index) -> Force
        getCollectiveVariable(self, index) -> Force
        Get a const reference to the Force object that computes a collective variable.

        Parameters
        ----------
        index : int
            the index of the collective variable to get

        Returns
        -------
        Force
            the Force object
        """
        return _openmm.CustomCVForce_getCollectiveVariable(self, *args)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomCVForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCVForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomCVForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomCVForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomCVForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomCVForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomCVForce_getEnergyParameterDerivativeName(self, index)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomCVForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomCVForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomCVForce_getTabulatedFunctionName(self, index)

    def getCollectiveVariableValues(self, context):
        r"""
        getCollectiveVariableValues(self, context)
        Get the current values of the collective variables in a Context.

        Parameters
        ----------
        context : Context
            the Context for which to get the values

        Returns
        -------
        values : vector< double >
            the values of the collective variables are computed and stored into this
        """
        return _openmm.CustomCVForce_getCollectiveVariableValues(self, context)

    def getInnerContext(self, context):
        r"""
        getInnerContext(self, context) -> Context
        Get the inner Context used for evaluating collective variables.

        When you create a Context for a System that contains a CustomCVForce, internally it creates a new System, adds the Forces that define the CVs to it, creates a new Context for that System, and uses it to evaluate the variables. In most cases you can ignore all of this. It is just an implementation detail. However, there are a few cases where you need to directly access that internal Context. For example, if you want to modify one of the Forces that defines a collective variable and call updateParametersInContext() on it, you need to pass that inner Context to it. This method returns a reference to it.

        Parameters
        ----------
        context : Context
            the Context containing the CustomCVForce

        Returns
        -------
        Context
            the inner Context used to evaluate the collective variables
        """
        return _openmm.CustomCVForce_getInnerContext(self, context)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the tabulated function parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call getTabulatedFunction(index).setFunctionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method is very limited. The only information it updates is the parameters of tabulated functions. All other aspects of the Force (the energy expression, the set of collective variables, etc.) are unaffected and can only be changed by reinitializing the Context.
        """
        return _openmm.CustomCVForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomCVForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomCVForce
        __init__(self, other) -> CustomCVForce
        Create a CustomCVForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the energy of the system as a function of the collective variables and global parameters
        """
        _openmm.CustomCVForce_swiginit(self, _openmm.new_CustomCVForce(*args))

# Register CustomCVForce in _openmm:
_openmm.CustomCVForce_swigregister(CustomCVForce)

class CustomExternalForce(Force):
    r"""
    This class implements an "external" force on particles. The force may be applied to any subset of the particles in the System. The force on each particle is specified by an arbitrary algebraic expression, which may depend on the current position of the particle as well as on arbitrary global and per-particle parameters.

    To use this class, create a CustomExternalForce object, passing an algebraic expression to the constructor that defines the potential energy of each affected particle. The expression may depend on the particle's x, y, and z coordinates, as well as on any parameters you choose. Then call addPerParticleParameter() to define per-particle parameters, and addGlobalParameter() to define global parameters. The values of per-particle parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter(). Finally, call addParticle() once for each particle that should be affected by the force. After a particle has been added, you can modify its parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    As an example, the following code creates a CustomExternalForce that attracts each particle to a target position (x0, y0, z0) via a harmonic potential:

    <tt>CustomExternalForce* force = new CustomExternalForce("k*((x-x0)^2+(y-y0)^2+(z-z0)^2)");</tt>

    This force depends on four parameters: the spring constant k and equilibrium coordinates x0, y0, and z0. The following code defines these parameters:

    <tt><pre>
    force->addGlobalParameter("k", 100.0);
    force->addPerParticleParameter("x0");
    force->addPerParticleParameter("y0");
    force->addPerParticleParameter("z0");
    </pre></tt>

    Special care is needed in systems that use periodic boundary conditions. In that case, each particle really represents an infinite set of particles repeating through space. The variables x, y, and z contain the coordinates of one of those periodic copies, but there is no guarantee about which. It might even change from one time step to the next. You can handle this situation by using the function periodicdistance(x1, y1, z1, x2, y2, z2), which returns the minimum distance between periodic copies of the points (x1, y1, z1) and (x2, y2, z2). For example, the force given above would be rewritten as

    <tt>CustomExternalForce* force = new CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2");</tt>

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomExternalForce_getNumParticles(self)

    def getNumPerParticleParameters(self):
        r"""
        getNumPerParticleParameters(self) -> int
        Get the number of per-particle parameters that the force depends on
        """
        return _openmm.CustomExternalForce_getNumPerParticleParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the force depends on.
        """
        return _openmm.CustomExternalForce_getNumGlobalParameters(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the potential energy of each particle
        """
        return _openmm.CustomExternalForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the potential energy of each particle
        """
        return _openmm.CustomExternalForce_setEnergyFunction(self, energy)

    def addPerParticleParameter(self, name):
        r"""
        addPerParticleParameter(self, name) -> int
        Add a new per-particle parameter that the force may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomExternalForce_addPerParticleParameter(self, name)

    def getPerParticleParameterName(self, index):
        r"""
        getPerParticleParameterName(self, index) -> std::string const &
        Get the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomExternalForce_getPerParticleParameterName(self, index)

    def setPerParticleParameterName(self, index, name):
        r"""
        setPerParticleParameterName(self, index, name)
        Set the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomExternalForce_setPerParticleParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomExternalForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomExternalForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomExternalForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomExternalForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomExternalForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addParticle(self, *args):
        r"""
        addParticle(self, particle, parameters=std::vector< double >()) -> int
        Add a particle term to the force field.

        Parameters
        ----------
        particle : int
            the index of the particle this term is applied to
        parameters : vector< double >
            the list of parameters for the new force term

        Returns
        -------
        int
            the index of the particle term that was added
        """
        return _openmm.CustomExternalForce_addParticle(self, *args)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the force field parameters for a force field term.

        Parameters
        ----------
        index : int
            the index of the particle term for which to get parameters

        Returns
        -------
        particle : int
            the index of the particle this term is applied to
        parameters : vector< double >
            the list of parameters for the force field term
        """
        return _openmm.CustomExternalForce_getParticleParameters(self, index)

    def setParticleParameters(self, *args):
        r"""
        setParticleParameters(self, index, particle, parameters=std::vector< double >())
        Set the force field parameters for a force field term.

        Parameters
        ----------
        index : int
            the index of the particle term for which to set parameters
        particle : int
            the index of the particle this term is applied to
        parameters : vector< double >
            the list of parameters for the force field term
        """
        return _openmm.CustomExternalForce_setParticleParameters(self, *args)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-particle parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. Also, this method cannot be used to add new particles, only to change the parameters of existing ones.
        """
        return _openmm.CustomExternalForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CustomExternalForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomExternalForce
        __init__(self, other) -> CustomExternalForce
        Create a CustomExternalForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the potential energy of each particle as a function of its x, y, and z coordinates
        """
        _openmm.CustomExternalForce_swiginit(self, _openmm.new_CustomExternalForce(*args))
    __swig_destroy__ = _openmm.delete_CustomExternalForce

# Register CustomExternalForce in _openmm:
_openmm.CustomExternalForce_swigregister(CustomExternalForce)

class CustomGBForce(Force):
    r"""
    This class implements complex, multiple stage nonbonded interactions between particles. It is designed primarily for implementing Generalized Born implicit solvation models, although it is not strictly limited to that purpose. The interaction is specified as a series of computations, each defined by an arbitrary algebraic expression. It also allows tabulated functions to be defined and used with the computations. It optionally supports periodic boundary conditions and cutoffs for long range interactions.

    The computation consists of calculating some number of per-particle _computed values_, followed by one or more _energy terms_. A computed value is a scalar value that is computed for each particle in the system. It may depend on an arbitrary set of global and per-particle parameters, and well as on other computed values that have been calculated before it. Once all computed values have been calculated, the energy terms and their derivatives are evaluated to determine the system energy and particle forces. The energy terms may depend on global parameters, per-particle parameters, and per-particle computed values.

    When specifying a computed value or energy term, you provide an algebraic expression to evaluate and a _computation type_ describing how the expression is to be evaluated. There are two main types of computations:

     - *Single Particle*: The expression is evaluated once for each particle in the System. In the case of a computed value, this means the value for a particle depends only on other properties of that particle (its position, parameters, and other computed values). In the case of an energy term, it means each particle makes an independent contribution to the System energy.
     - *Particle Pairs*: The expression is evaluated for every pair of particles in the system. In the case of a computed value, the value for a particular particle is calculated by pairing it with every other particle in the system, evaluating the expression for each pair, and summing them. For an energy term, each particle pair makes an independent contribution to the System energy. (Note that energy terms are assumed to be symmetric with respect to the two interacting particles, and therefore are evaluated only once per pair. In contrast, expressions for computed values need not be symmetric and therefore are calculated twice for each pair: once when calculating the value for the first particle, and again when calculating the value for the second particle.)

    Be aware that, although this class is extremely general in the computations it can define, particular Platforms may only support more restricted types of computations. In particular, all currently existing Platforms require that the first computed value _must_ be a particle pair computation, and all computed values after the first _must_ be single particle computations. This is sufficient for most Generalized Born models, but might not permit some other types of calculations to be implemented.

    This is a complicated class to use, and an example may help to clarify it. The following code implements the OBC variant of the GB/SA solvation model, using the ACE approximation to estimate surface area:

    <tt><pre>
    CustomGBForce* custom = new CustomGBForce();
    custom->addPerParticleParameter("q");
    custom->addPerParticleParameter("radius");
    custom->addPerParticleParameter("scale");
    custom->addGlobalParameter("solventDielectric", obc->getSolventDielectric());
    custom->addGlobalParameter("soluteDielectric", obc->getSoluteDielectric());
    custom->addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(1/U^2-1/L^2)*(r-sr2*sr2/r)+0.5*log(L/U)/r+C);"
                                  "U=r+sr2;"
                                  "C=2*(1/or1-1/L)*step(sr2-r-or1);"
                                  "L=max(or1, D);"
                                  "D=abs(r-sr2);"
                                  "sr2 = scale2*or2;"
                                  "or1 = radius1-0.009; or2 = radius2-0.009", CustomGBForce::ParticlePairNoExclusions);
    custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);"
                                  "psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle);
    custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B",
                          CustomGBForce::SingleParticle);
    custom->addEnergyTerm("-138.935456*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;"
                          "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePair);
    </pre></tt>

    It begins by defining three per-particle parameters (charge, atomic radius, and scale factor) and two global parameters (the dielectric constants for the solute and solvent). It then defines a computed value "I" of type ParticlePair. The expression for evaluating it is a complicated function of the distance between each pair of particles (r), their atomic radii (radius1 and radius2), and their scale factors (scale1 and scale2). Very roughly speaking, it is a measure of the distance between each particle and other nearby particles.

    Next a computation is defined for the Born Radius (B). It is computed independently for each particle, and is a function of that particle's atomic radius and the intermediate value I defined above.

    Finally, two energy terms are defined. The first one is computed for each particle and represents the surface area term, as well as the self interaction part of the polarization energy. The second term is calculated for each pair of particles, and represents the screening of electrostatic interactions by the solvent.

    After defining the force as shown above, you should then call addParticle() once for each particle in the System to set the values of its per-particle parameters (q, radius, and scale). The number of particles for which you set parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    CustomGBForce also lets you specify "exclusions", particular pairs of particles whose interactions should be omitted from calculations. This is most often used for particles that are bonded to each other. Even if you specify exclusions, however, you can use the computation type ParticlePairNoExclusions to indicate that exclusions should not be applied to a particular piece of the computation.

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise. In expressions for particle pair calculations, the names of per-particle parameters and computed values have the suffix "1" or "2" appended to them to indicate the values for the two interacting particles. As seen in the above example, an expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in expressions.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomGBForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.CustomGBForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.CustomGBForce_CutoffPeriodic
    
    SingleParticle = _openmm.CustomGBForce_SingleParticle
    
    ParticlePair = _openmm.CustomGBForce_ParticlePair
    
    ParticlePairNoExclusions = _openmm.CustomGBForce_ParticlePairNoExclusions
    
    __swig_destroy__ = _openmm.delete_CustomGBForce

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomGBForce_getNumParticles(self)

    def getNumExclusions(self):
        r"""
        getNumExclusions(self) -> int
        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomGBForce_getNumExclusions(self)

    def getNumPerParticleParameters(self):
        r"""
        getNumPerParticleParameters(self) -> int
        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumPerParticleParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomGBForce_getNumEnergyParameterDerivatives(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomGBForce_getNumTabulatedFunctions(self)

    def getNumFunctions(self):
        r"""
        getNumFunctions(self) -> int
        Get the number of tabulated functions that have been defined.

         @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
        """
        return _openmm.CustomGBForce_getNumFunctions(self)

    def getNumComputedValues(self):
        r"""
        getNumComputedValues(self) -> int
        Get the number of per-particle computed values the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumComputedValues(self)

    def getNumEnergyTerms(self):
        r"""
        getNumEnergyTerms(self) -> int
        Get the number of terms in the energy computation.
        """
        return _openmm.CustomGBForce_getNumEnergyTerms(self)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::CustomGBForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomGBForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomGBForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.CustomGBForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.CustomGBForce_setCutoffDistance(self, distance)

    def addPerParticleParameter(self, name):
        r"""
        addPerParticleParameter(self, name) -> int
        Add a new per-particle parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomGBForce_addPerParticleParameter(self, name)

    def getPerParticleParameterName(self, index):
        r"""
        getPerParticleParameterName(self, index) -> std::string const &
        Get the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomGBForce_getPerParticleParameterName(self, index)

    def setPerParticleParameterName(self, index, name):
        r"""
        setPerParticleParameterName(self, index, name)
        Set the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomGBForce_setPerParticleParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomGBForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomGBForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomGBForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomGBForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomGBForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomGBForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomGBForce_getEnergyParameterDerivativeName(self, index)

    def addParticle(self, *args):
        r"""
        addParticle(self, parameters=std::vector< double >()) -> int
        Add the nonbonded force parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        parameters : vector< double >
            the list of parameters for the new particle

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.CustomGBForce_addParticle(self, *args)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        parameters : vector< double >
            the list of parameters for the specified particle
        """
        return _openmm.CustomGBForce_getParticleParameters(self, index)

    def setParticleParameters(self, index, parameters):
        r"""
        setParticleParameters(self, index, parameters)
        Set the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        parameters : vector< double >
            the list of parameters for the specified particle
        """
        return _openmm.CustomGBForce_setParticleParameters(self, index, parameters)

    def addComputedValue(self, name, expression, type):
        r"""
        addComputedValue(self, name, expression, type) -> int
        Add a computed value to calculate for each particle.

        Parameters
        ----------
        name : string
            the name of the value
        expression : string
            an algebraic expression to evaluate when calculating the computed value. If the ComputationType is SingleParticle, the expression is evaluated independently for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and previous computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every other particle in the system and summed to get the final value. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and previous computed values for each of them. Append "1" to a variable name to indicate the parameter for the particle whose value is being calculated, and "2" to indicate the particle it is interacting with.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_addComputedValue(self, name, expression, type)

    def getComputedValueParameters(self, index):
        r"""
        getComputedValueParameters(self, index)
        Get the properties of a computed value.

        Parameters
        ----------
        index : int
            the index of the computed value for which to get parameters

        Returns
        -------
        name : string
            the name of the value
        expression : string
            an algebraic expression to evaluate when calculating the computed value. If the ComputationType is SingleParticle, the expression is evaluated independently for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and previous computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every other particle in the system and summed to get the final value. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and previous computed values for each of them. Append "1" to a variable name to indicate the parameter for the particle whose value is being calculated, and "2" to indicate the particle it is interacting with.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_getComputedValueParameters(self, index)

    def setComputedValueParameters(self, index, name, expression, type):
        r"""
        setComputedValueParameters(self, index, name, expression, type)
        Set the properties of a computed value.

        Parameters
        ----------
        index : int
            the index of the computed value for which to set parameters
        name : string
            the name of the value
        expression : string
            an algebraic expression to evaluate when calculating the computed value. If the ComputationType is SingleParticle, the expression is evaluated independently for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and previous computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every other particle in the system and summed to get the final value. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and previous computed values for each of them. Append "1" to a variable name to indicate the parameter for the particle whose value is being calculated, and "2" to indicate the particle it is interacting with.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_setComputedValueParameters(self, index, name, expression, type)

    def addEnergyTerm(self, expression, type):
        r"""
        addEnergyTerm(self, expression, type) -> int
        Add a term to the energy computation.

        Parameters
        ----------
        expression : string
            an algebraic expression to evaluate when calculating the energy. If the ComputationType is SingleParticle, the expression is evaluated once for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every pair of particles in the system. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and computed values for each of them. Append "1" to a variable name to indicate the parameter for the first particle in the pair and "2" to indicate the second particle in the pair.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_addEnergyTerm(self, expression, type)

    def getEnergyTermParameters(self, index):
        r"""
        getEnergyTermParameters(self, index)
        Get the properties of a term to the energy computation.

        Parameters
        ----------
        index : int
            the index of the term for which to get parameters

        Returns
        -------
        expression : string
            an algebraic expression to evaluate when calculating the energy. If the ComputationType is SingleParticle, the expression is evaluated once for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every pair of particles in the system. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and computed values for each of them. Append "1" to a variable name to indicate the parameter for the first particle in the pair and "2" to indicate the second particle in the pair.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_getEnergyTermParameters(self, index)

    def setEnergyTermParameters(self, index, expression, type):
        r"""
        setEnergyTermParameters(self, index, expression, type)
        Set the properties of a term to the energy computation.

        Parameters
        ----------
        index : int
            the index of the term for which to set parameters
        expression : string
            an algebraic expression to evaluate when calculating the energy. If the ComputationType is SingleParticle, the expression is evaluated once for each particle, and may depend on its x, y, and z coordinates, as well as the per-particle parameters and computed values for that particle. If the ComputationType is ParticlePair or ParticlePairNoExclusions, the expression is evaluated once for every pair of particles in the system. In the latter case, the expression may depend on the distance r between the two particles, and on the per-particle parameters and computed values for each of them. Append "1" to a variable name to indicate the parameter for the first particle in the pair and "2" to indicate the second particle in the pair.
        type : ComputationType
            the method to use for computing this value
        """
        return _openmm.CustomGBForce_setEnergyTermParameters(self, index, expression, type)

    def addExclusion(self, particle1, particle2):
        r"""
        addExclusion(self, particle1, particle2) -> int
        Add a particle pair to the list of interactions that should be excluded.

        Parameters
        ----------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair

        Returns
        -------
        int
            the index of the exclusion that was added
        """
        return _openmm.CustomGBForce_addExclusion(self, particle1, particle2)

    def getExclusionParticles(self, index):
        r"""
        getExclusionParticles(self, index)
        Get the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to get particle indices

        Returns
        -------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomGBForce_getExclusionParticles(self, index)

    def setExclusionParticles(self, index, particle1, particle2):
        r"""
        setExclusionParticles(self, index, particle1, particle2)
        Set the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to set particle indices
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomGBForce_setExclusionParticles(self, index, particle1, particle2)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in expressions.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomGBForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in expressions.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomGBForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in expressions.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomGBForce_getTabulatedFunctionName(self, index)

    def addFunction(self, name, values, min, max):
        r"""
        addFunction(self, name, values, min, max) -> int
        Add a tabulated function that may appear in expressions.

         @deprecated This method exists only for backward compatibility. Use addTabulatedFunction() instead.
        """
        return _openmm.CustomGBForce_addFunction(self, name, values, min, max)

    def getFunctionParameters(self, index):
        r"""
        getFunctionParameters(self, index)
        Get the parameters for a tabulated function that may appear in expressions.

         @deprecated This method exists only for backward compatibility. Use getTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomGBForce_getFunctionParameters(self, index)

    def setFunctionParameters(self, index, name, values, min, max):
        r"""
        setFunctionParameters(self, index, name, values, min, max)
        Set the parameters for a tabulated function that may appear in expressions.

         @deprecated This method exists only for backward compatibility. Use setTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomGBForce_setFunctionParameters(self, index, name, values, min, max)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-particle parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. Also, this method cannot be used to add new particles, only to change the parameters of existing ones.
        """
        return _openmm.CustomGBForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomGBForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> CustomGBForce
        __init__(self, other) -> CustomGBForce
        Create a CustomGBForce.
        """
        _openmm.CustomGBForce_swiginit(self, _openmm.new_CustomGBForce(*args))

# Register CustomGBForce in _openmm:
_openmm.CustomGBForce_swigregister(CustomGBForce)

class CustomHbondForce(Force):
    r"""
    This class supports a wide variety of energy functions used to represent hydrogen bonding. It computes interactions between "donor" particle groups and "acceptor" particle groups, where each group may include up to three particles. Typically a donor group consists of a hydrogen atom and the atoms it is bonded to, and an acceptor group consists of a negatively charged atom and the atoms it is bonded to.

    We refer to the particles in a donor group as d1, d2 and d3, and the particles in an acceptor group as a1, a2, and a3. For each donor and each acceptor, CustomHbondForce evaluates a user supplied algebraic expression to determine the interaction energy. The expression may depend on arbitrary distances, angles, and dihedral angles defined by any of the six particles involved. The function distance(p1, p2) is the distance between the particles p1 and p2 (where "p1" and "p2" should be replaced by the names of the actual particles to calculate the distance between), angle(p1, p2, p3) is the angle formed by the three specified particles, and dihedral(p1, p2, p3, p4) is the dihedral angle formed by the four specified particles.

    The expression also may involve tabulated functions, and may depend on arbitrary global, per-donor, and per-acceptor parameters. It also optionally supports periodic boundary conditions and cutoffs for long range interactions.

    To use this class, create a CustomHbondForce object, passing an algebraic expression to the constructor that defines the interaction energy between each donor and acceptor. Then call addPerDonorParameter() to define per-donor parameters, addPerAcceptorParameter() to define per-acceptor parameters, and addGlobalParameter() to define global parameters. The values of per-donor and per-acceptor parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().

    Next, call addDonor() and addAcceptor() to define donors and acceptors and specify their parameter values. After a donor or acceptor has been added, you can modify its parameters by calling setDonorParameters() or setAcceptorParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    CustomHbondForce also lets you specify "exclusions", particular combinations of donors and acceptors whose interactions should be omitted from force and energy calculations. This is most often used for particles that are bonded to each other.

    As an example, the following code creates a CustomHbondForce that implements a simple harmonic potential to keep the distance between a1 and d1, and the angle formed by a1-d1-d2, near ideal values:

    <tt>CustomHbondForce* force = new CustomHbondForce("k*(distance(a1,d1)-r0)^2*(angle(a1,d1,d2)-theta0)^2");</tt>

    This force depends on three parameters: k, r0, and theta0. The following code defines these as per-donor parameters:

    <tt><pre>
    force->addPerDonorParameter("k");
    force->addPerDonorParameter("r0");
    force->addPerDonorParameter("theta0");
    </pre></tt>

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomHbondForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.CustomHbondForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.CustomHbondForce_CutoffPeriodic
    
    __swig_destroy__ = _openmm.delete_CustomHbondForce

    def getNumDonors(self):
        r"""
        getNumDonors(self) -> int
        Get the number of donors for which force field parameters have been defined.
        """
        return _openmm.CustomHbondForce_getNumDonors(self)

    def getNumAcceptors(self):
        r"""
        getNumAcceptors(self) -> int
        Get the number of acceptors for which force field parameters have been defined.
        """
        return _openmm.CustomHbondForce_getNumAcceptors(self)

    def getNumExclusions(self):
        r"""
        getNumExclusions(self) -> int
        Get the number of donor-acceptor pairs whose interactions should be excluded.
        """
        return _openmm.CustomHbondForce_getNumExclusions(self)

    def getNumPerDonorParameters(self):
        r"""
        getNumPerDonorParameters(self) -> int
        Get the number of per-donor parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumPerDonorParameters(self)

    def getNumPerAcceptorParameters(self):
        r"""
        getNumPerAcceptorParameters(self) -> int
        Get the number of per-acceptor parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumPerAcceptorParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumGlobalParameters(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomHbondForce_getNumTabulatedFunctions(self)

    def getNumFunctions(self):
        r"""
        getNumFunctions(self) -> int
        Get the number of tabulated functions that have been defined.

         @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
        """
        return _openmm.CustomHbondForce_getNumFunctions(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy between a donor and an acceptor
        """
        return _openmm.CustomHbondForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy between a donor and an acceptor
        """
        return _openmm.CustomHbondForce_setEnergyFunction(self, energy)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::CustomHbondForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomHbondForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomHbondForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used. All interactions for which the distance between d1 and a1 is greater than the cutoff will be ignored. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.CustomHbondForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used. All interactions for which the distance between d1 and a1 is greater than the cutoff will be ignored. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.CustomHbondForce_setCutoffDistance(self, distance)

    def addPerDonorParameter(self, name):
        r"""
        addPerDonorParameter(self, name) -> int
        Add a new per-donor parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomHbondForce_addPerDonorParameter(self, name)

    def getPerDonorParameterName(self, index):
        r"""
        getPerDonorParameterName(self, index) -> std::string const &
        Get the name of a per-donor parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomHbondForce_getPerDonorParameterName(self, index)

    def setPerDonorParameterName(self, index, name):
        r"""
        setPerDonorParameterName(self, index, name)
        Set the name of a per-donor parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomHbondForce_setPerDonorParameterName(self, index, name)

    def addPerAcceptorParameter(self, name):
        r"""
        addPerAcceptorParameter(self, name) -> int
        Add a new per-acceptor parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomHbondForce_addPerAcceptorParameter(self, name)

    def getPerAcceptorParameterName(self, index):
        r"""
        getPerAcceptorParameterName(self, index) -> std::string const &
        Get the name of a per-acceptor parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomHbondForce_getPerAcceptorParameterName(self, index)

    def setPerAcceptorParameterName(self, index, name):
        r"""
        setPerAcceptorParameterName(self, index, name)
        Set the name of a per-acceptor parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomHbondForce_setPerAcceptorParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomHbondForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomHbondForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomHbondForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomHbondForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomHbondForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addDonor(self, *args):
        r"""
        addDonor(self, d1, d2, d3, parameters=std::vector< double >()) -> int
        Add a donor group to the force

        Parameters
        ----------
        d1 : int
            the index of the first particle for this donor group
        d2 : int
            the index of the second particle for this donor group. If the group only includes one particle, this must be -1.
        d3 : int
            the index of the third particle for this donor group. If the group includes less than three particles, this must be -1.
        parameters : vector< double >
            the list of per-donor parameter values for the new donor

        Returns
        -------
        int
            the index of the donor that was added
        """
        return _openmm.CustomHbondForce_addDonor(self, *args)

    def getDonorParameters(self, index):
        r"""
        getDonorParameters(self, index)
        Get the properties of a donor group.

        Parameters
        ----------
        index : int
            the index of the donor group to get

        Returns
        -------
        d1 : int
            the index of the first particle for this donor group
        d2 : int
            the index of the second particle for this donor group. If the group only includes one particle, this will be -1.
        d3 : int
            the index of the third particle for this donor group. If the group includes less than three particles, this will be -1.
        parameters : vector< double >
            the list of per-donor parameter values for the donor
        """
        return _openmm.CustomHbondForce_getDonorParameters(self, index)

    def setDonorParameters(self, *args):
        r"""
        setDonorParameters(self, index, d1, d2, d3, parameters=std::vector< double >())
        Set the properties of a donor group.

        Parameters
        ----------
        index : int
            the index of the donor group to set
        d1 : int
            the index of the first particle for this donor group
        d2 : int
            the index of the second particle for this donor group. If the group only includes one particle, this must be -1.
        d3 : int
            the index of the third particle for this donor group. If the group includes less than three particles, this must be -1.
        parameters : vector< double >
            the list of per-donor parameter values for the donor
        """
        return _openmm.CustomHbondForce_setDonorParameters(self, *args)

    def addAcceptor(self, *args):
        r"""
        addAcceptor(self, a1, a2, a3, parameters=std::vector< double >()) -> int
        Add an acceptor group to the force

        Parameters
        ----------
        a1 : int
            the index of the first particle for this acceptor group
        a2 : int
            the index of the second particle for this acceptor group. If the group only includes one particle, this must be -1.
        a3 : int
            the index of the third particle for this acceptor group. If the group includes less than three particles, this must be -1.
        parameters : vector< double >
            the list of per-acceptor parameter values for the new acceptor

        Returns
        -------
        int
            the index of the acceptor that was added
        """
        return _openmm.CustomHbondForce_addAcceptor(self, *args)

    def getAcceptorParameters(self, index):
        r"""
        getAcceptorParameters(self, index)
        Get the properties of an acceptor group.

        Parameters
        ----------
        index : int
            the index of the acceptor group to get

        Returns
        -------
        a1 : int
            the index of the first particle for this acceptor group
        a2 : int
            the index of the second particle for this acceptor group. If the group only includes one particle, this will be -1.
        a3 : int
            the index of the third particle for this acceptor group. If the group includes less than three particles, this will be -1.
        parameters : vector< double >
            the list of per-acceptor parameter values for the acceptor
        """
        return _openmm.CustomHbondForce_getAcceptorParameters(self, index)

    def setAcceptorParameters(self, *args):
        r"""
        setAcceptorParameters(self, index, a1, a2, a3, parameters=std::vector< double >())
        Set the properties of an acceptor group.

        Parameters
        ----------
        index : int
            the index of the acceptor group to set
        a1 : int
            the index of the first particle for this acceptor group
        a2 : int
            the index of the second particle for this acceptor group. If the group only includes one particle, this must be -1.
        a3 : int
            the index of the third particle for this acceptor group. If the group includes less than three particles, this must be -1.
        parameters : vector< double >
            the list of per-acceptor parameter values for the acceptor
        """
        return _openmm.CustomHbondForce_setAcceptorParameters(self, *args)

    def addExclusion(self, donor, acceptor):
        r"""
        addExclusion(self, donor, acceptor) -> int
        Add a donor-acceptor pair to the list of interactions that should be excluded.

        Parameters
        ----------
        donor : int
            the index of the donor to exclude
        acceptor : int
            the index of the acceptor to exclude

        Returns
        -------
        int
            the index of the exclusion that was added
        """
        return _openmm.CustomHbondForce_addExclusion(self, donor, acceptor)

    def getExclusionParticles(self, index):
        r"""
        getExclusionParticles(self, index)
        Get the donor and acceptor in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to get donor and acceptor indices

        Returns
        -------
        donor : int
            the index of the donor
        acceptor : int
            the index of the acceptor
        """
        return _openmm.CustomHbondForce_getExclusionParticles(self, index)

    def setExclusionParticles(self, index, donor, acceptor):
        r"""
        setExclusionParticles(self, index, donor, acceptor)
        Get the donor and acceptor in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to get donor and acceptor indices
        donor : int
            the index of the donor
        acceptor : int
            the index of the acceptor
        """
        return _openmm.CustomHbondForce_setExclusionParticles(self, index, donor, acceptor)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomHbondForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomHbondForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomHbondForce_getTabulatedFunctionName(self, index)

    def addFunction(self, name, values, min, max):
        r"""
        addFunction(self, name, values, min, max) -> int
        Add a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use addTabulatedFunction() instead.
        """
        return _openmm.CustomHbondForce_addFunction(self, name, values, min, max)

    def getFunctionParameters(self, index):
        r"""
        getFunctionParameters(self, index)
        Get the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use getTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomHbondForce_getFunctionParameters(self, index)

    def setFunctionParameters(self, index, name, values, min, max):
        r"""
        setFunctionParameters(self, index, name, values, min, max)
        Set the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use setTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomHbondForce_setFunctionParameters(self, index, name, values, min, max)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-donor and per-acceptor parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setDonorParameters() and setAcceptorParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-donor and per-acceptor parameters. All other aspects of the Force (the energy function, nonbonded method, cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. The set of particles involved in a donor or acceptor cannot be changed, nor can new donors or acceptors be added.
        """
        return _openmm.CustomHbondForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomHbondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomHbondForce
        __init__(self, other) -> CustomHbondForce
        Create a CustomHbondForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the interaction energy between a donor and an acceptor as a function of inter-particle distances, angles, and dihedrals, as well as any global, per-donor, and per-acceptor parameters
        """
        _openmm.CustomHbondForce_swiginit(self, _openmm.new_CustomHbondForce(*args))

# Register CustomHbondForce in _openmm:
_openmm.CustomHbondForce_swigregister(CustomHbondForce)

class CustomIntegrator(Integrator):
    r"""
    This is an Integrator that can be used to implemented arbitrary, user defined integration algorithms. It is flexible enough to support a wide range of methods including both deterministic and stochastic integrators, Metropolized integrators, and integrators that must integrate additional quantities along with the particle positions and momenta.

    To create an integration algorithm, you first define a set of variables the integrator will compute. Variables come in two types: global variables have a single value, while per-DOF variables have a value for every degree of freedom (x, y, or z coordinate of a particle). You can define as many variables as you want of each type. The value of any variable can be computed by the integration algorithm, or set directly by calling a method on the CustomIntegrator. All variables are persistent between integration steps; once a value is set, it keeps that value until it is changed by the user or recomputed in a later integration step.

    Next, you define the algorithm as a series of computations. To execute a time step, the integrator performs the list of computations in order. Each computation updates the value of one global or per-DOF value. There are several types of computations that can be done:

     - Global: You provide a mathematical expression involving only global variables. It is evaluated and stored into a global variable.
     - Per-DOF: You provide a mathematical expression involving both global and per-DOF variables. It is evaluated once for every degree of freedom, and the values are stored into a per-DOF variable.
     - Sum: You provide a mathematical expression involving both global and per-DOF variables. It is evaluated once for every degree of freedom. All of those values are then added together, and the sum is stored into a global variable.
     - Constrain Positions: The particle positions are updated so that all distance constraints are satisfied.
     - Constrain Velocities: The particle velocities are updated so the net velocity along any constrained distance is 0.

    Like all integrators, CustomIntegrator ignores any particle whose mass is 0. It is skipped when doing per-DOF computations, and is not included when computing sums over degrees of freedom.

    In addition to the variables you define by calling addGlobalVariable() and addPerDofVariable(), the integrator provides the following pre-defined variables:

     - dt: (global) This is the step size being used by the integrator.
     - energy: (global, read-only) This is the current potential energy of the system.
     - energy0, energy1, energy2, ...: (global, read-only) This is similar to energy, but includes only the contribution from forces in one force group. A single computation step may only depend on a single energy variable (energy, energy0, energy1, etc.).
     - x: (per-DOF) This is the current value of the degree of freedom (the x, y, or z coordinate of a particle).
     - v: (per-DOF) This is the current velocity associated with the degree of freedom (the x, y, or z component of a particle's velocity).
     - f: (per-DOF, read-only) This is the current force acting on the degree of freedom (the x, y, or z component of the force on a particle).
     - f0, f1, f2, ...: (per-DOF, read-only) This is similar to f, but includes only the contribution from forces in one force group. A single computation step may only depend on a single force variable (f, f0, f1, etc.).
     - m: (per-DOF, read-only) This is the mass of the particle the degree of freedom is associated with.
     - uniform: (either global or per-DOF, read-only) This is a uniformly distributed random number between 0 and 1. Every time an expression is evaluated, a different value will be used. When used in a per-DOF expression, a different value will be used for every degree of freedom. Note, however, that if this variable appears multiple times in a single expression, the same value is used everywhere it appears in that expression.
     - gaussian: (either global or per-DOF, read-only) This is a Gaussian distributed random number with mean 0 and variance 1. Every time an expression is evaluated, a different value will be used. When used in a per-DOF expression, a different value will be used for every degree of freedom. Note, however, that if this variable appears multiple times in a single expression, the same value is used everywhere it appears in that expression.
     - A global variable is created for every adjustable parameter defined in the integrator's Context.

    The following example uses a CustomIntegrator to implement a velocity Verlet integrator:

    <tt><pre>
    CustomIntegrator integrator(0.001);
    integrator.addComputePerDof("v", "v+0.5*dt*f/m");
    integrator.addComputePerDof("x", "x+dt*v");
    integrator.addComputePerDof("v", "v+0.5*dt*f/m");
    </pre></tt>

    The first step updates the velocities based on the current forces. The second step updates the positions based on the new velocities, and the third step updates the velocities again. Although the first and third steps look identical, the forces used in them are different. You do not need to tell the integrator that; it will recognize that the positions have changed and know to recompute the forces automatically.

    The above example has two problems. First, it does not respect distance constraints. To make the integrator work with constraints, you need to add extra steps to tell it when and how to apply them. Second, it never gives Forces an opportunity to update the context state. This should be done every time step so that, for example, an AndersenThermostat can randomize velocities or a MonteCarloBarostat can scale particle positions. You need to add a step to tell the integrator when to do this. The following example corrects both these problems, using the RATTLE algorithm to apply constraints:

    <tt><pre>
    CustomIntegrator integrator(0.001);
    integrator.addPerDofVariable("x1", 0);
    integrator.addUpdateContextState();
    integrator.addComputePerDof("v", "v+0.5*dt*f/m");
    integrator.addComputePerDof("x", "x+dt*v");
    integrator.addComputePerDof("x1", "x");
    integrator.addConstrainPositions();
    integrator.addComputePerDof("v", "v+0.5*dt*f/m+(x-x1)/dt");
    integrator.addConstrainVelocities();
    </pre></tt>

    CustomIntegrator can be used to implement multiple time step integrators. The following example shows an r-RESPA integrator. It assumes the quickly changing forces are in force group 0 and the slowly changing ones are in force group 1. It evaluates the "fast" forces four times as often as the "slow" forces.

    <tt><pre>
    CustomIntegrator integrator(0.004);
    integrator.addComputePerDof("v", "v+0.5*dt*f1/m");
    for (int i = 0; i < 4; i++) {
        integrator.addComputePerDof("v", "v+0.5*(dt/4)*f0/m");
        integrator.addComputePerDof("x", "x+(dt/4)*v");
        integrator.addComputePerDof("v", "v+0.5*(dt/4)*f0/m");
    }
    integrator.addComputePerDof("v", "v+0.5*dt*f1/m");
    </pre></tt>

    The sequence of computations in a CustomIntegrator can include flow control in the form of "if" and "while" blocks. The computations inside an "if" block are executed either zero or one times, depending on whether a condition is true. The computations inside a "while" block are executed repeatedly for as long as the condition remains true. Be very careful when writing "while" blocks; there is nothing to stop you from creating an infinite loop!

    For example, suppose you are writing a Monte Carlo algorithm. Assume you have already computed a new set of particle coordinates "xnew" and a step acceptance probability "acceptanceProbability". The following lines use an "if" block to decide whether to accept the step, and if it is accepted, store the new positions into "x".

    <tt><pre>
    integrator.beginIfBlock("uniform < acceptanceProbability");
    integrator.addComputePerDof("x", "xnew");
    integrator.endBlock();
    </pre></tt>

    The condition in an "if" or "while" block is evaluated globally, so it may only involve global variables, not per-DOF ones. It may use any of the following comparison operators: =, <. >, !=, <=, >=. Blocks may be nested inside each other.

    "Per-DOF" computations can also be thought of as per-particle computations that operate on three component vectors. For example, "x+dt*v" means to take the particle's velocity (a vector), multiply it by the step size, and add the position (also a vector). The result is a new vector that can be stored into a per-DOF variable with addComputePerDof(), or it can be summed over all components of all particles with addComputeSum(). Because the calculation is done on vectors, you can use functions that operate explicitly on vectors rather than just computing each component independently. For example, the following line uses a cross product to compute the angular momentum of each particle and stores it into a per-DOF variable.

    <tt><pre>
    integrator.addComputePerDof("angularMomentum", "m*cross(x, v)");
    </pre></tt>

    Here are two more examples that may be useful as starting points for writing your own integrators. The first one implements the algorithm used by the standard VerletIntegrator class. This is a leapfrog algorithm, in contrast to the velocity Verlet algorithm shown above, so it only requires applying constraints once in each time step.

    <tt><pre>
    CustomIntegrator integrator(dt);
    integrator.addPerDofVariable("x0", 0);
    integrator.addUpdateContextState();
    integrator.addComputePerDof("x0", "x");
    integrator.addComputePerDof("v", "v+dt*f/m");
    integrator.addComputePerDof("x", "x+dt*v");
    integrator.addConstrainPositions();
    integrator.addComputePerDof("v", "(x-x0)/dt");
    </pre></tt>

    The second one implements the algorithm used by the standard LangevinMiddleIntegrator class. kB is Boltzmann's constant.

    <tt><pre>
    CustomIntegrator integrator(dt);
    integrator.addGlobalVariable("a", exp(-friction*dt));
    integrator.addGlobalVariable("b", sqrt(1-exp(-2*friction*dt)));
    integrator.addGlobalVariable("kT", kB*temperature);
    integrator.addPerDofVariable("x1", 0);
    integrator.addUpdateContextState();
    integrator.addComputePerDof("v", "v + dt*f/m");
    integrator.addConstrainVelocities();
    integrator.addComputePerDof("x", "x + 0.5*dt*v");
    integrator.addComputePerDof("v", "a*v + b*sqrt(kT/m)*gaussian");
    integrator.addComputePerDof("x", "x + 0.5*dt*v");
    integrator.addComputePerDof("x1", "x");
    integrator.addConstrainPositions();
    integrator.addComputePerDof("v", "v + (x-x1)/dt");
    </pre></tt>

    Another feature of CustomIntegrator is that it can use derivatives of the potential energy with respect to context parameters. These derivatives are typically computed by custom forces, and are only computed if a Force object has been specifically told to compute them by calling addEnergyParameterDerivative() on it. CustomIntegrator provides a deriv() function for accessing these derivatives in global or per-DOF expressions. For example, "deriv(energy, lambda)" is the derivative of the total potentially energy with respect to the parameter lambda. You can also restrict it to a single force group by specifying a different variable for the first argument, such as "deriv(energy1, lambda)".

    An Integrator has one other job in addition to evolving the equations of motion: it defines how to compute the kinetic energy of the system. Depending on the integration method used, simply summing (mv^2)/2 over all degrees of freedom may not give the correct answer. For example, in a leapfrog integrator the velocities are "delayed" by half a time step, so the above formula would give the kinetic energy half a time step ago, not at the current time.

    Call setKineticEnergyExpression() to set an expression for the kinetic energy. It is computed for every degree of freedom (excluding ones whose mass is 0) and the result is summed. The default expression is "m*v*v/2", which is correct for many integrators.

    As example, the following line defines the correct way to compute kinetic energy when using a leapfrog algorithm:

    <tt><pre>
    integrator.setKineticEnergyExpression("m*v1*v1/2; v1=v+0.5*dt*f/m");
    </pre></tt>

    The kinetic energy expression may depend on the following pre-defined variables: x, v, f, m, dt. It also may depend on user-defined global and per-DOF variables, and on the values of adjustable parameters defined in the integrator's Context. It may not depend on any other variable, such as the potential energy, the force from a single force group, or a random number.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise. An expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator.

    Expressions used in ComputePerDof and ComputeSum steps can also use the following functions that operate on vectors: cross(a, b) is the cross product of two vectors; dot(a, b) is the dot product of two vectors; _x(a), _y(a), and _z(a) extract a single component from a vector; and vector(a, b, c) creates a new vector with the x component of the first argument, the y component of the second argument, and the z component of the third argument. Remember that every quantity appearing in a vector expression is a vector. Functions that appear to return a scalar really return a vector whose components are all the same. For example, _z(a) returns the vector (a.z, a.z, a.z). Likewise, wherever a constant appears in the expression, it really means a vector whose components all have the same value.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in expressions.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    ComputeGlobal = _openmm.CustomIntegrator_ComputeGlobal
    
    ComputePerDof = _openmm.CustomIntegrator_ComputePerDof
    
    ComputeSum = _openmm.CustomIntegrator_ComputeSum
    
    ConstrainPositions = _openmm.CustomIntegrator_ConstrainPositions
    
    ConstrainVelocities = _openmm.CustomIntegrator_ConstrainVelocities
    
    UpdateContextState = _openmm.CustomIntegrator_UpdateContextState
    
    IfBlockStart = _openmm.CustomIntegrator_IfBlockStart
    
    WhileBlockStart = _openmm.CustomIntegrator_WhileBlockStart
    
    BlockEnd = _openmm.CustomIntegrator_BlockEnd
    
    __swig_destroy__ = _openmm.delete_CustomIntegrator

    def getNumGlobalVariables(self):
        r"""
        getNumGlobalVariables(self) -> int
        Get the number of global variables that have been defined.
        """
        return _openmm.CustomIntegrator_getNumGlobalVariables(self)

    def getNumPerDofVariables(self):
        r"""
        getNumPerDofVariables(self) -> int
        Get the number of per-DOF variables that have been defined.
        """
        return _openmm.CustomIntegrator_getNumPerDofVariables(self)

    def getNumComputations(self):
        r"""
        getNumComputations(self) -> int
        Get the number of computation steps that have been added.
        """
        return _openmm.CustomIntegrator_getNumComputations(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomIntegrator_getNumTabulatedFunctions(self)

    def addGlobalVariable(self, name, initialValue):
        r"""
        addGlobalVariable(self, name, initialValue) -> int
        Define a new global variable.

        Parameters
        ----------
        name : string
            the name of the variable
        initialValue : double
            the variable will initially be set to this value

        Returns
        -------
        int
            the index of the variable that was added
        """
        return _openmm.CustomIntegrator_addGlobalVariable(self, name, initialValue)

    def getGlobalVariableName(self, index):
        r"""
        getGlobalVariableName(self, index) -> std::string const &
        Get the name of a global variable.

        Parameters
        ----------
        index : int
            the index of the variable to get

        Returns
        -------
        string
            the name of the variable
        """
        return _openmm.CustomIntegrator_getGlobalVariableName(self, index)

    def addPerDofVariable(self, name, initialValue):
        r"""
        addPerDofVariable(self, name, initialValue) -> int
        Define a new per-DOF variable.

        Parameters
        ----------
        name : string
            the name of the variable
        initialValue : double
            the variable will initially be set to this value for all degrees of freedom

        Returns
        -------
        int
            the index of the variable that was added
        """
        return _openmm.CustomIntegrator_addPerDofVariable(self, name, initialValue)

    def getPerDofVariableName(self, index):
        r"""
        getPerDofVariableName(self, index) -> std::string const &
        Get the name of a per-DOF variable.

        Parameters
        ----------
        index : int
            the index of the variable to get

        Returns
        -------
        string
            the name of the variable
        """
        return _openmm.CustomIntegrator_getPerDofVariableName(self, index)

    def getGlobalVariable(self, index):
        r"""
        getGlobalVariable(self, index) -> double
        Get the current value of a global variable.

        Parameters
        ----------
        index : int
            the index of the variable to get

        Returns
        -------
        double
            the current value of the variable
        """
        return _openmm.CustomIntegrator_getGlobalVariable(self, index)

    def getGlobalVariableByName(self, name):
        r"""
        getGlobalVariableByName(self, name) -> double
        Get the current value of a global variable, specified by name.

        Parameters
        ----------
        name : string
            the name of the variable to get

        Returns
        -------
        double
            the current value of the parameter
        """
        return _openmm.CustomIntegrator_getGlobalVariableByName(self, name)

    def setGlobalVariable(self, index, value):
        r"""
        setGlobalVariable(self, index, value)
        Set the value of a global variable.

        Parameters
        ----------
        index : int
            the index of the variable to set
        value : double
            the new value of the variable
        """
        return _openmm.CustomIntegrator_setGlobalVariable(self, index, value)

    def setGlobalVariableByName(self, name, value):
        r"""
        setGlobalVariableByName(self, name, value)
        Set the value of a global variable, specified by name.

        Parameters
        ----------
        name : string
            the name of the variable to set
        value : double
            the new value of the variable
        """
        return _openmm.CustomIntegrator_setGlobalVariableByName(self, name, value)

    def getPerDofVariableByName(self, name):
        r"""
        getPerDofVariableByName(self, name)
        Get the value of a per-DOF variable, specified by name.

        Parameters
        ----------
        name : string
            the name of the variable to get

        Returns
        -------
        values : vector< Vec3 >
            the values of the variable for all degrees of freedom are stored into this
        """
        return _openmm.CustomIntegrator_getPerDofVariableByName(self, name)

    def setPerDofVariable(self, index, values):
        r"""
        setPerDofVariable(self, index, values)
        Set the value of a per-DOF variable.

        Parameters
        ----------
        index : int
            the index of the variable to set
        values : vector< Vec3 >
            the new values of the variable for all degrees of freedom
        """
        return _openmm.CustomIntegrator_setPerDofVariable(self, index, values)

    def setPerDofVariableByName(self, name, values):
        r"""
        setPerDofVariableByName(self, name, values)
        Set the value of a per-DOF variable, specified by name.

        Parameters
        ----------
        name : string
            the name of the variable to set
        values : vector< Vec3 >
            the new values of the variable for all degrees of freedom
        """
        return _openmm.CustomIntegrator_setPerDofVariableByName(self, name, values)

    def addComputeGlobal(self, variable, expression):
        r"""
        addComputeGlobal(self, variable, expression) -> int
        Add a step to the integration algorithm that computes a global value.

        Parameters
        ----------
        variable : string
            the global variable to store the computed value into
        expression : string
            a mathematical expression involving only global variables. In each integration step, its value is computed and stored into the specified variable.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addComputeGlobal(self, variable, expression)

    def addComputePerDof(self, variable, expression):
        r"""
        addComputePerDof(self, variable, expression) -> int
        Add a step to the integration algorithm that computes a per-DOF value.

        Parameters
        ----------
        variable : string
            the per-DOF variable to store the computed value into
        expression : string
            a mathematical expression involving both global and per-DOF variables. In each integration step, its value is computed for every degree of freedom and stored into the specified variable.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addComputePerDof(self, variable, expression)

    def addComputeSum(self, variable, expression):
        r"""
        addComputeSum(self, variable, expression) -> int
        Add a step to the integration algorithm that computes a sum over degrees of freedom.

        Parameters
        ----------
        variable : string
            the global variable to store the computed value into
        expression : string
            a mathematical expression involving both global and per-DOF variables. In each integration step, its value is computed for every degree of freedom. Those values are then added together, and the sum is stored in the specified variable.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addComputeSum(self, variable, expression)

    def addConstrainPositions(self):
        r"""
        addConstrainPositions(self) -> int
        Add a step to the integration algorithm that updates particle positions so all constraints are satisfied.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addConstrainPositions(self)

    def addConstrainVelocities(self):
        r"""
        addConstrainVelocities(self) -> int
        Add a step to the integration algorithm that updates particle velocities so the net velocity along all constraints is 0.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addConstrainVelocities(self)

    def addUpdateContextState(self):
        r"""
        addUpdateContextState(self) -> int
        Add a step to the integration algorithm that allows Forces to update the context state.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_addUpdateContextState(self)

    def beginIfBlock(self, condition):
        r"""
        beginIfBlock(self, condition) -> int
        Add a step which begins a new "if" block.

        Parameters
        ----------
        condition : string
            a mathematical expression involving a comparison operator and global variables. All steps between this one and the end of the block are executed only if the condition is true.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_beginIfBlock(self, condition)

    def beginWhileBlock(self, condition):
        r"""
        beginWhileBlock(self, condition) -> int
        Add a step which begins a new "while" block.

        Parameters
        ----------
        condition : string
            a mathematical expression involving a comparison operator and global variables. All steps between this one and the end of the block are executed repeatedly as long as the condition remains true.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_beginWhileBlock(self, condition)

    def endBlock(self):
        r"""
        endBlock(self) -> int
        Add a step which marks the end of the most recently begun "if" or "while" block.

        Returns
        -------
        int
            the index of the step that was added
        """
        return _openmm.CustomIntegrator_endBlock(self)

    def getComputationStep(self, index):
        r"""
        getComputationStep(self, index)
        Get the details of a computation step that has been added to the integration algorithm.

        Parameters
        ----------
        index : int
            the index of the computation step to get

        Returns
        -------
        type : ComputationType
            the type of computation this step performs
        variable : string
            the variable into which this step stores its result. If this step does not store a result in a variable, this will be an empty string.
        expression : string
            the expression this step evaluates. If this step does not evaluate an expression, this will be an empty string.
        """
        return _openmm.CustomIntegrator_getComputationStep(self, index)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in expressions.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The integrator takes over ownership of it, and deletes it when the integrator itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomIntegrator_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in expressions.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomIntegrator_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in expressions.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomIntegrator_getTabulatedFunctionName(self, index)

    def getKineticEnergyExpression(self):
        r"""
        getKineticEnergyExpression(self) -> std::string const &
        Get the expression to use for computing the kinetic energy. The expression is evaluated for every degree of freedom. Those values are then added together, and the sum is reported as the current kinetic energy.
        """
        return _openmm.CustomIntegrator_getKineticEnergyExpression(self)

    def setKineticEnergyExpression(self, expression):
        r"""
        setKineticEnergyExpression(self, expression)
        Set the expression to use for computing the kinetic energy. The expression is evaluated for every degree of freedom. Those values are then added together, and the sum is reported as the current kinetic energy.
        """
        return _openmm.CustomIntegrator_setKineticEnergyExpression(self, expression)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.CustomIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random numbers will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.CustomIntegrator_setRandomNumberSeed(self, seed)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.CustomIntegrator_step(self, steps)

    def getPerDofVariable(self, *args):
        r"""
        getPerDofVariable(self, index)
        getPerDofVariable(self, index) -> PyObject *
        """
        return _openmm.CustomIntegrator_getPerDofVariable(self, *args)

    def __init__(self, *args):
        r"""
        __init__(self, stepSize) -> CustomIntegrator
        __init__(self, other) -> CustomIntegrator
        Create a CustomIntegrator.

        Parameters
        ----------
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        """
        _openmm.CustomIntegrator_swiginit(self, _openmm.new_CustomIntegrator(*args))

# Register CustomIntegrator in _openmm:
_openmm.CustomIntegrator_swigregister(CustomIntegrator)

class CustomManyParticleForce(Force):
    r"""
    This class supports a wide variety of nonbonded N-particle interactions, where N is user specified. The interaction energy is determined by an arbitrary, user specified algebraic expression that is evaluated for every possible set of N particles in the system. It may depend on the positions of the individual particles, the distances between pairs of particles, the angles formed by sets of three particles, and the dihedral angles formed by sets of four particles.

    Be aware that the cost of evaluating an N-particle interaction increases very rapidly with N. Values larger than N=3 are rarely used.

    We refer to a set of particles for which the energy is being evaluated as p1, p2, p3, etc. The energy expression may depend on the following variables and functions:

     - x1, y1, z1, x2, y2, z2, etc.: The x, y, and z coordinates of the particle positions. For example, x1 is the x coordinate of particle p1, and y3 is the y coordinate of particle p3.
     - distance(p1, p2): the distance between particles p1 and p2 (where "p1" and "p2" may be replaced by the names of whichever particles you want to calculate the distance between).
     - angle(p1, p2, p3): the angle formed by the three specified particles.
     - dihedral(p1, p2, p3, p4): the dihedral angle formed by the four specified particles.
     - arbitrary global and per-particle parameters that you define.

    To use this class, create a CustomManyParticleForce object, passing an algebraic expression to the constructor that defines the interaction energy of each set of particles. Then call addPerParticleParameter() to define per-particle parameters, and addGlobalParameter() to define global parameters. The values of per-particle parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().

    Next, call addParticle() once for each particle in the System to set the values of its per-particle parameters. The number of particles for which you set parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    Multi-particle interactions can be very expensive to evaluate, so they are usually used with a cutoff distance. The exact interpretation of the cutoff depends on the permutation mode, as discussed below.

    CustomManyParticleForce also lets you specify "exclusions", particular pairs of particles whose interactions should be omitted from force and energy calculations. This is most often used for particles that are bonded to each other. If you specify a pair of particles as an exclusion, _all_ sets that include those two particles will be omitted.

    As an example, the following code creates a CustomManyParticleForce that implements an Axilrod-Teller potential. This is an interaction between three particles that depends on all three distances and angles formed by the particles.

    <tt><pre>CustomManyParticleForce* force = new CustomManyParticleForce(3,
        "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;"
        "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);"
        "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)");
    force->setPermutationMode(CustomManyParticleForce::SinglePermutation);
    </pre></tt>

    This force depends on one parameter, C. The following code defines it as a global parameter:

    <tt><pre>
    force->addGlobalParameter("C", 1.0);
    </pre></tt>

    Notice that the expression is symmetric with respect to the particles. It only depends on the products cos(theta1)*cos(theta2)*cos(theta3) and r12*r13*r23, both of which are unchanged if the labels p1, p2, and p3 are permuted. This is required because we specified SinglePermutation as the permutation mode. (This is the default, so we did not really need to set it, but doing so makes the example clearer.) In this mode, the expression is only evaluated once for each set of particles. No guarantee is made about which particle will be identified as p1, p2, etc. Therefore, the energy _must_ be symmetric with respect to exchange of particles. Otherwise, the results would be undefined because permuting the labels would change the energy.

    Not all many-particle interactions work this way. Another common pattern is for the expression to describe an interaction between one central particle and other nearby particles. An example of this is the 3-particle piece of the Stillinger-Weber potential:

    <tt><pre>CustomManyParticleForce* force = new CustomManyParticleForce(3,
        "L*eps*(cos(theta1)+1/3)^2*exp(sigma*gamma/(r12-a*sigma))*exp(sigma*gamma/(r13-a*sigma));"
        "r12 = distance(p1,p2); r13 = distance(p1,p3); theta1 = angle(p3,p1,p2)");
    force->setPermutationMode(CustomManyParticleForce::UniqueCentralParticle);
    </pre></tt>

    When the permutation mode is set to UniqueCentralParticle, particle p1 is treated as the central particle. For a set of N particles, the expression is evaluated N times, once with each particle as p1. The expression can therefore treat p1 differently from the other particles. Notice that it is still symmetric with respect to p2 and p3, however. There is no guarantee about how those labels will be assigned to particles.

    Distance cutoffs are applied in different ways depending on the permutation mode. In SinglePermutation mode, every particle in the set must be within the cutoff distance of every other particle. If _any_ two particles are further apart than the cutoff distance, the interaction is skipped. In UniqueCentralParticle mode, each particle must be within the cutoff distance of the central particle, but not necessarily of all the other particles. The cutoff may therefore exclude a subset of the permutations of a set of particles.

    Another common situation is that some particles are fundamentally different from others, causing the expression to be inherently non-symmetric. An example would be a water model that involves three particles, two of which _must_ be hydrogen and one of which _must_ be oxygen. Cases like this can be implemented using particle types.

    A particle type is an integer that you specify when you call addParticle(). (If you omit the argument, it defaults to 0.) For the water model, you could specify 0 for all oxygen atoms and 1 for all hydrogen atoms. You can then call setTypeFilter() to specify the list of allowed types for each of the N particles involved in an interaction:

    <tt><pre>
    set<int> oxygenTypes, hydrogenTypes;
    oxygenTypes.insert(0);
    hydrogenTypes.insert(1);
    force->setTypeFilter(0, oxygenTypes);
    force->setTypeFilter(1, hydrogenTypes);
    force->setTypeFilter(2, hydrogenTypes);
    </pre></tt>

    This specifies that of the three particles in an interaction, p1 must be oxygen while p2 and p3 must be hydrogen. The energy expression will only be evaluated for triplets of particles that satisfy those requirements. It will still only be evaluated once for each triplet, so it must still be symmetric with respect to p2 and p3.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise. The names of per-particle parameters have the suffix "1", "2", etc. appended to them to indicate the values for the multiple interacting particles. For example, if you define a per-particle parameter called "charge", then the variable "charge2" is the charge of particle p2. As seen above, the expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomManyParticleForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.CustomManyParticleForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.CustomManyParticleForce_CutoffPeriodic
    
    SinglePermutation = _openmm.CustomManyParticleForce_SinglePermutation
    
    UniqueCentralParticle = _openmm.CustomManyParticleForce_UniqueCentralParticle
    
    __swig_destroy__ = _openmm.delete_CustomManyParticleForce

    def getNumParticlesPerSet(self):
        r"""
        getNumParticlesPerSet(self) -> int
        Get the number of particles in each set for which the energy is evaluated
        """
        return _openmm.CustomManyParticleForce_getNumParticlesPerSet(self)

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomManyParticleForce_getNumParticles(self)

    def getNumExclusions(self):
        r"""
        getNumExclusions(self) -> int
        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomManyParticleForce_getNumExclusions(self)

    def getNumPerParticleParameters(self):
        r"""
        getNumPerParticleParameters(self) -> int
        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomManyParticleForce_getNumPerParticleParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomManyParticleForce_getNumGlobalParameters(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomManyParticleForce_getNumTabulatedFunctions(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomManyParticleForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomManyParticleForce_setEnergyFunction(self, energy)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::CustomManyParticleForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomManyParticleForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomManyParticleForce_setNonbondedMethod(self, method)

    def getPermutationMode(self):
        r"""
        getPermutationMode(self) -> OpenMM::CustomManyParticleForce::PermutationMode
        Get the mode that selects which permutations of a set of particles to evaluate the interaction for.
        """
        return _openmm.CustomManyParticleForce_getPermutationMode(self)

    def setPermutationMode(self, mode):
        r"""
        setPermutationMode(self, mode)
        Set the mode that selects which permutations of a set of particles to evaluate the interaction for.
        """
        return _openmm.CustomManyParticleForce_setPermutationMode(self, mode)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.CustomManyParticleForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.CustomManyParticleForce_setCutoffDistance(self, distance)

    def addPerParticleParameter(self, name):
        r"""
        addPerParticleParameter(self, name) -> int
        Add a new per-particle parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomManyParticleForce_addPerParticleParameter(self, name)

    def getPerParticleParameterName(self, index):
        r"""
        getPerParticleParameterName(self, index) -> std::string const &
        Get the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomManyParticleForce_getPerParticleParameterName(self, index)

    def setPerParticleParameterName(self, index, name):
        r"""
        setPerParticleParameterName(self, index, name)
        Set the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomManyParticleForce_setPerParticleParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomManyParticleForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomManyParticleForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomManyParticleForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomManyParticleForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomManyParticleForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addParticle(self, *args):
        r"""
        addParticle(self, parameters=std::vector< double >(), type=0) -> int
        Add the nonbonded force parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        parameters : vector< double >
            the list of parameters for the new particle
        type : int
            the type of the new particle

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.CustomManyParticleForce_addParticle(self, *args)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        parameters : vector< double >
            the list of parameters for the specified particle
        type : int
            the type of the specified particle
        """
        return _openmm.CustomManyParticleForce_getParticleParameters(self, index)

    def setParticleParameters(self, index, parameters, type):
        r"""
        setParticleParameters(self, index, parameters, type)
        Set the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        parameters : vector< double >
            the list of parameters for the specified particle
        type : int
            the type of the specified particle
        """
        return _openmm.CustomManyParticleForce_setParticleParameters(self, index, parameters, type)

    def addExclusion(self, particle1, particle2):
        r"""
        addExclusion(self, particle1, particle2) -> int
        Add a particle pair to the list of interactions that should be excluded.

        In many cases, you can use createExclusionsFromBonds() rather than adding each exclusion explicitly.

        Parameters
        ----------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair

        Returns
        -------
        int
            the index of the exclusion that was added
        """
        return _openmm.CustomManyParticleForce_addExclusion(self, particle1, particle2)

    def getExclusionParticles(self, index):
        r"""
        getExclusionParticles(self, index)
        Get the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to get particle indices

        Returns
        -------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomManyParticleForce_getExclusionParticles(self, index)

    def setExclusionParticles(self, index, particle1, particle2):
        r"""
        setExclusionParticles(self, index, particle1, particle2)
        Set the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to set particle indices
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomManyParticleForce_setExclusionParticles(self, index, particle1, particle2)

    def createExclusionsFromBonds(self, bonds, bondCutoff):
        r"""
        createExclusionsFromBonds(self, bonds, bondCutoff)
        Identify exclusions based on the molecular topology. Particles which are separated by up to a specified number of bonds are added as exclusions.

        Parameters
        ----------
        bonds : vector< std::pair< int, int > >
            the set of bonds based on which to construct exclusions. Each element specifies the indices of two particles that are bonded to each other.
        bondCutoff : int
            pairs of particles that are separated by this many bonds or fewer are added to the list of exclusions
        """
        return _openmm.CustomManyParticleForce_createExclusionsFromBonds(self, bonds, bondCutoff)

    def getTypeFilter(self, index):
        r"""
        getTypeFilter(self, index)
        Get the allowed particle types for one of the particles involved in the interaction. If this an empty set (the default), no filter is applied and all interactions are evaluated regardless of the type of the specified particle.

        Parameters
        ----------
        index : int
            the index of the particle within the interaction (between 0 and getNumParticlesPerSet())

        Returns
        -------
        types : set< int >
            the allowed types for the specified particle
        """
        return _openmm.CustomManyParticleForce_getTypeFilter(self, index)

    def setTypeFilter(self, index, types):
        r"""
        setTypeFilter(self, index, types)
        Set the allowed particle types for one of the particles involved in the interaction. If this an empty set (the default), no filter is applied and all interactions are evaluated regardless of the type of the specified particle.

        Parameters
        ----------
        index : int
            the index of the particle within the interaction (between 0 and getNumParticlesPerSet())
        types : set< int >
            the allowed types for the specified particle
        """
        return _openmm.CustomManyParticleForce_setTypeFilter(self, index, types)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomManyParticleForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomManyParticleForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomManyParticleForce_getTabulatedFunctionName(self, index)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-particle parameters. All other aspects of the Force (the energy function, nonbonded method, cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Also, this method cannot be used to add new particles, only to change the parameters of existing ones.
        """
        return _openmm.CustomManyParticleForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomManyParticleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, particlesPerSet, energy) -> CustomManyParticleForce
        __init__(self, other) -> CustomManyParticleForce
        Create a CustomManyParticleForce.

        Parameters
        ----------
        particlesPerSet : int
            the number of particles in each set for which the energy is evaluated
        energy : string
            an algebraic expression giving the interaction energy of each triplet as a function of particle positions, inter-particle distances, angles, and any global and per-particle parameters
        """
        _openmm.CustomManyParticleForce_swiginit(self, _openmm.new_CustomManyParticleForce(*args))

# Register CustomManyParticleForce in _openmm:
_openmm.CustomManyParticleForce_swigregister(CustomManyParticleForce)

class CustomNonbondedForce(Force):
    r"""
    This class implements nonbonded interactions between particles. Unlike NonbondedForce, the functional form of the interaction is completely customizable, and may involve arbitrary algebraic expressions and tabulated functions. It may depend on the distance between particles, as well as on arbitrary global and per-particle parameters. It also optionally supports periodic boundary conditions and cutoffs for long range interactions.

    To use this class, create a CustomNonbondedForce object, passing an algebraic expression to the constructor that defines the interaction energy between each pair of particles. The expression may depend on r, the distance between the particles, as well as on any parameters you choose. Then call addPerParticleParameter() to define per-particle parameters, and addGlobalParameter() to define global parameters. The values of per-particle parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().

    Next, call addParticle() once for each particle in the System to set the values of its per-particle parameters. The number of particles for which you set parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    CustomNonbondedForce also lets you specify "exclusions", particular pairs of particles whose interactions should be omitted from force and energy calculations. This is most often used for particles that are bonded to each other.

    As an example, the following code creates a CustomNonbondedForce that implements a 12-6 Lennard-Jones potential:

    <tt>CustomNonbondedForce* force = new CustomNonbondedForce("4*epsilon*((sigma/r)^12-(sigma/r)^6); sigma=0.5*(sigma1+sigma2); epsilon=sqrt(epsilon1*epsilon2)");</tt>

    This force depends on two parameters: sigma and epsilon. The following code defines these as per-particle parameters:

    <tt><pre>
    force->addPerParticleParameter("sigma");
    force->addPerParticleParameter("epsilon");
    </pre></tt>

    The expression _must_ be symmetric with respect to the two particles. It typically will only be evaluated once for each pair of particles, and no guarantee is made about which particle will be identified as "particle 1". In the above example, the energy only depends on the products sigma1*sigma2 and epsilon1*epsilon2, both of which are unchanged if the labels 1 and 2 are reversed. In contrast, if it depended on the difference sigma1-sigma2, the results would be undefined, because reversing the labels 1 and 2 would change the energy.

    CustomNonbondedForce can operate in two modes. By default, it computes the interaction of every particle in the System with every other particle. Alternatively, you can restrict it to only a subset of particle pairs. To do this, specify one or more "interaction groups". An interaction group consists of two sets of particles that should interact with each other. Every particle in the first set interacts with every particle in the second set. For example, you might use this feature to compute a solute-solvent interaction energy, while omitting all interactions between two solute atoms or two solvent atoms.

    To create an interaction group, call addInteractionGroup(). You may add as many interaction groups as you want. Be aware of the following:

     - Exclusions are still taken into account, so the interactions between excluded pairs are omitted.
     - Likewise, a particle will never interact with itself, even if it appears in both sets of an interaction group.
     - If a particle pair appears in two different interaction groups, its interaction will be computed twice. This is sometimes useful, but be aware of it so you do not accidentally create unwanted duplicate interactions.
     - If you do not add any interaction groups to a CustomNonbondedForce, it operates in the default mode where every particle interacts with every other particle.

    When using a cutoff, by default the interaction is sharply truncated at the cutoff distance. Optionally you can instead use a switching function to make the interaction smoothly go to zero over a finite distance range. To enable this, call setUseSwitchingFunction(). You must also call setSwitchingDistance() to specify the distance at which the interaction should begin to decrease. The switching distance must be less than the cutoff distance. Of course, you could also incorporate the switching function directly into your energy expression, but there are several advantages to keeping it separate. It makes your energy expression simpler to write and understand. It allows you to use the same energy expression with or without a cutoff. Also, when using a long range correction (see below), separating out the switching function allows the correction to be calculated more accurately.

    Another optional feature of this class is to add a contribution to the energy which approximates the effect of all interactions beyond the cutoff in a periodic system. When running a simulation at constant pressure, this can improve the quality of the result. Call setUseLongRangeCorrection() to enable it.

    Computing the long range correction takes negligible work in each time step, but it does require an expensive precomputation at the start of the simulation. Furthermore, that precomputation must be repeated every time a global parameter changes (or when you modify per-particle parameters by calling updateParametersInContext()). This means that if parameters change frequently, the long range correction can be very slow. For this reason, it is disabled by default.

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise. The names of per-particle parameters have the suffix "1" or "2" appended to them to indicate the values for the two interacting particles. As seen in the above example, the expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator.

    In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by creating a TabulatedFunction object. That function can then appear in the expression.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomNonbondedForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.CustomNonbondedForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.CustomNonbondedForce_CutoffPeriodic
    

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomNonbondedForce
        __init__(self, rhs) -> CustomNonbondedForce
        Create a CustomNonbondedForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the interaction energy between two particles as a function of r, the distance between them, as well as any global and per-particle parameters
        """
        _openmm.CustomNonbondedForce_swiginit(self, _openmm.new_CustomNonbondedForce(*args))
    __swig_destroy__ = _openmm.delete_CustomNonbondedForce

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumParticles(self)

    def getNumExclusions(self):
        r"""
        getNumExclusions(self) -> int
        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomNonbondedForce_getNumExclusions(self)

    def getNumPerParticleParameters(self):
        r"""
        getNumPerParticleParameters(self) -> int
        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomNonbondedForce_getNumPerParticleParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomNonbondedForce_getNumGlobalParameters(self)

    def getNumTabulatedFunctions(self):
        r"""
        getNumTabulatedFunctions(self) -> int
        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumTabulatedFunctions(self)

    def getNumFunctions(self):
        r"""
        getNumFunctions(self) -> int
        Get the number of tabulated functions that have been defined.

         @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
        """
        return _openmm.CustomNonbondedForce_getNumFunctions(self)

    def getNumInteractionGroups(self):
        r"""
        getNumInteractionGroups(self) -> int
        Get the number of interaction groups that have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumInteractionGroups(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomNonbondedForce_getNumEnergyParameterDerivatives(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy between two particles
        """
        return _openmm.CustomNonbondedForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy between two particles
        """
        return _openmm.CustomNonbondedForce_setEnergyFunction(self, energy)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::CustomNonbondedForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomNonbondedForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomNonbondedForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.CustomNonbondedForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.CustomNonbondedForce_setCutoffDistance(self, distance)

    def getUseSwitchingFunction(self):
        r"""
        getUseSwitchingFunction(self) -> bool
        Get whether a switching function is applied to the interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.CustomNonbondedForce_getUseSwitchingFunction(self)

    def setUseSwitchingFunction(self, use):
        r"""
        setUseSwitchingFunction(self, use)
        Set whether a switching function is applied to the interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.CustomNonbondedForce_setUseSwitchingFunction(self, use)

    def getSwitchingDistance(self):
        r"""
        getSwitchingDistance(self) -> double
        Get the distance at which the switching function begins to reduce the interaction. This must be less than the cutoff distance.
        """
        val = _openmm.CustomNonbondedForce_getSwitchingDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setSwitchingDistance(self, distance):
        r"""
        setSwitchingDistance(self, distance)
        Set the distance at which the switching function begins to reduce the interaction. This must be less than the cutoff distance.
        """
        return _openmm.CustomNonbondedForce_setSwitchingDistance(self, distance)

    def getUseLongRangeCorrection(self):
        r"""
        getUseLongRangeCorrection(self) -> bool
        Get whether to add a correction to the energy to compensate for the cutoff and switching function. This has no effect if periodic boundary conditions are not used.
        """
        return _openmm.CustomNonbondedForce_getUseLongRangeCorrection(self)

    def setUseLongRangeCorrection(self, use):
        r"""
        setUseLongRangeCorrection(self, use)
        Set whether to add a correction to the energy to compensate for the cutoff and switching function. This has no effect if periodic boundary conditions are not used.
        """
        return _openmm.CustomNonbondedForce_setUseLongRangeCorrection(self, use)

    def addPerParticleParameter(self, name):
        r"""
        addPerParticleParameter(self, name) -> int
        Add a new per-particle parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomNonbondedForce_addPerParticleParameter(self, name)

    def getPerParticleParameterName(self, index):
        r"""
        getPerParticleParameterName(self, index) -> std::string const &
        Get the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomNonbondedForce_getPerParticleParameterName(self, index)

    def setPerParticleParameterName(self, index, name):
        r"""
        setPerParticleParameterName(self, index, name)
        Set the name of a per-particle parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomNonbondedForce_setPerParticleParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomNonbondedForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomNonbondedForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomNonbondedForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomNonbondedForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomNonbondedForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomNonbondedForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomNonbondedForce_getEnergyParameterDerivativeName(self, index)

    def addParticle(self, *args):
        r"""
        addParticle(self, parameters=std::vector< double >()) -> int
        Add the nonbonded force parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        parameters : vector< double >
            the list of parameters for the new particle

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.CustomNonbondedForce_addParticle(self, *args)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        parameters : vector< double >
            the list of parameters for the specified particle
        """
        return _openmm.CustomNonbondedForce_getParticleParameters(self, index)

    def setParticleParameters(self, index, parameters):
        r"""
        setParticleParameters(self, index, parameters)
        Set the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        parameters : vector< double >
            the list of parameters for the specified particle
        """
        return _openmm.CustomNonbondedForce_setParticleParameters(self, index, parameters)

    def addExclusion(self, particle1, particle2):
        r"""
        addExclusion(self, particle1, particle2) -> int
        Add a particle pair to the list of interactions that should be excluded.

        In many cases, you can use createExclusionsFromBonds() rather than adding each exclusion explicitly.

        Parameters
        ----------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair

        Returns
        -------
        int
            the index of the exclusion that was added
        """
        return _openmm.CustomNonbondedForce_addExclusion(self, particle1, particle2)

    def getExclusionParticles(self, index):
        r"""
        getExclusionParticles(self, index)
        Get the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to get particle indices

        Returns
        -------
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomNonbondedForce_getExclusionParticles(self, index)

    def setExclusionParticles(self, index, particle1, particle2):
        r"""
        setExclusionParticles(self, index, particle1, particle2)
        Set the particles in a pair whose interaction should be excluded.

        Parameters
        ----------
        index : int
            the index of the exclusion for which to set particle indices
        particle1 : int
            the index of the first particle in the pair
        particle2 : int
            the index of the second particle in the pair
        """
        return _openmm.CustomNonbondedForce_setExclusionParticles(self, index, particle1, particle2)

    def createExclusionsFromBonds(self, bonds, bondCutoff):
        r"""
        createExclusionsFromBonds(self, bonds, bondCutoff)
        Identify exclusions based on the molecular topology. Particles which are separated by up to a specified number of bonds are added as exclusions.

        Parameters
        ----------
        bonds : vector< std::pair< int, int > >
            the set of bonds based on which to construct exclusions. Each element specifies the indices of two particles that are bonded to each other.
        bondCutoff : int
            pairs of particles that are separated by this many bonds or fewer are added to the list of exclusions
        """
        return _openmm.CustomNonbondedForce_createExclusionsFromBonds(self, bonds, bondCutoff)

    def addTabulatedFunction(self, name, function):
        r"""
        addTabulatedFunction(self, name, function) -> int
        Add a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        name : string
            the name of the function as it appears in expressions
        function : TabulatedFunction *
            a TabulatedFunction object defining the function. The TabulatedFunction should have been created on the heap with the "new" operator. The Force takes over ownership of it, and deletes it when the Force itself is deleted.

        Returns
        -------
        int
            the index of the function that was added
        """

        if not function.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.CustomNonbondedForce_addTabulatedFunction(self, name, function)

        function.thisown=0


        return val


    def getTabulatedFunction(self, *args):
        r"""
        getTabulatedFunction(self, index) -> TabulatedFunction
        getTabulatedFunction(self, index) -> TabulatedFunction
        Get a reference to a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        TabulatedFunction
            the TabulatedFunction object defining the function
        """
        return _openmm.CustomNonbondedForce_getTabulatedFunction(self, *args)

    def getTabulatedFunctionName(self, index):
        r"""
        getTabulatedFunctionName(self, index) -> std::string const &
        Get the name of a tabulated function that may appear in the energy expression.

        Parameters
        ----------
        index : int
            the index of the function to get

        Returns
        -------
        string
            the name of the function as it appears in expressions
        """
        return _openmm.CustomNonbondedForce_getTabulatedFunctionName(self, index)

    def addFunction(self, name, values, min, max):
        r"""
        addFunction(self, name, values, min, max) -> int
        Add a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use addTabulatedFunction() instead.
        """
        return _openmm.CustomNonbondedForce_addFunction(self, name, values, min, max)

    def getFunctionParameters(self, index):
        r"""
        getFunctionParameters(self, index)
        Get the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use getTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomNonbondedForce_getFunctionParameters(self, index)

    def setFunctionParameters(self, index, name, values, min, max):
        r"""
        setFunctionParameters(self, index, name, values, min, max)
        Set the parameters for a tabulated function that may appear in the energy expression.

         @deprecated This method exists only for backward compatibility. Use setTabulatedFunctionParameters() instead. If the specified function is not a Continuous1DFunction, this throws an exception.
        """
        return _openmm.CustomNonbondedForce_setFunctionParameters(self, index, name, values, min, max)

    def addInteractionGroup(self, set1, set2):
        r"""
        addInteractionGroup(self, set1, set2) -> int
        Add an interaction group. An interaction will be computed between every particle in set1 and every particle in set2.

        Parameters
        ----------
        set1 : set< int >
            the first set of particles forming the interaction group
        set2 : set< int >
            the second set of particles forming the interaction group

        Returns
        -------
        int
            the index of the interaction group that was added
        """

        set1 = list(set1)
        set2 = list(set2)


        return _openmm.CustomNonbondedForce_addInteractionGroup(self, set1, set2)


    def getInteractionGroupParameters(self, index):
        r"""
        getInteractionGroupParameters(self, index)
        Get the parameters for an interaction group.

        Parameters
        ----------
        index : int
            the index of the interaction group for which to get parameters

        Returns
        -------
        set1 : set< int >
            the first set of particles forming the interaction group
        set2 : set< int >
            the second set of particles forming the interaction group
        """
        return _openmm.CustomNonbondedForce_getInteractionGroupParameters(self, index)

    def setInteractionGroupParameters(self, index, set1, set2):
        r"""
        setInteractionGroupParameters(self, index, set1, set2)
        Set the parameters for an interaction group.

        Parameters
        ----------
        index : int
            the index of the interaction group for which to set parameters
        set1 : set< int >
            the first set of particles forming the interaction group
        set2 : set< int >
            the second set of particles forming the interaction group
        """

        set1 = list(set1)
        set2 = list(set2)


        return _openmm.CustomNonbondedForce_setInteractionGroupParameters(self, index, set1, set2)


    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-particle parameters. All other aspects of the Force (the energy function, nonbonded method, cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Also, this method cannot be used to add new particles, only to change the parameters of existing ones.
        """
        return _openmm.CustomNonbondedForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomNonbondedForce_usesPeriodicBoundaryConditions(self)

# Register CustomNonbondedForce in _openmm:
_openmm.CustomNonbondedForce_swigregister(CustomNonbondedForce)

class CustomTorsionForce(Force):
    r"""
    This class implements interactions between sets of four particles that depend on the torsion angle between them. Unlike PeriodicTorsionForce, the functional form of the interaction is completely customizable, and may involve arbitrary algebraic expressions. In addition to the angle formed by the particles, it may depend on arbitrary global and per-torsion parameters.

    To use this class, create a CustomTorsionForce object, passing an algebraic expression to the constructor that defines the interaction energy between each set of particles. The expression may depend on theta, the torsion angle formed by the particles, as well as on any parameters you choose. Then call addPerTorsionParameter() to define per-torsion parameters, and addGlobalParameter() to define global parameters. The values of per-torsion parameters are specified as part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter(). Finally, call addTorsion() once for each torsion. After an torsion has been added, you can modify its parameters by calling setTorsionParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext(). Note that theta is guaranteed to be in the range [-pi,+pi], which may cause issues with force discontinuities if the energy function does not respect this domain.

    As an example, the following code creates a CustomTorsionForce that implements a periodic potential:

    <tt>CustomTorsionForce* force = new CustomTorsionForce("0.5*k*(1-cos(theta-theta0))");</tt>

    This force depends on two parameters: the spring constant k and equilibrium angle theta0. The following code defines these parameters:

    <tt><pre>
    force->addPerTorsionParameter("k");
    force->addPerTorsionParameter("theta0");
    </pre></tt>

    If a harmonic restraint is desired, it is important to be careful of the domain for theta, using an idiom like this:

    <tt>CustomTorsionForce* force = new CustomTorsionForce("0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535");</tt>

    This class also has the ability to compute derivatives of the potential energy with respect to global parameters. Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be computed. You can then query its value in a Context by calling getState() on it.

    Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumTorsions(self):
        r"""
        getNumTorsions(self) -> int
        Get the number of torsions for which force field parameters have been defined.
        """
        return _openmm.CustomTorsionForce_getNumTorsions(self)

    def getNumPerTorsionParameters(self):
        r"""
        getNumPerTorsionParameters(self) -> int
        Get the number of per-torsion parameters that the interaction depends on.
        """
        return _openmm.CustomTorsionForce_getNumPerTorsionParameters(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomTorsionForce_getNumGlobalParameters(self)

    def getNumEnergyParameterDerivatives(self):
        r"""
        getNumEnergyParameterDerivatives(self) -> int
        Get the number of global parameters with respect to which the derivative of the energy should be computed.
        """
        return _openmm.CustomTorsionForce_getNumEnergyParameterDerivatives(self)

    def getEnergyFunction(self):
        r"""
        getEnergyFunction(self) -> std::string const &
        Get the algebraic expression that gives the interaction energy for each torsion
        """
        return _openmm.CustomTorsionForce_getEnergyFunction(self)

    def setEnergyFunction(self, energy):
        r"""
        setEnergyFunction(self, energy)
        Set the algebraic expression that gives the interaction energy for each torsion
        """
        return _openmm.CustomTorsionForce_setEnergyFunction(self, energy)

    def addPerTorsionParameter(self, name):
        r"""
        addPerTorsionParameter(self, name) -> int
        Add a new per-torsion parameter that the interaction may depend on.

        Parameters
        ----------
        name : string
            the name of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomTorsionForce_addPerTorsionParameter(self, name)

    def getPerTorsionParameterName(self, index):
        r"""
        getPerTorsionParameterName(self, index) -> std::string const &
        Get the name of a per-torsion parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomTorsionForce_getPerTorsionParameterName(self, index)

    def setPerTorsionParameterName(self, index, name):
        r"""
        setPerTorsionParameterName(self, index, name)
        Set the name of a per-torsion parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomTorsionForce_setPerTorsionParameterName(self, index, name)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that the interaction may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.CustomTorsionForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomTorsionForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.CustomTorsionForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.CustomTorsionForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.CustomTorsionForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addEnergyParameterDerivative(self, name):
        r"""
        addEnergyParameterDerivative(self, name)
        Request that this Force compute the derivative of its energy with respect to a global parameter. The parameter must have already been added with addGlobalParameter().

        Parameters
        ----------
        name : string
            the name of the parameter
        """
        return _openmm.CustomTorsionForce_addEnergyParameterDerivative(self, name)

    def getEnergyParameterDerivativeName(self, index):
        r"""
        getEnergyParameterDerivativeName(self, index) -> std::string const &
        Get the name of a global parameter with respect to which this Force should compute the derivative of the energy.

        Parameters
        ----------
        index : int
            the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.CustomTorsionForce_getEnergyParameterDerivativeName(self, index)

    def addTorsion(self, *args):
        r"""
        addTorsion(self, particle1, particle2, particle3, particle4, parameters=std::vector< double >()) -> int
        Add a torsion term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        parameters : vector< double >
            the list of parameters for the new torsion

        Returns
        -------
        int
            the index of the torsion that was added
        """
        return _openmm.CustomTorsionForce_addTorsion(self, *args)

    def getTorsionParameters(self, index):
        r"""
        getTorsionParameters(self, index)
        Get the force field parameters for a torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        parameters : vector< double >
            the list of parameters for the torsion
        """
        return _openmm.CustomTorsionForce_getTorsionParameters(self, index)

    def setTorsionParameters(self, *args):
        r"""
        setTorsionParameters(self, index, particle1, particle2, particle3, particle4, parameters=std::vector< double >())
        Set the force field parameters for a torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to set parameters
        particle1 : int
            the index of the first particle connected by the torsion
        particle2 : int
            the index of the second particle connected by the torsion
        particle3 : int
            the index of the third particle connected by the torsion
        particle4 : int
            the index of the fourth particle connected by the torsion
        parameters : vector< double >
            the list of parameters for the torsion
        """
        return _openmm.CustomTorsionForce_setTorsionParameters(self, *args)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the values of per-torsion parameters. All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing the Context. The set of particles involved in a torsion cannot be changed, nor can new torsions be added.
        """
        return _openmm.CustomTorsionForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.CustomTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.CustomTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, energy) -> CustomTorsionForce
        __init__(self, other) -> CustomTorsionForce
        Create a CustomTorsionForce.

        Parameters
        ----------
        energy : string
            an algebraic expression giving the interaction energy between three particles as a function of theta, the torsion angle between them
        """
        _openmm.CustomTorsionForce_swiginit(self, _openmm.new_CustomTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_CustomTorsionForce

# Register CustomTorsionForce in _openmm:
_openmm.CustomTorsionForce_swigregister(CustomTorsionForce)

class Discrete1DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a discrete one dimensional function f(x). To evaluate it, x is rounded to the nearest integer and the table element with that index is returned. If the index is outside the range [0, size), the result is undefined."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, values):
        r"""
        __init__(self, values) -> Discrete1DFunction
        This is a TabulatedFunction that computes a discrete one dimensional function f(x). To evaluate it, x is rounded to the nearest integer and the table element with that index is returned. If the index is outside the range [0, size), the result is undefined.
        """
        _openmm.Discrete1DFunction_swiginit(self, _openmm.new_Discrete1DFunction(values))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Discrete1DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, values):
        r"""setFunctionParameters(self, values)"""
        return _openmm.Discrete1DFunction_setFunctionParameters(self, values)

    def Copy(self):
        r"""
        Copy(self) -> Discrete1DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Discrete1DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Discrete1DFunction

# Register Discrete1DFunction in _openmm:
_openmm.Discrete1DFunction_swigregister(Discrete1DFunction)

class Discrete2DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a discrete two dimensional function f(x,y). To evaluate it, x and y are each rounded to the nearest integer and the table element with those indices is returned. If either index is outside the range [0, size), the result is undefined."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, values):
        r"""
        __init__(self, xsize, ysize, values) -> Discrete2DFunction
        This is a TabulatedFunction that computes a discrete two dimensional function f(x,y). To evaluate it, x and y are each rounded to the nearest integer and the table element with those indices is returned. If either index is outside the range [0, size), the result is undefined.
        """
        _openmm.Discrete2DFunction_swiginit(self, _openmm.new_Discrete2DFunction(xsize, ysize, values))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Discrete2DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, xsize, ysize, values):
        r"""setFunctionParameters(self, xsize, ysize, values)"""
        return _openmm.Discrete2DFunction_setFunctionParameters(self, xsize, ysize, values)

    def Copy(self):
        r"""
        Copy(self) -> Discrete2DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Discrete2DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Discrete2DFunction

# Register Discrete2DFunction in _openmm:
_openmm.Discrete2DFunction_swigregister(Discrete2DFunction)

class Discrete3DFunction(TabulatedFunction):
    r"""This is a TabulatedFunction that computes a discrete three dimensional function f(x,y,z). To evaluate it, x, y, and z are each rounded to the nearest integer and the table element with those indices is returned. If any index is outside the range [0, size), the result is undefined."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, zsize, values):
        r"""
        __init__(self, xsize, ysize, zsize, values) -> Discrete3DFunction
        This is a TabulatedFunction that computes a discrete three dimensional function f(x,y,z). To evaluate it, x, y, and z are each rounded to the nearest integer and the table element with those indices is returned. If any index is outside the range [0, size), the result is undefined.
        """
        _openmm.Discrete3DFunction_swiginit(self, _openmm.new_Discrete3DFunction(xsize, ysize, zsize, values))

    def getFunctionParameters(self):
        r"""getFunctionParameters(self)"""
        return _openmm.Discrete3DFunction_getFunctionParameters(self)

    def setFunctionParameters(self, xsize, ysize, zsize, values):
        r"""setFunctionParameters(self, xsize, ysize, zsize, values)"""
        return _openmm.Discrete3DFunction_setFunctionParameters(self, xsize, ysize, zsize, values)

    def Copy(self):
        r"""
        Copy(self) -> Discrete3DFunction
        @deprecated This will be removed in a future release.
        """
        return _openmm.Discrete3DFunction_Copy(self)
    __swig_destroy__ = _openmm.delete_Discrete3DFunction

# Register Discrete3DFunction in _openmm:
_openmm.Discrete3DFunction_swigregister(Discrete3DFunction)

class DrudeForce(Force):
    r"""
    This class implements forces that are specific to Drude oscillators. There are two distinct forces it applies: an anisotropic harmonic force connecting each Drude particle to its parent particle; and a screened Coulomb interaction between specific pairs of dipoles. The latter is typically used between closely bonded particles whose Coulomb interaction would otherwise be fully excluded.

    To use this class, create a DrudeForce object, then call addParticle() once for each Drude particle in the System to define its parameters. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext(). Likewise, call addScreenedPair() for each pair of dipoles (each dipole consisting of a Drude particle and its parent) that should be computed.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.DrudeForce_getNumParticles(self)

    def getNumScreenedPairs(self):
        r"""
        getNumScreenedPairs(self) -> int
        Get the number of special interactions that should be calculated differently from other interactions.
        """
        return _openmm.DrudeForce_getNumScreenedPairs(self)

    def addParticle(self, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34):
        r"""
        addParticle(self, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34) -> int
        Add a Drude particle to which forces should be applied.

        Parameters
        ----------
        particle : int
            the index within the System of the Drude particle
        particle1 : int
            the index within the System of the particle to which the Drude particle is attached
        particle2 : int
            the index within the System of the second particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso12 will be ignored.
        particle3 : int
            the index within the System of the third particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        particle4 : int
            the index within the System of the fourth particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        charge : double
            The charge on the Drude particle
        polarizability : double
            The isotropic polarizability
        aniso12 : double
            The scale factor for the polarizability along the direction defined by particle1 and particle2
        aniso34 : double
            The scale factor for the polarizability along the direction defined by particle3 and particle4

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.DrudeForce_addParticle(self, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the parameters for a Drude particle.

        Parameters
        ----------
        index : int
            the index of the Drude particle for which to get parameters

        Returns
        -------
        particle : int
            the index within the System of the Drude particle
        particle1 : int
            the index within the System of the particle to which the Drude particle is attached
        particle2 : int
            the index within the System of the second particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso12 will be ignored.
        particle3 : int
            the index within the System of the third particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        particle4 : int
            the index within the System of the fourth particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        charge : double
            The charge on the Drude particle
        polarizability : double
            The isotropic polarizability
        aniso12 : double
            The scale factor for the polarizability along the direction defined by particle1 and particle2
        aniso34 : double
            The scale factor for the polarizability along the direction defined by particle3 and particle4
        """
        val = _openmm.DrudeForce_getParticleParameters(self, index)

        val[5]=unit.Quantity(val[5], unit.elementary_charge)
        val[6]=unit.Quantity(val[6], unit.nanometer**3)


        return val


    def setParticleParameters(self, index, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34):
        r"""
        setParticleParameters(self, index, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34)
        Set the parameters for a Drude particle.

        Parameters
        ----------
        index : int
            the index of the Drude particle for which to set parameters
        particle : int
            the index within the System of the Drude particle
        particle1 : int
            the index within the System of the particle to which the Drude particle is attached
        particle2 : int
            the index within the System of the second particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso12 will be ignored.
        particle3 : int
            the index within the System of the third particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        particle4 : int
            the index within the System of the fourth particle used for defining anisotropic polarizability. This may be set to -1, in which case aniso34 will be ignored.
        charge : double
            The charge on the Drude particle
        polarizability : double
            The isotropic polarizability
        aniso12 : double
            The scale factor for the polarizability along the direction defined by particle1 and particle2
        aniso34 : double
            The scale factor for the polarizability along the direction defined by particle3 and particle4
        """
        return _openmm.DrudeForce_setParticleParameters(self, index, particle, particle1, particle2, particle3, particle4, charge, polarizability, aniso12, aniso34)

    def addScreenedPair(self, particle1, particle2, thole):
        r"""
        addScreenedPair(self, particle1, particle2, thole) -> int
        Add an interaction to the list of screened pairs.

        Parameters
        ----------
        particle1 : int
            the index within this Force of the first particle involved in the interaction
        particle2 : int
            the index within this Force of the second particle involved in the interaction
        thole : double
            the Thole screening factor

        Returns
        -------
        int
            the index of the screenedPair that was added
        """
        return _openmm.DrudeForce_addScreenedPair(self, particle1, particle2, thole)

    def getScreenedPairParameters(self, index):
        r"""
        getScreenedPairParameters(self, index)
        Get the force field parameters for screened pair.

        Parameters
        ----------
        index : int
            the index of the pair for which to get parameters

        Returns
        -------
        particle1 : int
            the index within this Force of the first particle involved in the interaction
        particle2 : int
            the index within this Force of the second particle involved in the interaction
        thole : double
            the Thole screening factor
        """
        return _openmm.DrudeForce_getScreenedPairParameters(self, index)

    def setScreenedPairParameters(self, index, particle1, particle2, thole):
        r"""
        setScreenedPairParameters(self, index, particle1, particle2, thole)
        Set the force field parameters for screened pair.

        Parameters
        ----------
        index : int
            the index of the pair for which to get parameters
        particle1 : int
            the index within this Force of the first particle involved in the interaction
        particle2 : int
            the index within this Force of the second particle involved in the interaction
        thole : double
            the Thole screening factor
        """
        return _openmm.DrudeForce_setScreenedPairParameters(self, index, particle1, particle2, thole)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the particle and screened pair parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() and setScreenedPairParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. It can be used to modify the numeric parameters associated with a particle or screened pair (polarizability, thole, etc.), but not the identities of the particles they involve. It also cannot be used to add new particles or screenedPairs, only to change the parameters of existing ones.
        """
        return _openmm.DrudeForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.DrudeForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> DrudeForce
        __init__(self, other) -> DrudeForce
        Create a DrudeForce.
        """
        _openmm.DrudeForce_swiginit(self, _openmm.new_DrudeForce(*args))
    __swig_destroy__ = _openmm.delete_DrudeForce

# Register DrudeForce in _openmm:
_openmm.DrudeForce_swigregister(DrudeForce)

class DrudeIntegrator(Integrator):
    r"""A base class to encapsulate features common to Drude integrators."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.DrudeIntegrator_step(self, steps)

    def getDrudeTemperature(self):
        r"""
        getDrudeTemperature(self) -> double
        Get the temperature of the heat bath applied to internal coordinates of Drude particles (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.DrudeIntegrator_getDrudeTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setDrudeTemperature(self, temp):
        r"""
        setDrudeTemperature(self, temp)
        Set the temperature of the heat bath applied to internal coordinates of Drude particles (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.DrudeIntegrator_setDrudeTemperature(self, temp)

    def getMaxDrudeDistance(self):
        r"""
        getMaxDrudeDistance(self) -> double
        Get the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
        """
        val = _openmm.DrudeIntegrator_getMaxDrudeDistance(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setMaxDrudeDistance(self, distance):
        r"""
        setMaxDrudeDistance(self, distance)
        Set the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
        """
        return _openmm.DrudeIntegrator_setMaxDrudeDistance(self, distance)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.DrudeIntegrator_setRandomNumberSeed(self, seed)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.DrudeIntegrator_getRandomNumberSeed(self)

    def __init__(self, *args):
        r"""
        __init__(self, stepSize) -> DrudeIntegrator
        __init__(self, other) -> DrudeIntegrator
        Create a DrudeSCFIntegrator.

        Parameters
        ----------
        stepSize : double
            the step size with which to integrator the system (in picoseconds)
        """
        _openmm.DrudeIntegrator_swiginit(self, _openmm.new_DrudeIntegrator(*args))
    __swig_destroy__ = _openmm.delete_DrudeIntegrator

# Register DrudeIntegrator in _openmm:
_openmm.DrudeIntegrator_swigregister(DrudeIntegrator)

class DrudeLangevinIntegrator(DrudeIntegrator):
    r"""
    This Integrator simulates systems that include Drude particles. It applies two different Langevin thermostats to different parts of the system. The first is applied to ordinary particles (ones that are not part of a Drude particle pair), as well as to the center of mass of each Drude particle pair. A second thermostat, typically with a much lower temperature, is applied to the relative internal displacement of each pair.

    This integrator can optionally set an upper limit on how far any Drude particle is ever allowed to get from its parent particle. This can sometimes help to improve stability. The limit is enforced with a hard wall constraint.

    This Integrator requires the System to include a DrudeForce, which it uses to identify the Drude particles.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the main heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.DrudeLangevinIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the main heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.DrudeLangevinIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the main heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.DrudeLangevinIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the main heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.DrudeLangevinIntegrator_setFriction(self, coeff)

    def getDrudeFriction(self):
        r"""
        getDrudeFriction(self) -> double
        Get the friction coefficient which determines how strongly the internal coordinates of Drude particles are coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.DrudeLangevinIntegrator_getDrudeFriction(self)

        val=unit.Quantity(val, unit.picosecond**-1)


        return val


    def setDrudeFriction(self, coeff):
        r"""
        setDrudeFriction(self, coeff)
        Set the friction coefficient which determines how strongly the internal coordinates of Drude particles are coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.DrudeLangevinIntegrator_setDrudeFriction(self, coeff)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.DrudeLangevinIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, frictionCoeff, drudeTemperature, drudeFrictionCoeff, stepSize) -> DrudeLangevinIntegrator
        __init__(self, other) -> DrudeLangevinIntegrator
        Create a DrudeLangevinIntegrator.

        Parameters
        ----------
        temperature : double
            the temperature of the main heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the main heat bath (in inverse picoseconds)
        drudeTemperature : double
            the temperature of the heat bath applied to internal coordinates of Drude particles (in Kelvin)
        drudeFrictionCoeff : double
            the friction coefficient which couples the system to the heat bath applied to internal coordinates of Drude particles (in inverse picoseconds)
        stepSize : double
            the step size with which to integrator the system (in picoseconds)
        """
        _openmm.DrudeLangevinIntegrator_swiginit(self, _openmm.new_DrudeLangevinIntegrator(*args))
    __swig_destroy__ = _openmm.delete_DrudeLangevinIntegrator

# Register DrudeLangevinIntegrator in _openmm:
_openmm.DrudeLangevinIntegrator_swigregister(DrudeLangevinIntegrator)

class NoseHooverIntegrator(Integrator):
    r"""This is an Integrator which simulates a System using one or more Nose Hoover chain thermostats, using the "middle" leapfrog propagation algorithm described in J. Phys. Chem. A 2019, 123, 6056-6079."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_NoseHooverIntegrator

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.NoseHooverIntegrator_step(self, steps)

    def addThermostat(self, temperature, collisionFrequency, chainLength, numMTS, numYoshidaSuzuki):
        r"""
        addThermostat(self, temperature, collisionFrequency, chainLength, numMTS, numYoshidaSuzuki) -> int
        Add a simple Nose-Hoover Chain thermostat to control the temperature of the full system

        Parameters
        ----------
        temperature : double
            the target temperature for the system.
        collisionFrequency : double
            the frequency of the interaction with the heat bath (in 1/ps).
        chainLength : int
            the number of beads in the Nose-Hoover chain
        numMTS : int
            the number of step in the multiple time step chain propagation algorithm.
        numYoshidaSuzuki : int
            the number of terms in the Yoshida-Suzuki multi time step decomposition used in the chain propagation algorithm (must be 1, 3, 5, or 7).
        """

        if unit.is_quantity(temperature):
            temperature = temperature.value_in_unit(unit.kelvin)
        if unit.is_quantity(collisionFrequency):
            collisionFrequency = collisionFrequency.value_in_unit(unit.picosecond**-1)


        return _openmm.NoseHooverIntegrator_addThermostat(self, temperature, collisionFrequency, chainLength, numMTS, numYoshidaSuzuki)


    def addSubsystemThermostat(self, thermostatedParticles, thermostatedPairs, temperature, collisionFrequency, relativeTemperature, relativeCollisionFrequency, chainLength=3, numMTS=3, numYoshidaSuzuki=7):
        r"""
        addSubsystemThermostat(self, thermostatedParticles, thermostatedPairs, temperature, collisionFrequency, relativeTemperature, relativeCollisionFrequency, chainLength=3, numMTS=3, numYoshidaSuzuki=7) -> int
        Add a Nose-Hoover Chain thermostat to control the temperature of a collection of atoms and/or pairs of connected atoms within the full system. A list of atoms defining the atoms to be thermostated is provided and the thermostat will only control members of that list. Additionally a list of pairs of connected atoms may be provided; in this case both the center of mass absolute motion of each pair is controlled as well as their motion relative to each other, which is independently thermostated. If both the list of thermostated particles and thermostated pairs are empty all particles will be thermostated.

        Parameters
        ----------
        thermostatedParticles : vector< int >
            list of particle ids to be thermostated.
        thermostatedPairs : vector< std::pair< int, int > >
            a list of pairs of connected atoms whose absolute center of mass motion and motion relative to one another will be independently thermostated.
        temperature : double
            the target temperature for each pair's absolute of center of mass motion.
        collisionFrequency : double
            the frequency of the interaction with the heat bath for the pairs' center of mass motion (in 1/ps).
        relativeTemperature : double
            the target temperature for each pair's relative motion.
        relativeCollisionFrequency : double
            the frequency of the interaction with the heat bath for the pairs' relative motion (in 1/ps).
        chainLength : int
            the number of beads in the Nose-Hoover chain.
        numMTS : int
            the number of step in the multiple time step chain propagation algorithm.
        numYoshidaSuzuki : int
            the number of terms in the Yoshida-Suzuki multi time step decomposition used in the chain propagation algorithm (must be 1, 3, 5, or 7).
        """

        if unit.is_quantity(temperature):
            temperature = temperature.value_in_unit(unit.kelvin)
        if unit.is_quantity(collisionFrequency):
            collisionFrequency = collisionFrequency.value_in_unit(unit.picosecond**-1)
        if unit.is_quantity(relativeTemperature):
            relativeTemperature = relativeTemperature.value_in_unit(unit.kelvin)
        if unit.is_quantity(relativeCollisionFrequency):
            relativeCollisionFrequency = relativeCollisionFrequency.value_in_unit(unit.picosecond**-1)


        return _openmm.NoseHooverIntegrator_addSubsystemThermostat(self, thermostatedParticles, thermostatedPairs, temperature, collisionFrequency, relativeTemperature, relativeCollisionFrequency, chainLength, numMTS, numYoshidaSuzuki)


    def getTemperature(self, chainID=0):
        r"""
        getTemperature(self, chainID=0) -> double
        Get the temperature of the i-th chain for controling absolute particle motion (in Kelvin).

        Parameters
        ----------
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).

        Returns
        -------
        double
            the temperature.
        """
        val = _openmm.NoseHooverIntegrator_getTemperature(self, chainID)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temperature, chainID=0):
        r"""
        setTemperature(self, temperature, chainID=0)
        set the (absolute motion) temperature of the i-th chain.

        Parameters
        ----------
        temperature : double
            the temperature for the Nose-Hoover chain thermostat (in Kelvin).
        chainID : int
            The id of the Nose-Hoover chain thermostat for which the temperature is set (default=0).
        """

        if unit.is_quantity(temperature):
            temperature = temperature.value_in_unit(unit.kelvin)


        return _openmm.NoseHooverIntegrator_setTemperature(self, temperature, chainID)


    def getRelativeTemperature(self, chainID=0):
        r"""
        getRelativeTemperature(self, chainID=0) -> double
        Get the temperature of the i-th chain for controling pairs' relative particle motion (in Kelvin).

        Parameters
        ----------
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).

        Returns
        -------
        double
            the temperature.
        """
        val = _openmm.NoseHooverIntegrator_getRelativeTemperature(self, chainID)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setRelativeTemperature(self, temperature, chainID=0):
        r"""
        setRelativeTemperature(self, temperature, chainID=0)
        set the (relative pair motion) temperature of the i-th chain.

        Parameters
        ----------
        temperature : double
            the temperature for the Nose-Hoover chain thermostat (in Kelvin).
        chainID : int
            The id of the Nose-Hoover chain thermostat for which the temperature is set (default=0).
        """

        if unit.is_quantity(temperature):
            temperature = temperature.value_in_unit(unit.kelvin)


        return _openmm.NoseHooverIntegrator_setRelativeTemperature(self, temperature, chainID)


    def getCollisionFrequency(self, chainID=0):
        r"""
        getCollisionFrequency(self, chainID=0) -> double
        Get the collision frequency for absolute motion of the i-th chain (in 1/picosecond).

        Parameters
        ----------
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).

        Returns
        -------
        double
            the collision frequency.
        """
        val = _openmm.NoseHooverIntegrator_getCollisionFrequency(self, chainID)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setCollisionFrequency(self, frequency, chainID=0):
        r"""
        setCollisionFrequency(self, frequency, chainID=0)
        Set the collision frequency for absolute motion of the i-th chain.

        Parameters
        ----------
        frequency : double
            the collision frequency in picosecond.
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).
        """

        if unit.is_quantity(frequency):
            frequency = frequency.value_in_unit(unit.picosecond**-1)


        return _openmm.NoseHooverIntegrator_setCollisionFrequency(self, frequency, chainID)


    def getRelativeCollisionFrequency(self, chainID=0):
        r"""
        getRelativeCollisionFrequency(self, chainID=0) -> double
        Get the collision frequency for pairs' relative motion of the i-th chain (in 1/picosecond).

        Parameters
        ----------
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).

        Returns
        -------
        double
            the collision frequency.
        """
        val = _openmm.NoseHooverIntegrator_getRelativeCollisionFrequency(self, chainID)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setRelativeCollisionFrequency(self, frequency, chainID=0):
        r"""
        setRelativeCollisionFrequency(self, frequency, chainID=0)
        Set the collision frequency for pairs' relative motion of the i-th chain.

        Parameters
        ----------
        frequency : double
            the collision frequency in picosecond.
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).
        """

        if unit.is_quantity(frequency):
            frequency = frequency.value_in_unit(unit.picosecond**-1)


        return _openmm.NoseHooverIntegrator_setRelativeCollisionFrequency(self, frequency, chainID)


    def computeHeatBathEnergy(self):
        r"""
        computeHeatBathEnergy(self) -> double
        Compute the total (potential + kinetic) heat bath energy for all heat baths associated with this integrator, at the current time.
        """
        val = _openmm.NoseHooverIntegrator_computeHeatBathEnergy(self)

        val=unit.Quantity(val, unit.kilojoules_per_mole)


        return val


    def getNumThermostats(self):
        r"""
        getNumThermostats(self) -> int
        Get the number of Nose-Hoover chains registered with this integrator.
        """
        return _openmm.NoseHooverIntegrator_getNumThermostats(self)

    def getThermostat(self, chainID=0):
        r"""
        getThermostat(self, chainID=0) -> NoseHooverChain
        Get the NoseHooverChain thermostat

        Parameters
        ----------
        chainID : int
            the index of the Nose-Hoover chain thermostat (default=0).
        """
        return _openmm.NoseHooverIntegrator_getThermostat(self, chainID)

    def hasSubsystemThermostats(self):
        r"""
        hasSubsystemThermostats(self) -> bool
        Return false, if this integrator was set up with the 'default constructor' that thermostats the whole system, true otherwise. Required for serialization.
        """
        return _openmm.NoseHooverIntegrator_hasSubsystemThermostats(self)

    def getMaximumPairDistance(self):
        r"""
        getMaximumPairDistance(self) -> double
        Gets the maximum distance (in nm) that a connected pair may stray from each other. If zero, there are no constraints on the intra-pair separation.
        """
        val = _openmm.NoseHooverIntegrator_getMaximumPairDistance(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setMaximumPairDistance(self, distance):
        r"""
        setMaximumPairDistance(self, distance)
        Sets the maximum distance (in nm) that a connected pair may stray from each other, implemented using a hard wall. If set to zero, the hard wall constraint is omited and the pairs are free to be separated by any distance.
        """

        if unit.is_quantity(distance):
            distance = distance.value_in_unit(unit.nanometer)


        return _openmm.NoseHooverIntegrator_setMaximumPairDistance(self, distance)


    def __init__(self, *args):
        r"""
        __init__(self, stepSize) -> NoseHooverIntegrator
        __init__(self, temperature, collisionFrequency, stepSize, chainLength=3, numMTS=3, numYoshidaSuzuki=7) -> NoseHooverIntegrator
        __init__(self, other) -> NoseHooverIntegrator
        Create a NoseHooverIntegrator.

        Parameters
        ----------
        temperature : double
            the target temperature for the system (in Kelvin).
        collisionFrequency : double
            the frequency of the interaction with the heat bath (in inverse picoseconds).
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        chainLength : int
            the number of beads in the Nose-Hoover chain.
        numMTS : int
            the number of step in the multiple time step chain propagation algorithm.
        numYoshidaSuzuki : int
            the number of terms in the Yoshida-Suzuki multi time step decomposition used in the chain propagation algorithm (must be 1, 3, 5, or 7).
        """
        _openmm.NoseHooverIntegrator_swiginit(self, _openmm.new_NoseHooverIntegrator(*args))

# Register NoseHooverIntegrator in _openmm:
_openmm.NoseHooverIntegrator_swigregister(NoseHooverIntegrator)

class DrudeNoseHooverIntegrator(NoseHooverIntegrator):
    r"""
    This Integrator simulates systems that include Drude particles. It applies two different Nose-Hoover chain thermostats to the different parts of the system. The first is applied to ordinary particles (ones that are not part of a Drude particle pair), as well as to the center of mass of each Drude particle pair. A second thermostat, typically with a much lower temperature, is applied to the relative internal displacement of each pair.

    This Integrator requires the System to include a DrudeForce, which it uses to identify the Drude particles.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_DrudeNoseHooverIntegrator

    def initialize(self, context):
        r"""
        initialize(self, context)
        This will be called by the Context when it is created. It informs the Integrator of what context it will be integrating, and gives it a chance to do any necessary initialization. It will also get called again if the application calls reinitialize() on the Context.
        """
        return _openmm.DrudeNoseHooverIntegrator_initialize(self, context)

    def getMaxDrudeDistance(self):
        r"""
        getMaxDrudeDistance(self) -> double
        Get the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
        """
        val = _openmm.DrudeNoseHooverIntegrator_getMaxDrudeDistance(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setMaxDrudeDistance(self, distance):
        r"""
        setMaxDrudeDistance(self, distance)
        Set the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
        """

        if unit.is_quantity(distance):
            distance = distance.value_in_unit(unit.nanometer)


        return _openmm.DrudeNoseHooverIntegrator_setMaxDrudeDistance(self, distance)


    def computeDrudeKineticEnergy(self):
        r"""
        computeDrudeKineticEnergy(self) -> double
        Compute the kinetic energy of the drude particles at the current time.
        """
        return _openmm.DrudeNoseHooverIntegrator_computeDrudeKineticEnergy(self)

    def computeTotalKineticEnergy(self):
        r"""
        computeTotalKineticEnergy(self) -> double
        Compute the kinetic energy of all (real and drude) particles at the current time.
        """
        return _openmm.DrudeNoseHooverIntegrator_computeTotalKineticEnergy(self)

    def getVelocitiesForTemperature(self, system, temperature, randomSeed):
        r"""
        getVelocitiesForTemperature(self, system, temperature, randomSeed) -> std::vector< Vec3,std::allocator< Vec3 > >
        Return a list of velocities normally distributed around a target temperature, with the Drude temperatures assigned according to the Drude temperature assigned to the integrator.

        Parameters
        ----------
        system : System
            the system whose velocities are to be initialized.
        temperature : double
            the target temperature in Kelvin.
        randomSeed : int
            the random number seed to use when selecting velocities
        """
        val = _openmm.DrudeNoseHooverIntegrator_getVelocitiesForTemperature(self, system, temperature, randomSeed)

        val=unit.Quantity(val, unit.nanometers / unit.picosecond)


        return val


    def __init__(self, *args):
        r"""
        __init__(self, temperature, collisionFrequency, drudeTemperature, drudeCollisionFrequency, stepSize, chainLength=3, numMTS=3, numYoshidaSuzuki=7) -> DrudeNoseHooverIntegrator
        __init__(self, other) -> DrudeNoseHooverIntegrator
        Create a DrudeNoseHooverIntegrator.

        Parameters
        ----------
        temperature : double
            the target temperature for the system (in Kelvin).
        collisionFrequency : double
            the frequency of the system's interaction with the heat bath (in inverse picoseconds).
        drudeTemperature : double
            the target temperature for the Drude particles, relative to their parent atom (in Kelvin).
        drudeCollisionFrequency : double
            the frequency of the drude particles' interaction with the heat bath (in inverse picoseconds).
        stepSize : double
            the step size with which to integrator the system (in picoseconds)
        chainLength : int
            the number of beads in the Nose-Hoover chain.
        numMTS : int
            the number of step in the multiple time step chain propagation algorithm.
        numYoshidaSuzuki : int
            the number of terms in the Yoshida-Suzuki multi time step decomposition used in the chain propagation algorithm (must be 1, 3, or 5).
        """
        _openmm.DrudeNoseHooverIntegrator_swiginit(self, _openmm.new_DrudeNoseHooverIntegrator(*args))

# Register DrudeNoseHooverIntegrator in _openmm:
_openmm.DrudeNoseHooverIntegrator_swigregister(DrudeNoseHooverIntegrator)

class DrudeSCFIntegrator(DrudeIntegrator):
    r"""
    This is a leap-frog Verlet Integrator that simulates systems with Drude particles. It uses the self-consistent field (SCF) method: at every time step, the positions of Drude particles are adjusted to minimize the potential energy.

    This Integrator requires the System to include a DrudeForce, which it uses to identify the Drude particles.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getMinimizationErrorTolerance(self):
        r"""
        getMinimizationErrorTolerance(self) -> double
        Get the error tolerance to use when minimizing the potential energy. This roughly corresponds to the maximum allowed force magnitude on the Drude particles after minimization.

        Returns
        -------
        double
            the error tolerance to use, measured in kJ/mol/nm
        """
        val = _openmm.DrudeSCFIntegrator_getMinimizationErrorTolerance(self)

        val=unit.Quantity(val, unit.kilojoules_per_mole/unit.nanometer)


        return val


    def setMinimizationErrorTolerance(self, tol):
        r"""
        setMinimizationErrorTolerance(self, tol)
        Set the error tolerance to use when minimizing the potential energy. This roughly corresponds to the maximum allowed force magnitude on the Drude particles after minimization.

        Parameters
        ----------
        tol : double
            the error tolerance to use, measured in kJ/mol/nm
        """
        return _openmm.DrudeSCFIntegrator_setMinimizationErrorTolerance(self, tol)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.DrudeSCFIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, stepSize) -> DrudeSCFIntegrator
        __init__(self, other) -> DrudeSCFIntegrator
        Create a DrudeSCFIntegrator.

        Parameters
        ----------
        stepSize : double
            the step size with which to integrator the system (in picoseconds)
        """
        _openmm.DrudeSCFIntegrator_swiginit(self, _openmm.new_DrudeSCFIntegrator(*args))
    __swig_destroy__ = _openmm.delete_DrudeSCFIntegrator

# Register DrudeSCFIntegrator in _openmm:
_openmm.DrudeSCFIntegrator_swigregister(DrudeSCFIntegrator)

class GayBerneForce(Force):
    r"""
    This class implements the Gay-Berne anisotropic potential. This is similar to a Lennard-Jones potential, but it represents the particles as ellipsoids rather than point particles. In addition to the standard sigma and epsilon parameters, each particle has three widths sx, sy, and sz that give the diameter of the ellipsoid along each axis. It also has three scale factors ex, ey, and ez that scale the strength of the interaction along each axis. You can think of this force as a Lennard-Jones interaction computed based on the distance between the nearest points on two ellipsoids. The scale factors act as multipliers for epsilon along each axis, so the strength of the interaction along the ellipsoid's x axis is multiplied by ex, and likewise for the other axes. If two particles each have all their widths set to sigma and all their scale factors set to 1, the interaction simplifies to a standard Lennard-Jones force between point particles.

    The orientation of a particle's ellipsoid is determined based on the positions of two other particles. The vector to the first particle sets the direction of the x axis. The vector to the second particle (after subtracting out any x component) sets the direction of the y axis. If the ellipsoid is axially symmetric (sy=sz and ey=ez), you can omit the second particle and define only an x axis direction. If the ellipsoid is a sphere (all three widths and all three scale factors are equal), both particles can be omitted.

    To determine the values of sigma and epsilon for an interaction, this class uses Lorentz-Berthelot combining rules: it takes the arithmetic mean of the sigmas and the geometric mean of the epsilons for the two interacting particles. You also can specify "exceptions", particular pairs of particles for which different values should be used.

    To use this class, create a GayBerneForce object, then call addParticle() once for each particle in the System to define its parameters. The number of particles for which you define parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    When using a cutoff, by default interactions are sharply truncated at the cutoff distance. Optionally you can instead use a switching function to make the interaction smoothly go to zero over a finite distance range. To enable this, call setUseSwitchingFunction(). You must also call setSwitchingDistance() to specify the distance at which the interaction should begin to decrease. The switching distance must be less than the cutoff distance.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.GayBerneForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.GayBerneForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.GayBerneForce_CutoffPeriodic
    

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.GayBerneForce_getNumParticles(self)

    def getNumExceptions(self):
        r"""
        getNumExceptions(self) -> int
        Get the number of special interactions that should be calculated differently from other interactions.
        """
        return _openmm.GayBerneForce_getNumExceptions(self)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::GayBerneForce::NonbondedMethod
        Get the method used for handling long range interactions.
        """
        return _openmm.GayBerneForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range interactions.
        """
        return _openmm.GayBerneForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.GayBerneForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.GayBerneForce_setCutoffDistance(self, distance)

    def getUseSwitchingFunction(self):
        r"""
        getUseSwitchingFunction(self) -> bool
        Get whether a switching function is applied to the interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.GayBerneForce_getUseSwitchingFunction(self)

    def setUseSwitchingFunction(self, use):
        r"""
        setUseSwitchingFunction(self, use)
        Set whether a switching function is applied to the interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.GayBerneForce_setUseSwitchingFunction(self, use)

    def getSwitchingDistance(self):
        r"""
        getSwitchingDistance(self) -> double
        Get the distance at which the switching function begins to reduce the interaction. This must be less than the cutoff distance.
        """
        val = _openmm.GayBerneForce_getSwitchingDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setSwitchingDistance(self, distance):
        r"""
        setSwitchingDistance(self, distance)
        Set the distance at which the switching function begins to reduce the interaction. This must be less than the cutoff distance.
        """
        return _openmm.GayBerneForce_setSwitchingDistance(self, distance)

    def addParticle(self, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez):
        r"""
        addParticle(self, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez) -> int
        Add the parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        xparticle : int
            the index of the particle whose position defines the ellipsoid's x axis, or -1 if the ellipsoid is a sphere
        yparticle : int
            the index of the particle whose position defines the ellipsoid's y axis, or -1 if the ellipsoid is axially symmetric
        sx : double
            the diameter of the ellipsoid along its x axis
        sy : double
            the diameter of the ellipsoid along its y axis
        sz : double
            the diameter of the ellipsoid along its z axis
        ex : double
            the factor by which epsilon is scaled along the ellipsoid's x axis
        ey : double
            the factor by which epsilon is scaled along the ellipsoid's y axis
        ez : double
            the factor by which epsilon is scaled along the ellipsoid's z axis

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.GayBerneForce_addParticle(self, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        xparticle : int
            the index of the particle whose position defines the ellipsoid's x axis, or -1 if the ellipsoid is a sphere
        yparticle : int
            the index of the particle whose position defines the ellipsoid's y axis, or -1 if the ellipsoid is axially symmetric
        sx : double
            the diameter of the ellipsoid along its x axis
        sy : double
            the diameter of the ellipsoid along its y axis
        sz : double
            the diameter of the ellipsoid along its z axis
        ex : double
            the factor by which epsilon is scaled along the ellipsoid's x axis
        ey : double
            the factor by which epsilon is scaled along the ellipsoid's y axis
        ez : double
            the factor by which epsilon is scaled along the ellipsoid's z axis
        """
        val = _openmm.GayBerneForce_getParticleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.nanometer)
        val[1]=unit.Quantity(val[1], unit.kilojoule_per_mole)
        val[4]=unit.Quantity(val[4], unit.nanometer)
        val[5]=unit.Quantity(val[5], unit.nanometer)
        val[6]=unit.Quantity(val[6], unit.nanometer)


        return val


    def setParticleParameters(self, index, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez):
        r"""
        setParticleParameters(self, index, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez)
        Set the parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        xparticle : int
            the index of the particle whose position defines the ellipsoid's x axis, or -1 if the ellipsoid is a sphere
        yparticle : int
            the index of the particle whose position defines the ellipsoid's y axis, or -1 if the ellipsoid is axially symmetric
        sx : double
            the diameter of the ellipsoid along its x axis
        sy : double
            the diameter of the ellipsoid along its y axis
        sz : double
            the diameter of the ellipsoid along its z axis
        ex : double
            the factor by which epsilon is scaled along the ellipsoid's x axis
        ey : double
            the factor by which epsilon is scaled along the ellipsoid's y axis
        ez : double
            the factor by which epsilon is scaled along the ellipsoid's z axis
        """
        return _openmm.GayBerneForce_setParticleParameters(self, index, sigma, epsilon, xparticle, yparticle, sx, sy, sz, ex, ey, ez)

    def addException(self, particle1, particle2, sigma, epsilon, replace=False):
        r"""
        addException(self, particle1, particle2, sigma, epsilon, replace=False) -> int
        Add an interaction to the list of exceptions that should be calculated differently from other interactions. If epsilon is equal to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        Parameters
        ----------
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        replace : bool
            determines the behavior if there is already an exception for the same two particles. If true, the existing one is replaced. If false, an exception is thrown.

        Returns
        -------
        int
            the index of the exception that was added
        """
        return _openmm.GayBerneForce_addException(self, particle1, particle2, sigma, epsilon, replace)

    def getExceptionParameters(self, index):
        r"""
        getExceptionParameters(self, index)
        Get the force field parameters for an interaction that should be calculated differently from others.

        Parameters
        ----------
        index : int
            the index of the interaction for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        return _openmm.GayBerneForce_getExceptionParameters(self, index)

    def setExceptionParameters(self, index, particle1, particle2, sigma, epsilon):
        r"""
        setExceptionParameters(self, index, particle1, particle2, sigma, epsilon)
        Set the force field parameters for an interaction that should be calculated differently from others. If epsilon is equal to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        Parameters
        ----------
        index : int
            the index of the interaction for which to get parameters
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        sigma : double
            the sigma parameter (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        return _openmm.GayBerneForce_setExceptionParameters(self, index, particle1, particle2, sigma, epsilon)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the particle and exception parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() and setExceptionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the parameters of particles and exceptions. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Furthermore, only the sigma and epsilon values of an exception can be changed; the pair of particles involved in the exception cannot change. Likewise, the xparticle and yparticle defining the orientation of an ellipse cannot be changed. Finally, this method cannot be used to add new particles or exceptions, only to change the parameters of existing ones.
        """
        return _openmm.GayBerneForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.GayBerneForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> GayBerneForce
        __init__(self, other) -> GayBerneForce
        Create a GayBerneForce.
        """
        _openmm.GayBerneForce_swiginit(self, _openmm.new_GayBerneForce(*args))
    __swig_destroy__ = _openmm.delete_GayBerneForce

# Register GayBerneForce in _openmm:
_openmm.GayBerneForce_swigregister(GayBerneForce)

class GBSAOBCForce(Force):
    r"""
    This class implements an implicit solvation force using the GBSA-OBC model.

    To use this class, create a GBSAOBCForce object, then call addParticle() once for each particle in the System to define its parameters. The number of particles for which you define GBSA parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    When using this Force, the System should also include a NonbondedForce, and both objects must specify identical charges for all particles. Otherwise, the results will not be correct. Furthermore, if the nonbonded method is set to CutoffNonPeriodic or CutoffPeriodic, you should call setReactionFieldDielectric(1.0) on the NonbondedForce to turn off the reaction field approximation, which does not produce correct results when combined with GBSA.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.GBSAOBCForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.GBSAOBCForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.GBSAOBCForce_CutoffPeriodic
    

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles in the system.
        """
        return _openmm.GBSAOBCForce_getNumParticles(self)

    def addParticle(self, charge, radius, scalingFactor):
        r"""
        addParticle(self, charge, radius, scalingFactor) -> int
        Add the GBSA parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the GBSA radius of the particle, measured in nm
        scalingFactor : double
            the OBC scaling factor for the particle

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.GBSAOBCForce_addParticle(self, charge, radius, scalingFactor)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the force field parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the GBSA radius of the particle, measured in nm
        scalingFactor : double
            the OBC scaling factor for the particle
        """
        val = _openmm.GBSAOBCForce_getParticleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.elementary_charge)
        val[1]=unit.Quantity(val[1], unit.nanometer)


        return val


    def setParticleParameters(self, index, charge, radius, scalingFactor):
        r"""
        setParticleParameters(self, index, charge, radius, scalingFactor)
        Set the force field parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        charge : double
            the charge of the particle, measured in units of the proton charge
        radius : double
            the GBSA radius of the particle, measured in nm
        scalingFactor : double
            the OBC scaling factor for the particle
        """
        return _openmm.GBSAOBCForce_setParticleParameters(self, index, charge, radius, scalingFactor)

    def getSolventDielectric(self):
        r"""
        getSolventDielectric(self) -> double
        Get the dielectric constant for the solvent.
        """
        return _openmm.GBSAOBCForce_getSolventDielectric(self)

    def setSolventDielectric(self, dielectric):
        r"""
        setSolventDielectric(self, dielectric)
        Set the dielectric constant for the solvent.
        """
        return _openmm.GBSAOBCForce_setSolventDielectric(self, dielectric)

    def getSoluteDielectric(self):
        r"""
        getSoluteDielectric(self) -> double
        Get the dielectric constant for the solute.
        """
        return _openmm.GBSAOBCForce_getSoluteDielectric(self)

    def setSoluteDielectric(self, dielectric):
        r"""
        setSoluteDielectric(self, dielectric)
        Set the dielectric constant for the solute.
        """
        return _openmm.GBSAOBCForce_setSoluteDielectric(self, dielectric)

    def getSurfaceAreaEnergy(self):
        r"""
        getSurfaceAreaEnergy(self) -> double
        Get the energy scale for the surface energy term, measured in kJ/mol/nm^2.
        """
        val = _openmm.GBSAOBCForce_getSurfaceAreaEnergy(self)

        val=unit.Quantity(val, unit.kilojoule_per_mole/unit.nanometer/unit.nanometer)


        return val


    def setSurfaceAreaEnergy(self, energy):
        r"""
        setSurfaceAreaEnergy(self, energy)
        Set the energy scale for the surface energy term, measured in kJ/mol/nm^2.
        """
        return _openmm.GBSAOBCForce_setSurfaceAreaEnergy(self, energy)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::GBSAOBCForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.GBSAOBCForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.GBSAOBCForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.GBSAOBCForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.GBSAOBCForce_setCutoffDistance(self, distance)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the particle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-particle parameters. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Furthermore, this method cannot be used to add new particles, only to change the parameters of existing ones.
        """
        return _openmm.GBSAOBCForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.GBSAOBCForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> GBSAOBCForce
        __init__(self, other) -> GBSAOBCForce
        Create a GBSAOBCForce.
        """
        _openmm.GBSAOBCForce_swiginit(self, _openmm.new_GBSAOBCForce(*args))
    __swig_destroy__ = _openmm.delete_GBSAOBCForce

# Register GBSAOBCForce in _openmm:
_openmm.GBSAOBCForce_swigregister(GBSAOBCForce)

class HarmonicAngleForce(Force):
    r"""This class implements an interaction between groups of three particles that varies harmonically with the angle between them. To use it, create a HarmonicAngleForce object then call addAngle() once for each angle. After an angle has been added, you can modify its force field parameters by calling setAngleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext()."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumAngles(self):
        r"""
        getNumAngles(self) -> int
        Get the number of harmonic bond angle terms in the potential function
        """
        return _openmm.HarmonicAngleForce_getNumAngles(self)

    def addAngle(self, particle1, particle2, particle3, angle, k):
        r"""
        addAngle(self, particle1, particle2, particle3, angle, k) -> int
        Add an angle term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle forming the angle
        particle2 : int
            the index of the second particle forming the angle
        particle3 : int
            the index of the third particle forming the angle
        angle : double
            the equilibrium angle, measured in radians
        k : double
            the harmonic force constant for the angle, measured in kJ/mol/radian^2

        Returns
        -------
        int
            the index of the angle that was added
        """
        return _openmm.HarmonicAngleForce_addAngle(self, particle1, particle2, particle3, angle, k)

    def getAngleParameters(self, index):
        r"""
        getAngleParameters(self, index)
        Get the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle forming the angle
        particle2 : int
            the index of the second particle forming the angle
        particle3 : int
            the index of the third particle forming the angle
        angle : double
            the equilibrium angle, measured in radians
        k : double
            the harmonic force constant for the angle, measured in kJ/mol/radian^2
        """
        val = _openmm.HarmonicAngleForce_getAngleParameters(self, index)

        val[3]=unit.Quantity(val[3], unit.radian)
        val[4]=unit.Quantity(val[4], unit.kilojoule_per_mole/(unit.radian*unit.radian))


        return val


    def setAngleParameters(self, index, particle1, particle2, particle3, angle, k):
        r"""
        setAngleParameters(self, index, particle1, particle2, particle3, angle, k)
        Set the force field parameters for an angle term.

        Parameters
        ----------
        index : int
            the index of the angle for which to set parameters
        particle1 : int
            the index of the first particle forming the angle
        particle2 : int
            the index of the second particle forming the angle
        particle3 : int
            the index of the third particle forming the angle
        angle : double
            the equilibrium angle, measured in radians
        k : double
            the harmonic force constant for the angle, measured in kJ/mol/radian^2
        """
        return _openmm.HarmonicAngleForce_setAngleParameters(self, index, particle1, particle2, particle3, angle, k)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-angle parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-angle parameters. The set of particles involved in a angle cannot be changed, nor can new angles be added.
        """
        return _openmm.HarmonicAngleForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.HarmonicAngleForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.HarmonicAngleForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> HarmonicAngleForce
        __init__(self, other) -> HarmonicAngleForce
        Create a HarmonicAngleForce.
        """
        _openmm.HarmonicAngleForce_swiginit(self, _openmm.new_HarmonicAngleForce(*args))
    __swig_destroy__ = _openmm.delete_HarmonicAngleForce

# Register HarmonicAngleForce in _openmm:
_openmm.HarmonicAngleForce_swigregister(HarmonicAngleForce)

class HarmonicBondForce(Force):
    r"""This class implements an interaction between pairs of particles that varies harmonically with the distance between them. To use it, create a HarmonicBondForce object then call addBond() once for each bond. After a bond has been added, you can modify its force field parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext()."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumBonds(self):
        r"""
        getNumBonds(self) -> int
        Get the number of harmonic bond stretch terms in the potential function
        """
        return _openmm.HarmonicBondForce_getNumBonds(self)

    def addBond(self, particle1, particle2, length, k):
        r"""
        addBond(self, particle1, particle2, length, k) -> int
        Add a bond term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        k : double
            the harmonic force constant for the bond, measured in kJ/mol/nm^2

        Returns
        -------
        int
            the index of the bond that was added
        """
        return _openmm.HarmonicBondForce_addBond(self, particle1, particle2, length, k)

    def getBondParameters(self, index):
        r"""
        getBondParameters(self, index)
        Get the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        k : double
            the harmonic force constant for the bond, measured in kJ/mol/nm^2
        """
        val = _openmm.HarmonicBondForce_getBondParameters(self, index)

        val[2]=unit.Quantity(val[2], unit.nanometer)
        val[3]=unit.Quantity(val[3], unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer))


        return val


    def setBondParameters(self, index, particle1, particle2, length, k):
        r"""
        setBondParameters(self, index, particle1, particle2, length, k)
        Set the force field parameters for a bond term.

        Parameters
        ----------
        index : int
            the index of the bond for which to set parameters
        particle1 : int
            the index of the first particle connected by the bond
        particle2 : int
            the index of the second particle connected by the bond
        length : double
            the equilibrium length of the bond, measured in nm
        k : double
            the harmonic force constant for the bond, measured in kJ/mol/nm^2
        """
        return _openmm.HarmonicBondForce_setBondParameters(self, index, particle1, particle2, length, k)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-bond parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-bond parameters. The set of particles involved in a bond cannot be changed, nor can new bonds be added.
        """
        return _openmm.HarmonicBondForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.HarmonicBondForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.HarmonicBondForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> HarmonicBondForce
        __init__(self, other) -> HarmonicBondForce
        Create a HarmonicBondForce.
        """
        _openmm.HarmonicBondForce_swiginit(self, _openmm.new_HarmonicBondForce(*args))
    __swig_destroy__ = _openmm.delete_HarmonicBondForce

# Register HarmonicBondForce in _openmm:
_openmm.HarmonicBondForce_swigregister(HarmonicBondForce)

class HippoNonbondedForce(Force):
    r"""
    This class implements all nonbonded interactions in the HIPPO force field: electrostatics, induction, charge transfer, dispersion, and repulsion. Although some of these are conceptually distinct, they share parameters in common and are most efficiently computed together. For example, the same multipole definitions are used for both electrostatics and Pauli repulsion. Therefore, all of them are computed by a single Force object.

    To use it, create a HippoNonbondedForce object, then call addParticle() once for each particle. After an entry has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    You also can specify "exceptions", particular pairs of particles whose interactions should be reduced or completely omitted. Call addException() to define exceptions.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.HippoNonbondedForce_NoCutoff
    
    PME = _openmm.HippoNonbondedForce_PME
    
    ZThenX = _openmm.HippoNonbondedForce_ZThenX
    
    Bisector = _openmm.HippoNonbondedForce_Bisector
    
    ZBisect = _openmm.HippoNonbondedForce_ZBisect
    
    ThreeFold = _openmm.HippoNonbondedForce_ThreeFold
    
    ZOnly = _openmm.HippoNonbondedForce_ZOnly
    
    NoAxisType = _openmm.HippoNonbondedForce_NoAxisType
    

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles in the potential function.
        """
        return _openmm.HippoNonbondedForce_getNumParticles(self)

    def getNumExceptions(self):
        r"""
        getNumExceptions(self) -> int
        Get the number of exceptions.
        """
        return _openmm.HippoNonbondedForce_getNumExceptions(self)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::HippoNonbondedForce::NonbondedMethod
        Get the method used for handling long-range nonbonded interactions.
        """
        return _openmm.HippoNonbondedForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long-range nonbonded interactions.
        """
        return _openmm.HippoNonbondedForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.HippoNonbondedForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.HippoNonbondedForce_setCutoffDistance(self, distance)

    def getSwitchingDistance(self):
        r"""
        getSwitchingDistance(self) -> double
        Get the distance at which the switching function begins to reduce the repulsion and charge transfer interactions. This must be less than the cutoff distance.
        """
        val = _openmm.HippoNonbondedForce_getSwitchingDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setSwitchingDistance(self, distance):
        r"""
        setSwitchingDistance(self, distance)
        Set the distance at which the switching function begins to reduce the repulsion and charge transfer interactions. This must be less than the cutoff distance.
        """
        return _openmm.HippoNonbondedForce_setSwitchingDistance(self, distance)

    def getExtrapolationCoefficients(self):
        r"""
        getExtrapolationCoefficients(self) -> vectord
        Get the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the extrapolation algorithm for induced dipoles.
        """
        return _openmm.HippoNonbondedForce_getExtrapolationCoefficients(self)

    def setExtrapolationCoefficients(self, coefficients):
        r"""
        setExtrapolationCoefficients(self, coefficients)
        Set the coefficients for the mu_0, mu_1, mu_2, ..., mu_n terms in the extrapolation algorithm for induced dipoles.

        Parameters
        ----------
        coefficients : vector< double >
            a vector whose mth entry specifies the coefficient for mu_m. The length of this vector determines how many iterations are performed.
        """
        return _openmm.HippoNonbondedForce_setExtrapolationCoefficients(self, coefficients)

    def getPMEParameters(self):
        r"""
        getPMEParameters(self)
        Get the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_getPMEParameters(self)

    def getDPMEParameters(self):
        r"""
        getDPMEParameters(self)
        Get the parameters to use for dispersion PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of dispersion grid points along the X axis
        ny : int
            the number of dispersion grid points along the Y axis
        nz : int
            the number of dispersion grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_getDPMEParameters(self)

    def setPMEParameters(self, alpha, nx, ny, nz):
        r"""
        setPMEParameters(self, alpha, nx, ny, nz)
        Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Parameters
        ----------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_setPMEParameters(self, alpha, nx, ny, nz)

    def setDPMEParameters(self, alpha, nx, ny, nz):
        r"""
        setDPMEParameters(self, alpha, nx, ny, nz)
        Set the parameters to use for dispersion PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Parameters
        ----------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_setDPMEParameters(self, alpha, nx, ny, nz)

    def getPMEParametersInContext(self, context):
        r"""
        getPMEParametersInContext(self, context)
        Get the parameters being used for PME in a particular Context. Because some platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different from those specified with setPmeGridDimensions(), or the standard values calculated based on the Ewald error tolerance. See the manual for details.

        Parameters
        ----------
        context : Context
            the Context for which to get the parameters

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_getPMEParametersInContext(self, context)

    def getDPMEParametersInContext(self, context):
        r"""
        getDPMEParametersInContext(self, context)
        Get the parameters being used for dispersion PME in a particular Context. Because some platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different from those specified with setPMEParameters(), or the standard values calculated based on the Ewald error tolerance. See the manual for details.

        Parameters
        ----------
        context : Context
            the Context for which to get the parameters

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.HippoNonbondedForce_getDPMEParametersInContext(self, context)

    def addParticle(self, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY):
        r"""
        addParticle(self, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY) -> int
        Add the nonbonded force parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.

        Parameters
        ----------
        charge : double
            the particle's charge
        dipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        quadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        coreCharge : double
            the charge of the atomic core
        alpha : double
            controls the width of the particle's electron density
        epsilon : double
            sets the magnitude of charge transfer
        damping : double
            sets the length scale for charge transfer
        c6 : double
            the coefficient of the dispersion interaction
        pauliK : double
            the coefficient of the Pauli repulsion interaction
        pauliQ : double
            the charge used in computing the Pauli repulsion interaction
        pauliAlpha : double
            the width of the particle's electron density for computing the Pauli repulsion interaction
        polarizability : double
            atomic polarizability
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in defining the local coordinate system for multipoles
        multipoleAtomX : int
            index of second atom used in defining the local coordinate system for multipoles
        multipoleAtomY : int
            index of third atom used in defining the local coordinate system for multipoles

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.HippoNonbondedForce_addParticle(self, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters
        charge : double
            the particle's charge
        dipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        quadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        coreCharge : double
            the charge of the atomic core
        alpha : double
            controls the width of the particle's electron density
        epsilon : double
            sets the magnitude of charge transfer
        damping : double
            sets the length scale for charge transfer
        c6 : double
            the coefficient of the dispersion interaction
        pauliK : double
            the coefficient of the Pauli repulsion interaction
        pauliQ : double
            the charge used in computing the Pauli repulsion interaction
        pauliAlpha : double
            the width of the particle's electron density for computing the Pauli repulsion interaction
        polarizability : double
            atomic polarizability
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in defining the local coordinate system for multipoles
        multipoleAtomX : int
            index of second atom used in defining the local coordinate system for multipoles
        multipoleAtomY : int
            index of third atom used in defining the local coordinate system for multipoles
        """
        val = _openmm.HippoNonbondedForce_getParticleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.elementary_charge)
        val[1]=unit.Quantity(val[1], unit.elementary_charge*unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.elementary_charge*unit.nanometer**2)
        val[3]=unit.Quantity(val[3], unit.elementary_charge)


        return val


    def setParticleParameters(self, index, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY):
        r"""
        setParticleParameters(self, index, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY)
        Set the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        charge : double
            the particle's charge
        dipole : vector< double >
            the particle's molecular dipole (vector of size 3)
        quadrupole : vector< double >
            the particle's molecular quadrupole (vector of size 9)
        coreCharge : double
            the charge of the atomic core
        alpha : double
            controls the width of the particle's electron density
        epsilon : double
            sets the magnitude of charge transfer
        damping : double
            sets the length scale for charge transfer
        c6 : double
            the coefficient of the dispersion interaction
        pauliK : double
            the coefficient of the Pauli repulsion interaction
        pauliQ : double
            the charge used in computing the Pauli repulsion interaction
        pauliAlpha : double
            the width of the particle's electron density for computing the Pauli repulsion interaction
        polarizability : double
            atomic polarizability
        axisType : int
            the particle's axis type
        multipoleAtomZ : int
            index of first atom used in defining the local coordinate system for multipoles
        multipoleAtomX : int
            index of second atom used in defining the local coordinate system for multipoles
        multipoleAtomY : int
            index of third atom used in defining the local coordinate system for multipoles
        """
        return _openmm.HippoNonbondedForce_setParticleParameters(self, index, charge, dipole, quadrupole, coreCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY)

    def addException(self, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale, replace=False):
        r"""
        addException(self, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale, replace=False) -> int
        Add an interaction to the list of exceptions that should be calculated differently from other interactions. If all scale factors are set to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        Parameters
        ----------
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        multipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between fixed multipoles
        dipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between an induced dipole and a fixed multipole
        dipoleDipoleScale : double
            the factor by which to scale the Coulomb interaction between induced dipoles
        dispersionScale : double
            the factor by which to scale the dispersion interaction
        repulsionScale : double
            the factor by which to scale the Pauli repulsion
        chargeTransferScale : double
            the factor by which to scale the charge transfer interaction
        replace : bool
            determines the behavior if there is already an exception for the same two particles. If true, the existing one is replaced. If false, an exception is thrown.

        Returns
        -------
        int
            the index of the exception that was added
        """
        return _openmm.HippoNonbondedForce_addException(self, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale, replace)

    def getExceptionParameters(self, index):
        r"""
        getExceptionParameters(self, index)
        Get the scale factors for an interaction that should be calculated differently from others.

        Parameters
        ----------
        index : int
            the index of the interaction for which to get parameters
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        multipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between fixed multipoles
        dipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between an induced dipole and a fixed multipole
        dipoleDipoleScale : double
            the factor by which to scale the Coulomb interaction between induced dipoles
        dispersionScale : double
            the factor by which to scale the dispersion interaction
        repulsionScale : double
            the factor by which to scale the Pauli repulsion
        chargeTransferScale : double
            the factor by which to scale the charge transfer interaction
        """
        return _openmm.HippoNonbondedForce_getExceptionParameters(self, index)

    def setExceptionParameters(self, index, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale):
        r"""
        setExceptionParameters(self, index, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale)
        Set the scale factors for an interaction that should be calculated differently from others. If all scale factors are set to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        Parameters
        ----------
        index : int
            the index of the interaction for which to set parameters
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        multipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between fixed multipoles
        dipoleMultipoleScale : double
            the factor by which to scale the Coulomb interaction between an induced dipole and a fixed multipole
        dipoleDipoleScale : double
            the factor by which to scale the Coulomb interaction between induced dipoles
        dispersionScale : double
            the factor by which to scale the dispersion interaction
        repulsionScale : double
            the factor by which to scale the Pauli repulsion
        chargeTransferScale : double
            the factor by which to scale the charge transfer interaction
        """
        return _openmm.HippoNonbondedForce_setExceptionParameters(self, index, particle1, particle2, multipoleMultipoleScale, dipoleMultipoleScale, dipoleDipoleScale, dispersionScale, repulsionScale, chargeTransferScale)

    def getEwaldErrorTolerance(self):
        r"""
        getEwaldErrorTolerance(self) -> double
        Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the grid dimensions and separation (alpha) parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        This can be overridden by explicitly setting an alpha parameter and grid dimensions to use.
        """
        return _openmm.HippoNonbondedForce_getEwaldErrorTolerance(self)

    def setEwaldErrorTolerance(self, tol):
        r"""
        setEwaldErrorTolerance(self, tol)
        Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the grid dimensions and separation (alpha) parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        This can be overridden by explicitly setting an alpha parameter and grid dimensions to use.
        """
        return _openmm.HippoNonbondedForce_setEwaldErrorTolerance(self, tol)

    def getLabFramePermanentDipoles(self, context):
        r"""
        getLabFramePermanentDipoles(self, context)
        Get the fixed dipole moments of all particles in the global reference frame.

        Parameters
        ----------
        context : Context
            the Context for which to get the fixed dipoles

        Returns
        -------
        dipoles : vector< Vec3 >
            the fixed dipole moment of particle i is stored into the i'th element
        """
        return _openmm.HippoNonbondedForce_getLabFramePermanentDipoles(self, context)

    def getInducedDipoles(self, context):
        r"""
        getInducedDipoles(self, context)
        Get the induced dipole moments of all particles.

        Parameters
        ----------
        context : Context
            the Context for which to get the induced dipoles

        Returns
        -------
        dipoles : vector< Vec3 >
            the induced dipole moment of particle i is stored into the i'th element
        """
        return _openmm.HippoNonbondedForce_getInducedDipoles(self, context)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the particle and exception parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the parameters of particles and exceptions. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Furthermore, only the scale factors for an exception can be changed; the pair of particles involved in the exception cannot change. Finally, this method cannot be used to add new particles or exceptions, only to change the parameters of existing ones.
        """
        return _openmm.HippoNonbondedForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if nonbondedMethod uses PBC and false otherwise
        """
        return _openmm.HippoNonbondedForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> HippoNonbondedForce
        __init__(self, other) -> HippoNonbondedForce
        Create a HippoNonbondedForce.
        """
        _openmm.HippoNonbondedForce_swiginit(self, _openmm.new_HippoNonbondedForce(*args))
    __swig_destroy__ = _openmm.delete_HippoNonbondedForce

# Register HippoNonbondedForce in _openmm:
_openmm.HippoNonbondedForce_swigregister(HippoNonbondedForce)

class LangevinIntegrator(Integrator):
    r"""This is an Integrator which simulates a System using Langevin dynamics."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.LangevinIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.LangevinIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.LangevinIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.LangevinIntegrator_setFriction(self, coeff)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.LangevinIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.LangevinIntegrator_setRandomNumberSeed(self, seed)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.LangevinIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, frictionCoeff, stepSize) -> LangevinIntegrator
        __init__(self, other) -> LangevinIntegrator
        Create a LangevinIntegrator.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        """
        _openmm.LangevinIntegrator_swiginit(self, _openmm.new_LangevinIntegrator(*args))
    __swig_destroy__ = _openmm.delete_LangevinIntegrator

# Register LangevinIntegrator in _openmm:
_openmm.LangevinIntegrator_swigregister(LangevinIntegrator)

class LangevinMiddleIntegrator(Integrator):
    r"""
    This is an Integrator which simulates a System using Langevin dynamics, with the LFMiddle discretization (J. Phys. Chem. A 2019, 123, 28, 6056-6079). This method tend to produce more accurate configurational sampling than other discretizations, such as the one used in LangevinIntegrator.

    The algorithm is closely related to the BAOAB discretization (Proc. R. Soc. A. 472: 20160138). Both methods produce identical trajectories, but LFMiddle returns half step (leapfrog) velocities, while BAOAB returns on-step velocities. The former provide a much more accurate sampling of the thermal ensemble.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.LangevinMiddleIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.LangevinMiddleIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.LangevinMiddleIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.LangevinMiddleIntegrator_setFriction(self, coeff)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.LangevinMiddleIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Integrator. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.LangevinMiddleIntegrator_setRandomNumberSeed(self, seed)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.LangevinMiddleIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, frictionCoeff, stepSize) -> LangevinMiddleIntegrator
        __init__(self, other) -> LangevinMiddleIntegrator
        Create a LangevinMiddleIntegrator.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        """
        _openmm.LangevinMiddleIntegrator_swiginit(self, _openmm.new_LangevinMiddleIntegrator(*args))
    __swig_destroy__ = _openmm.delete_LangevinMiddleIntegrator

# Register LangevinMiddleIntegrator in _openmm:
_openmm.LangevinMiddleIntegrator_swigregister(LangevinMiddleIntegrator)

class VirtualSite(object):
    r"""A VirtualSite describes the rules for computing a particle's position based on other particles. This is an abstract class. Subclasses define particular rules. To define a virtual site, create an instance of a VirtualSite subclass and then call setVirtualSite() on the System."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_VirtualSite

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles this virtual site depends on.
        """
        return _openmm.VirtualSite_getNumParticles(self)

    def getParticle(self, particle):
        r"""
        getParticle(self, particle) -> int
        Get the index of a particle this virtual site depends on.

        Parameters
        ----------
        particle : int
            the particle to get (between 0 and getNumParticles())

        Returns
        -------
        int
            the index of the particle in the System
        """
        return _openmm.VirtualSite_getParticle(self, particle)

# Register VirtualSite in _openmm:
_openmm.VirtualSite_swigregister(VirtualSite)

class LocalCoordinatesSite(VirtualSite):
    r"""
    This is a VirtualSite that uses the locations of several other particles to compute a local coordinate system, then places the virtual site at a fixed location in that coordinate system. The origin of the coordinate system and the directions of its x and y axes are each specified as a weighted sum of the locations of the other particles:

    origin = w<sub>1</sub>r<sub>1</sub> + w<sub>2</sub>r<sub>2</sub> + w<sub>3</sub>r<sub>3</sub> + ...

    xdir = w<sub>1</sub>r<sub>1</sub> + w<sub>2</sub>r<sub>2</sub> + w<sub>3</sub>r<sub>3</sub> + ...

    ydir = w<sub>1</sub>r<sub>1</sub> + w<sub>2</sub>r<sub>2</sub> + w<sub>3</sub>r<sub>3</sub> + ...

    For the origin, the weights must add to one. For example if (w<sub>1</sub>, w<sub>2</sub>, w<sub>3</sub>) = (1.0, 0.0, 0.0), the origin of the local coordinate system is at the location of particle 1. For xdir and ydir, the weights must add to zero. For example, if (w<sub>1</sub>, w<sub>2</sub>, w<sub>3</sub>) = (-1.0, 0.5, 0.5), the x axis points from particle 1 toward the midpoint between particles 2 and 3.

    The z direction is computed as zdir = xdir x ydir. To ensure the axes are all orthogonal, ydir is then recomputed as ydir = zdir x xdir. All three axis vectors are then normalized, and the virtual site location is set to

    origin + x*xdir + y*ydir + z*zdir
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getOriginWeights(self):
        r"""
        getOriginWeights(self)
        Get the weight factors for the particles when computing the origin location.
        """
        return _openmm.LocalCoordinatesSite_getOriginWeights(self)

    def getXWeights(self):
        r"""
        getXWeights(self)
        Get the weight factors for the particles when computing xdir.
        """
        return _openmm.LocalCoordinatesSite_getXWeights(self)

    def getYWeights(self):
        r"""
        getYWeights(self)
        Get the weight factors for the particles when computing ydir.
        """
        return _openmm.LocalCoordinatesSite_getYWeights(self)

    def getLocalPosition(self):
        r"""
        getLocalPosition(self) -> Vec3 const &
        Get the position of the virtual site in the local coordinate system.
        """
        val = _openmm.LocalCoordinatesSite_getLocalPosition(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def __init__(self, *args):
        r"""
        __init__(self, particles, originWeights, xWeights, yWeights, localPosition) -> LocalCoordinatesSite
        __init__(self, particle1, particle2, particle3, originWeights, xWeights, yWeights, localPosition) -> LocalCoordinatesSite
        __init__(self, other) -> LocalCoordinatesSite
        Create a new LocalCoordinatesSite virtual site. This constructor assumes the site depends on exactly three other particles.

        Parameters
        ----------
        particle1 : int
            the index of the first particle
        particle2 : int
            the index of the second particle
        particle3 : int
            the index of the third particle
        originWeights : Vec3
            the weight factors for the three particles when computing the origin location
        xWeights : Vec3
            the weight factors for the three particles when computing xdir
        yWeights : Vec3
            the weight factors for the three particles when computing ydir
        localPosition : Vec3
            the position of the virtual site in the local coordinate system
        """
        _openmm.LocalCoordinatesSite_swiginit(self, _openmm.new_LocalCoordinatesSite(*args))
    __swig_destroy__ = _openmm.delete_LocalCoordinatesSite

# Register LocalCoordinatesSite in _openmm:
_openmm.LocalCoordinatesSite_swigregister(LocalCoordinatesSite)

class LocalEnergyMinimizer(object):
    r"""
    Given a Context, this class searches for a new set of particle positions that represent a local minimum of the potential energy. The search is performed with the L-BFGS algorithm. Distance constraints are enforced during minimization by adding a harmonic restraining force to the potential function. The strength of the restraining force is steadily increased until the minimum energy configuration satisfies all constraints to within the tolerance specified by the Context's Integrator.

    Energy minimization is done using the force groups defined by the Integrator. If you have called setIntegrationForceGroups() on it to restrict the set of forces used for integration, only the energy of the included forces will be minimized.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    @staticmethod
    def minimize(context, tolerance=10, maxIterations=0):
        r"""
        minimize(context, tolerance=10, maxIterations=0)
        Search for a new set of particle positions that represent a local potential energy minimum. On exit, the Context will have been updated with the new positions.

        Parameters
        ----------
        context : Context
            a Context specifying the System to minimize and the initial particle positions
        tolerance : double
            this specifies how precisely the energy minimum must be located. Minimization will be halted once the root-mean-square value of all force components reaches this tolerance. The default value is 10.
        maxIterations : int
            the maximum number of iterations to perform. If this is 0, minimation is continued until the results converge without regard to how many iterations it takes. The default value is 0.
        """
        return _openmm.LocalEnergyMinimizer_minimize(context, tolerance, maxIterations)
    __swig_destroy__ = _openmm.delete_LocalEnergyMinimizer

# Register LocalEnergyMinimizer in _openmm:
_openmm.LocalEnergyMinimizer_swigregister(LocalEnergyMinimizer)

def LocalEnergyMinimizer_minimize(context, tolerance=10, maxIterations=0):
    r"""
    LocalEnergyMinimizer_minimize(context, tolerance=10, maxIterations=0)
    Search for a new set of particle positions that represent a local potential energy minimum. On exit, the Context will have been updated with the new positions.

    Parameters
    ----------
    context : Context
        a Context specifying the System to minimize and the initial particle positions
    tolerance : double
        this specifies how precisely the energy minimum must be located. Minimization will be halted once the root-mean-square value of all force components reaches this tolerance. The default value is 10.
    maxIterations : int
        the maximum number of iterations to perform. If this is 0, minimation is continued until the results converge without regard to how many iterations it takes. The default value is 0.
    """
    return _openmm.LocalEnergyMinimizer_minimize(context, tolerance, maxIterations)

class MonteCarloAnisotropicBarostat(Force):
    r"""
    This class uses a Monte Carlo algorithm to adjust the size of the periodic box, simulating the effect of constant pressure.

    This class is similar to MonteCarloBarostat, but each Monte Carlo move is applied to only one axis of the periodic box (unlike MonteCarloBarostat, which scales the entire box isotropically). This means that the box may change shape as well as size over the course of the simulation. It also allows you to specify a different pressure for each axis of the box, or to keep the box size fixed along certain axes while still allowing it to change along others.

    This class assumes the simulation is also being run at constant temperature, and requires you to specify the system temperature (since it affects the acceptance probability for Monte Carlo moves). It does not actually perform temperature regulation, however. You must use another mechanism along with it to maintain the temperature, such as LangevinIntegrator or AndersenThermostat.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    @staticmethod
    def PressureX():
        r"""
        PressureX() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the X-axis (in bar).
        """
        return _openmm.MonteCarloAnisotropicBarostat_PressureX()

    @staticmethod
    def PressureY():
        r"""
        PressureY() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the Y-axis (in bar).
        """
        return _openmm.MonteCarloAnisotropicBarostat_PressureY()

    @staticmethod
    def PressureZ():
        r"""
        PressureZ() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the Z-axis (in bar).
        """
        return _openmm.MonteCarloAnisotropicBarostat_PressureZ()

    @staticmethod
    def Temperature():
        r"""
        Temperature() -> std::string const &
        This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
        """
        return _openmm.MonteCarloAnisotropicBarostat_Temperature()

    def getDefaultPressure(self):
        r"""
        getDefaultPressure(self) -> Vec3 const &
        Get the default pressure (in bar).

        Returns
        -------
        Vec3
            the default pressure acting along each axis, measured in bar.
        """
        val = _openmm.MonteCarloAnisotropicBarostat_getDefaultPressure(self)

        val=unit.Quantity(val, unit.bar)


        return val


    def setDefaultPressure(self, pressure):
        r"""
        setDefaultPressure(self, pressure)
        Set the default pressure acting on the system. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        pressure : Vec3
            the default pressure acting on the system, measured in bar.
        """

        if unit.is_quantity(pressure):
            pressure = pressure.value_in_unit(unit.bar)


        return _openmm.MonteCarloAnisotropicBarostat_setDefaultPressure(self, pressure)


    def getScaleX(self):
        r"""
        getScaleX(self) -> bool
        Get whether to allow the X dimension of the periodic box to change size.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getScaleX(self)

    def getScaleY(self):
        r"""
        getScaleY(self) -> bool
        Get whether to allow the Y dimension of the periodic box to change size.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getScaleY(self)

    def getScaleZ(self):
        r"""
        getScaleZ(self) -> bool
        Get whether to allow the Z dimension of the periodic box to change size.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getScaleZ(self)

    def getFrequency(self):
        r"""
        getFrequency(self) -> int
        Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getFrequency(self)

    def setFrequency(self, freq):
        r"""
        setFrequency(self, freq)
        Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloAnisotropicBarostat_setFrequency(self, freq)

    def getDefaultTemperature(self):
        r"""
        getDefaultTemperature(self) -> double
        Get the default temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloAnisotropicBarostat_getDefaultTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setDefaultTemperature(self, temp):
        r"""
        setDefaultTemperature(self, temp)
        Set the default temperature at which the system is being maintained. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """

        if unit.is_quantity(temp):
            temp = temp.value_in_unit(unit.kelvin)


        return _openmm.MonteCarloAnisotropicBarostat_setDefaultTemperature(self, temp)


    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. It is guaranteed that if two simulations are run with different random number seeds, the sequence of Monte Carlo steps will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.MonteCarloAnisotropicBarostat_setRandomNumberSeed(self, seed)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.MonteCarloAnisotropicBarostat_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, defaultPressure, defaultTemperature, scaleX=True, scaleY=True, scaleZ=True, frequency=25) -> MonteCarloAnisotropicBarostat
        __init__(self, other) -> MonteCarloAnisotropicBarostat
        Create a MonteCarloAnisotropicBarostat.

        Parameters
        ----------
        defaultPressure : Vec3
            The default pressure acting on each axis (in bar)
        defaultTemperature : double
            the default temperature at which the system is being maintained (in Kelvin)
        scaleX : bool
            whether to allow the X dimension of the periodic box to change size
        scaleY : bool
            whether to allow the Y dimension of the periodic box to change size
        scaleZ : bool
            whether to allow the Z dimension of the periodic box to change size
        frequency : int
            the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
        """
        _openmm.MonteCarloAnisotropicBarostat_swiginit(self, _openmm.new_MonteCarloAnisotropicBarostat(*args))
    __swig_destroy__ = _openmm.delete_MonteCarloAnisotropicBarostat

# Register MonteCarloAnisotropicBarostat in _openmm:
_openmm.MonteCarloAnisotropicBarostat_swigregister(MonteCarloAnisotropicBarostat)

def MonteCarloAnisotropicBarostat_PressureX():
    r"""
    MonteCarloAnisotropicBarostat_PressureX() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the X-axis (in bar).
    """
    return _openmm.MonteCarloAnisotropicBarostat_PressureX()

def MonteCarloAnisotropicBarostat_PressureY():
    r"""
    MonteCarloAnisotropicBarostat_PressureY() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the Y-axis (in bar).
    """
    return _openmm.MonteCarloAnisotropicBarostat_PressureY()

def MonteCarloAnisotropicBarostat_PressureZ():
    r"""
    MonteCarloAnisotropicBarostat_PressureZ() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the Z-axis (in bar).
    """
    return _openmm.MonteCarloAnisotropicBarostat_PressureZ()

def MonteCarloAnisotropicBarostat_Temperature():
    r"""
    MonteCarloAnisotropicBarostat_Temperature() -> std::string const &
    This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
    """
    return _openmm.MonteCarloAnisotropicBarostat_Temperature()

class MonteCarloBarostat(Force):
    r"""
    This class uses a Monte Carlo algorithm to adjust the size of the periodic box, simulating the effect of constant pressure.

    This class assumes the simulation is also being run at constant temperature, and requires you to specify the system temperature (since it affects the acceptance probability for Monte Carlo moves). It does not actually perform temperature regulation, however. You must use another mechanism along with it to maintain the temperature, such as LangevinIntegrator or AndersenThermostat.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    @staticmethod
    def Pressure():
        r"""
        Pressure() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the system (in bar).
        """
        return _openmm.MonteCarloBarostat_Pressure()

    @staticmethod
    def Temperature():
        r"""
        Temperature() -> std::string const &
        This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
        """
        return _openmm.MonteCarloBarostat_Temperature()

    def getDefaultPressure(self):
        r"""
        getDefaultPressure(self) -> double
        Get the default pressure acting on the system (in bar).

        Returns
        -------
        double
            the default pressure acting on the system, measured in bar.
        """
        val = _openmm.MonteCarloBarostat_getDefaultPressure(self)

        val=unit.Quantity(val, unit.bar)


        return val


    def setDefaultPressure(self, pressure):
        r"""
        setDefaultPressure(self, pressure)
        Set the default pressure acting on the system. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        pressure : double
            the default pressure acting on the system, measured in bar.
        """

        if unit.is_quantity(pressure):
            pressure = pressure.value_in_unit(unit.bar)


        return _openmm.MonteCarloBarostat_setDefaultPressure(self, pressure)


    def getFrequency(self):
        r"""
        getFrequency(self) -> int
        Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloBarostat_getFrequency(self)

    def setFrequency(self, freq):
        r"""
        setFrequency(self, freq)
        Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloBarostat_setFrequency(self, freq)

    def getDefaultTemperature(self):
        r"""
        getDefaultTemperature(self) -> double
        Get the default temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloBarostat_getDefaultTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setDefaultTemperature(self, temp):
        r"""
        setDefaultTemperature(self, temp)
        Set the default temperature at which the system is being maintained. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """

        if unit.is_quantity(temp):
            temp = temp.value_in_unit(unit.kelvin)


        return _openmm.MonteCarloBarostat_setDefaultTemperature(self, temp)


    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloBarostat_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. It is guaranteed that if two simulations are run with different random number seeds, the sequence of Monte Carlo steps will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.MonteCarloBarostat_setRandomNumberSeed(self, seed)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.MonteCarloBarostat_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, defaultPressure, defaultTemperature, frequency=25) -> MonteCarloBarostat
        __init__(self, other) -> MonteCarloBarostat
        Create a MonteCarloBarostat.

        Parameters
        ----------
        defaultPressure : double
            the default pressure acting on the system (in bar)
        defaultTemperature : double
            the default temperature at which the system is being maintained (in Kelvin)
        frequency : int
            the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
        """
        _openmm.MonteCarloBarostat_swiginit(self, _openmm.new_MonteCarloBarostat(*args))
    __swig_destroy__ = _openmm.delete_MonteCarloBarostat

# Register MonteCarloBarostat in _openmm:
_openmm.MonteCarloBarostat_swigregister(MonteCarloBarostat)

def MonteCarloBarostat_Pressure():
    r"""
    MonteCarloBarostat_Pressure() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the system (in bar).
    """
    return _openmm.MonteCarloBarostat_Pressure()

def MonteCarloBarostat_Temperature():
    r"""
    MonteCarloBarostat_Temperature() -> std::string const &
    This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
    """
    return _openmm.MonteCarloBarostat_Temperature()

class MonteCarloMembraneBarostat(Force):
    r"""
    This is a Monte Carlo barostat designed specifically for membrane simulations. It assumes the membrane lies in the XY plane. The Monte Carlo acceptance criterion includes a term to model isotropic pressure, which depends on the volume of the periodic box, and a second term to model surface tension, which depends on the cross sectional area of the box in the XY plane. Note that pressure and surface tension are defined with opposite senses: a larger pressure tends to make the box smaller, but a larger surface tension tends to make the box larger.

    There are options for configuring exactly how the various box dimensions are allowed to change:

     - The X and Y axes may be treated isotropically, in which case they always scale by the same amount and remain in proportion to each other; or they may be treated anisotropically, in which case they can vary independently of each other.
     - The Z axis can be allowed to vary independently of the other axes; or held fixed; or constrained to vary in inverse proportion to the other two axes, so that the total box volume remains fixed.

    This class assumes the simulation is also being run at constant temperature, and requires you to specify the system temperature (since it affects the acceptance probability for Monte Carlo moves). It does not actually perform temperature regulation, however. You must use another mechanism along with it to maintain the temperature, such as LangevinIntegrator or AndersenThermostat.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    XYIsotropic = _openmm.MonteCarloMembraneBarostat_XYIsotropic
    
    XYAnisotropic = _openmm.MonteCarloMembraneBarostat_XYAnisotropic
    
    ZFree = _openmm.MonteCarloMembraneBarostat_ZFree
    
    ZFixed = _openmm.MonteCarloMembraneBarostat_ZFixed
    
    ConstantVolume = _openmm.MonteCarloMembraneBarostat_ConstantVolume
    

    @staticmethod
    def Pressure():
        r"""
        Pressure() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the system (in bar).
        """
        return _openmm.MonteCarloMembraneBarostat_Pressure()

    @staticmethod
    def SurfaceTension():
        r"""
        SurfaceTension() -> std::string const &
        This is the name of the parameter which stores the current surface tension acting on the system (in bar*nm).
        """
        return _openmm.MonteCarloMembraneBarostat_SurfaceTension()

    @staticmethod
    def Temperature():
        r"""
        Temperature() -> std::string const &
        This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
        """
        return _openmm.MonteCarloMembraneBarostat_Temperature()

    def getDefaultPressure(self):
        r"""
        getDefaultPressure(self) -> double
        Get the default pressure acting on the system (in bar).

        Returns
        -------
        double
            the default pressure acting on the system, measured in bar.
        """
        val = _openmm.MonteCarloMembraneBarostat_getDefaultPressure(self)

        val=unit.Quantity(val, unit.bar)


        return val


    def setDefaultPressure(self, pressure):
        r"""
        setDefaultPressure(self, pressure)
        Set the default pressure acting on the system. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        pressure : double
            the default pressure acting on the system, measured in bar.
        """

        if unit.is_quantity(pressure):
            pressure = pressure.value_in_unit(unit.bar)


        return _openmm.MonteCarloMembraneBarostat_setDefaultPressure(self, pressure)


    def getDefaultSurfaceTension(self):
        r"""
        getDefaultSurfaceTension(self) -> double
        Get the default surface tension acting on the system (in bar*nm).

        Returns
        -------
        double
            the default surface tension acting on the system, measured in bar*nm.
        """
        val = _openmm.MonteCarloMembraneBarostat_getDefaultSurfaceTension(self)

        val=unit.Quantity(val, unit.bar*unit.nanometer)


        return val


    def setDefaultSurfaceTension(self, surfaceTension):
        r"""
        setDefaultSurfaceTension(self, surfaceTension)
        Set the default surface tension acting on the system. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        surfaceTension : double
            the default surface tension acting on the system, measured in bar.
        """

        if unit.is_quantity(surfaceTension):
            surfaceTension = surfaceTension.value_in_unit(unit.bar*unit.nanometer)


        return _openmm.MonteCarloMembraneBarostat_setDefaultSurfaceTension(self, surfaceTension)


    def getFrequency(self):
        r"""
        getFrequency(self) -> int
        Get the frequency (in time steps) at which Monte Carlo volume changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloMembraneBarostat_getFrequency(self)

    def setFrequency(self, freq):
        r"""
        setFrequency(self, freq)
        Set the frequency (in time steps) at which Monte Carlo volume changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.MonteCarloMembraneBarostat_setFrequency(self, freq)

    def getDefaultTemperature(self):
        r"""
        getDefaultTemperature(self) -> double
        Get the default temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloMembraneBarostat_getDefaultTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setDefaultTemperature(self, temp):
        r"""
        setDefaultTemperature(self, temp)
        Set the default temperature at which the system is being maintained. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """

        if unit.is_quantity(temp):
            temp = temp.value_in_unit(unit.kelvin)


        return _openmm.MonteCarloMembraneBarostat_setDefaultTemperature(self, temp)


    def getXYMode(self):
        r"""
        getXYMode(self) -> OpenMM::MonteCarloMembraneBarostat::XYMode
        Get the mode specifying the behavior of the X and Y axes.
        """
        return _openmm.MonteCarloMembraneBarostat_getXYMode(self)

    def setXYMode(self, mode):
        r"""
        setXYMode(self, mode)
        Set the mode specifying the behavior of the X and Y axes.
        """
        return _openmm.MonteCarloMembraneBarostat_setXYMode(self, mode)

    def getZMode(self):
        r"""
        getZMode(self) -> OpenMM::MonteCarloMembraneBarostat::ZMode
        Get the mode specifying the behavior of the Z axis.
        """
        return _openmm.MonteCarloMembraneBarostat_getZMode(self)

    def setZMode(self, mode):
        r"""
        setZMode(self, mode)
        Set the mode specifying the behavior of the Z axis.
        """
        return _openmm.MonteCarloMembraneBarostat_setZMode(self, mode)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloMembraneBarostat_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. It is guaranteed that if two simulations are run with different random number seeds, the sequence of Monte Carlo steps will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.MonteCarloMembraneBarostat_setRandomNumberSeed(self, seed)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.MonteCarloMembraneBarostat_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, defaultPressure, defaultSurfaceTension, defaultTemperature, xymode, zmode, frequency=25) -> MonteCarloMembraneBarostat
        __init__(self, other) -> MonteCarloMembraneBarostat
        Create a MonteCarloMembraneBarostat.

        Parameters
        ----------
        defaultPressure : double
            the default pressure acting on the system (in bar)
        defaultSurfaceTension : double
            the default surface tension acting on the system (in bar*nm)
        defaultTemperature : double
            the default temperature at which the system is being maintained (in Kelvin)
        xymode : XYMode
            the mode specifying the behavior of the X and Y axes
        zmode : ZMode
            the mode specifying the behavior of the Z axis
        frequency : int
            the frequency at which Monte Carlo volume changes should be attempted (in time steps)
        """

        args = list(args)
        if unit.is_quantity(args[0]):
            args[0] = args[0].value_in_unit(unit.bar)
        if unit.is_quantity(args[1]):
            args[1] = args[1].value_in_unit(unit.bar*unit.nanometer)
        if unit.is_quantity(args[2]):
            args[2] = args[2].value_in_unit(unit.kelvin)


        _openmm.MonteCarloMembraneBarostat_swiginit(self, _openmm.new_MonteCarloMembraneBarostat(*args))
    __swig_destroy__ = _openmm.delete_MonteCarloMembraneBarostat

# Register MonteCarloMembraneBarostat in _openmm:
_openmm.MonteCarloMembraneBarostat_swigregister(MonteCarloMembraneBarostat)

def MonteCarloMembraneBarostat_Pressure():
    r"""
    MonteCarloMembraneBarostat_Pressure() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the system (in bar).
    """
    return _openmm.MonteCarloMembraneBarostat_Pressure()

def MonteCarloMembraneBarostat_SurfaceTension():
    r"""
    MonteCarloMembraneBarostat_SurfaceTension() -> std::string const &
    This is the name of the parameter which stores the current surface tension acting on the system (in bar*nm).
    """
    return _openmm.MonteCarloMembraneBarostat_SurfaceTension()

def MonteCarloMembraneBarostat_Temperature():
    r"""
    MonteCarloMembraneBarostat_Temperature() -> std::string const &
    This is the name of the parameter which stores the current temperature at which the system is being maintained (in Kelvin)
    """
    return _openmm.MonteCarloMembraneBarostat_Temperature()

class NonbondedForce(Force):
    r"""
    This class implements nonbonded interactions between particles, including a Coulomb force to represent electrostatics and a Lennard-Jones force to represent van der Waals interactions. It optionally supports periodic boundary conditions and cutoffs for long range interactions. Lennard-Jones interactions are calculated with the Lorentz-Berthelot combining rule: it uses the arithmetic mean of the sigmas and the geometric mean of the epsilons for the two interacting particles.

    To use this class, create a NonbondedForce object, then call addParticle() once for each particle in the System to define its parameters. The number of particles for which you define nonbonded parameters must be exactly equal to the number of particles in the System, or else an exception will be thrown when you try to create a Context. After a particle has been added, you can modify its force field parameters by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext().

    NonbondedForce also lets you specify "exceptions", particular pairs of particles whose interactions should be computed based on different parameters than those defined for the individual particles. This can be used to completely exclude certain interactions from the force calculation, or to alter how they interact with each other.

    Many molecular force fields omit Coulomb and Lennard-Jones interactions between particles separated by one or two bonds, while using modified parameters for those separated by three bonds (known as "1-4 interactions"). This class provides a convenience method for this case called createExceptionsFromBonds(). You pass to it a list of bonds and the scale factors to use for 1-4 interactions. It identifies all pairs of particles which are separated by 1, 2, or 3 bonds, then automatically creates exceptions for them.

    When using a cutoff, by default Lennard-Jones interactions are sharply truncated at the cutoff distance. Optionally you can instead use a switching function to make the interaction smoothly go to zero over a finite distance range. To enable this, call setUseSwitchingFunction(). You must also call setSwitchingDistance() to specify the distance at which the interaction should begin to decrease. The switching distance must be less than the cutoff distance.

    Another optional feature of this class (enabled by default) is to add a contribution to the energy which approximates the effect of all Lennard-Jones interactions beyond the cutoff in a periodic system. When running a simulation at constant pressure, this can improve the quality of the result. Call setUseDispersionCorrection() to set whether this should be used.

    In some applications, it is useful to be able to inexpensively change the parameters of small groups of particles. Usually this is done to interpolate between two sets of parameters. For example, a titratable group might have two states it can exist in, each described by a different set of parameters for the atoms that make up the group. You might then want to smoothly interpolate between the two states. This is done by first calling addGlobalParameter() to define a Context parameter, then addParticleParameterOffset() to create a "parameter offset" that depends on the Context parameter. Each offset defines the following:

     - A Context parameter used to interpolate between the states.
     - A single particle whose parameters are influenced by the Context parameter.
     - Three scale factors (chargeScale, sigmaScale, and epsilonScale) that specify how the Context parameter affects the particle.

    The "effective" parameters for a particle (those used to compute forces) are given by

    <tt><pre>
    charge = baseCharge + param*chargeScale
    sigma = baseSigma + param*sigmaScale
    epsilon = baseEpsilon + param*epsilonScale
    </pre></tt>

    where the "base" values are the ones specified by addParticle() and "oaram" is the current value of the Context parameter. A single Context parameter can apply offsets to multiple particles, and multiple parameters can be used to apply offsets to the same particle. Parameters can also be used to modify exceptions in exactly the same way by calling addExceptionParameterOffset().
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    NoCutoff = _openmm.NonbondedForce_NoCutoff
    
    CutoffNonPeriodic = _openmm.NonbondedForce_CutoffNonPeriodic
    
    CutoffPeriodic = _openmm.NonbondedForce_CutoffPeriodic
    
    Ewald = _openmm.NonbondedForce_Ewald
    
    PME = _openmm.NonbondedForce_PME
    
    LJPME = _openmm.NonbondedForce_LJPME
    

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.NonbondedForce_getNumParticles(self)

    def getNumExceptions(self):
        r"""
        getNumExceptions(self) -> int
        Get the number of special interactions that should be calculated differently from other interactions.
        """
        return _openmm.NonbondedForce_getNumExceptions(self)

    def getNumGlobalParameters(self):
        r"""
        getNumGlobalParameters(self) -> int
        Get the number of global parameters that have been added.
        """
        return _openmm.NonbondedForce_getNumGlobalParameters(self)

    def getNumParticleParameterOffsets(self):
        r"""
        getNumParticleParameterOffsets(self) -> int
        Get the number of particles parameter offsets that have been added.
        """
        return _openmm.NonbondedForce_getNumParticleParameterOffsets(self)

    def getNumExceptionParameterOffsets(self):
        r"""
        getNumExceptionParameterOffsets(self) -> int
        Get the number of exception parameter offsets that have been added.
        """
        return _openmm.NonbondedForce_getNumExceptionParameterOffsets(self)

    def getNonbondedMethod(self):
        r"""
        getNonbondedMethod(self) -> OpenMM::NonbondedForce::NonbondedMethod
        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.NonbondedForce_getNonbondedMethod(self)

    def setNonbondedMethod(self, method):
        r"""
        setNonbondedMethod(self, method)
        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.NonbondedForce_setNonbondedMethod(self, method)

    def getCutoffDistance(self):
        r"""
        getCutoffDistance(self) -> double
        Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Returns
        -------
        double
            the cutoff distance, measured in nm
        """
        val = _openmm.NonbondedForce_getCutoffDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setCutoffDistance(self, distance):
        r"""
        setCutoffDistance(self, distance)
        Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use is NoCutoff, this value will have no effect.

        Parameters
        ----------
        distance : double
            the cutoff distance, measured in nm
        """
        return _openmm.NonbondedForce_setCutoffDistance(self, distance)

    def getUseSwitchingFunction(self):
        r"""
        getUseSwitchingFunction(self) -> bool
        Get whether a switching function is applied to the Lennard-Jones interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.NonbondedForce_getUseSwitchingFunction(self)

    def setUseSwitchingFunction(self, use):
        r"""
        setUseSwitchingFunction(self, use)
        Set whether a switching function is applied to the Lennard-Jones interaction. If the nonbonded method is set to NoCutoff, this option is ignored.
        """
        return _openmm.NonbondedForce_setUseSwitchingFunction(self, use)

    def getSwitchingDistance(self):
        r"""
        getSwitchingDistance(self) -> double
        Get the distance at which the switching function begins to reduce the Lennard-Jones interaction. This must be less than the cutoff distance.
        """
        val = _openmm.NonbondedForce_getSwitchingDistance(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def setSwitchingDistance(self, distance):
        r"""
        setSwitchingDistance(self, distance)
        Set the distance at which the switching function begins to reduce the Lennard-Jones interaction. This must be less than the cutoff distance.
        """
        return _openmm.NonbondedForce_setSwitchingDistance(self, distance)

    def getReactionFieldDielectric(self):
        r"""
        getReactionFieldDielectric(self) -> double
        Get the dielectric constant to use for the solvent in the reaction field approximation.
        """
        return _openmm.NonbondedForce_getReactionFieldDielectric(self)

    def setReactionFieldDielectric(self, dielectric):
        r"""
        setReactionFieldDielectric(self, dielectric)
        Set the dielectric constant to use for the solvent in the reaction field approximation.
        """
        return _openmm.NonbondedForce_setReactionFieldDielectric(self, dielectric)

    def getEwaldErrorTolerance(self):
        r"""
        getEwaldErrorTolerance(self) -> double
        Get the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the reciprocal space cutoff and separation parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        For PME calculations, if setPMEParameters() is used to set alpha to something other than 0, this value is ignored.
        """
        return _openmm.NonbondedForce_getEwaldErrorTolerance(self)

    def setEwaldErrorTolerance(self, tol):
        r"""
        setEwaldErrorTolerance(self, tol)
        Set the error tolerance for Ewald summation. This corresponds to the fractional error in the forces which is acceptable. This value is used to select the reciprocal space cutoff and separation parameter so that the average error level will be less than the tolerance. There is not a rigorous guarantee that all forces on all atoms will be less than the tolerance, however.

        For PME calculations, if setPMEParameters() is used to set alpha to something other than 0, this value is ignored.
        """
        return _openmm.NonbondedForce_setEwaldErrorTolerance(self, tol)

    def getPMEParameters(self):
        r"""
        getPMEParameters(self)
        Get the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        val = _openmm.NonbondedForce_getPMEParameters(self)

        val[0]=unit.Quantity(val[0], 1/unit.nanometer)


        return val


    def getLJPMEParameters(self):
        r"""
        getLJPMEParameters(self)
        Get the parameters to use for dispersion term in LJ-PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of dispersion grid points along the X axis
        ny : int
            the number of dispersion grid points along the Y axis
        nz : int
            the number of dispersion grid points along the Z axis
        """
        return _openmm.NonbondedForce_getLJPMEParameters(self)

    def setPMEParameters(self, alpha, nx, ny, nz):
        r"""
        setPMEParameters(self, alpha, nx, ny, nz)
        Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Parameters
        ----------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.NonbondedForce_setPMEParameters(self, alpha, nx, ny, nz)

    def setLJPMEParameters(self, alpha, nx, ny, nz):
        r"""
        setLJPMEParameters(self, alpha, nx, ny, nz)
        Set the parameters to use for the dispersion term in LJPME calculations. If alpha is 0 (the default), these parameters are ignored and instead their values are chosen based on the Ewald error tolerance.

        Parameters
        ----------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.NonbondedForce_setLJPMEParameters(self, alpha, nx, ny, nz)

    def getPMEParametersInContext(self, context):
        r"""
        getPMEParametersInContext(self, context)
        Get the parameters being used for PME in a particular Context. Because some platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different from those specified with setPMEParameters(), or the standard values calculated based on the Ewald error tolerance. See the manual for details.

        Parameters
        ----------
        context : Context
            the Context for which to get the parameters

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.NonbondedForce_getPMEParametersInContext(self, context)

    def getLJPMEParametersInContext(self, context):
        r"""
        getLJPMEParametersInContext(self, context)
        Get the PME parameters being used for the dispersion term for LJPME in a particular Context. Because some platforms have restrictions on the allowed grid sizes, the values that are actually used may be slightly different from those specified with setPMEParameters(), or the standard values calculated based on the Ewald error tolerance. See the manual for details.

        Parameters
        ----------
        context : Context
            the Context for which to get the parameters

        Returns
        -------
        alpha : double
            the separation parameter
        nx : int
            the number of grid points along the X axis
        ny : int
            the number of grid points along the Y axis
        nz : int
            the number of grid points along the Z axis
        """
        return _openmm.NonbondedForce_getLJPMEParametersInContext(self, context)

    def addParticle(self, charge, sigma, epsilon):
        r"""
        addParticle(self, charge, sigma, epsilon) -> int
        Add the nonbonded force parameters for a particle. This should be called once for each particle in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle. For calculating the Lennard-Jones interaction between two particles, the arithmetic mean of the sigmas and the geometric mean of the epsilons for the two interacting particles is used (the Lorentz-Berthelot combining rule).

        Parameters
        ----------
        charge : double
            the charge of the particle, measured in units of the proton charge
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.NonbondedForce_addParticle(self, charge, sigma, epsilon)

    def getParticleParameters(self, index):
        r"""
        getParticleParameters(self, index)
        Get the nonbonded force parameters for a particle.

        Parameters
        ----------
        index : int
            the index of the particle for which to get parameters

        Returns
        -------
        charge : double
            the charge of the particle, measured in units of the proton charge
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        val = _openmm.NonbondedForce_getParticleParameters(self, index)

        val[0]=unit.Quantity(val[0], unit.elementary_charge)
        val[1]=unit.Quantity(val[1], unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.kilojoule_per_mole)


        return val


    def setParticleParameters(self, index, charge, sigma, epsilon):
        r"""
        setParticleParameters(self, index, charge, sigma, epsilon)
        Set the nonbonded force parameters for a particle. When calculating the Lennard-Jones interaction between two particles, it uses the arithmetic mean of the sigmas and the geometric mean of the epsilons for the two interacting particles (the Lorentz-Berthelot combining rule).

        Parameters
        ----------
        index : int
            the index of the particle for which to set parameters
        charge : double
            the charge of the particle, measured in units of the proton charge
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        return _openmm.NonbondedForce_setParticleParameters(self, index, charge, sigma, epsilon)

    def addException(self, particle1, particle2, chargeProd, sigma, epsilon, replace=False):
        r"""
        addException(self, particle1, particle2, chargeProd, sigma, epsilon, replace=False) -> int
        Add an interaction to the list of exceptions that should be calculated differently from other interactions. If chargeProd and epsilon are both equal to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        In many cases, you can use createExceptionsFromBonds() rather than adding each exception explicitly.

        Parameters
        ----------
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        chargeProd : double
            the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        replace : bool
            determines the behavior if there is already an exception for the same two particles. If true, the existing one is replaced. If false, an exception is thrown.

        Returns
        -------
        int
            the index of the exception that was added
        """
        return _openmm.NonbondedForce_addException(self, particle1, particle2, chargeProd, sigma, epsilon, replace)

    def getExceptionParameters(self, index):
        r"""
        getExceptionParameters(self, index)
        Get the force field parameters for an interaction that should be calculated differently from others.

        Parameters
        ----------
        index : int
            the index of the interaction for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        chargeProd : double
            the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        val = _openmm.NonbondedForce_getExceptionParameters(self, index)

        val[2]=unit.Quantity(val[2], unit.elementary_charge*unit.elementary_charge)
        val[3]=unit.Quantity(val[3], unit.nanometer)
        val[4]=unit.Quantity(val[4], unit.kilojoule_per_mole)


        return val


    def setExceptionParameters(self, index, particle1, particle2, chargeProd, sigma, epsilon):
        r"""
        setExceptionParameters(self, index, particle1, particle2, chargeProd, sigma, epsilon)
        Set the force field parameters for an interaction that should be calculated differently from others. If chargeProd and epsilon are both equal to 0, this will cause the interaction to be completely omitted from force and energy calculations.

        Parameters
        ----------
        index : int
            the index of the interaction for which to get parameters
        particle1 : int
            the index of the first particle involved in the interaction
        particle2 : int
            the index of the second particle involved in the interaction
        chargeProd : double
            the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
        sigma : double
            the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
        epsilon : double
            the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
        """
        return _openmm.NonbondedForce_setExceptionParameters(self, index, particle1, particle2, chargeProd, sigma, epsilon)

    def createExceptionsFromBonds(self, bonds, coulomb14Scale, lj14Scale):
        r"""
        createExceptionsFromBonds(self, bonds, coulomb14Scale, lj14Scale)
        Identify exceptions based on the molecular topology. Particles which are separated by one or two bonds are set to not interact at all, while pairs of particles separated by three bonds (known as "1-4 interactions") have their Coulomb and Lennard-Jones interactions reduced by a fixed factor.

        Parameters
        ----------
        bonds : vector< std::pair< int, int > >
            the set of bonds based on which to construct exceptions. Each element specifies the indices of two particles that are bonded to each other.
        coulomb14Scale : double
            pairs of particles separated by three bonds will have the strength of their Coulomb interaction multiplied by this factor
        lj14Scale : double
            pairs of particles separated by three bonds will have the strength of their Lennard-Jones interaction multiplied by this factor
        """
        return _openmm.NonbondedForce_createExceptionsFromBonds(self, bonds, coulomb14Scale, lj14Scale)

    def addGlobalParameter(self, name, defaultValue):
        r"""
        addGlobalParameter(self, name, defaultValue) -> int
        Add a new global parameter that parameter offsets may depend on. The default value provided to this method is the initial value of the parameter in newly created Contexts. You can change the value at any time by calling setParameter() on the Context.

        Parameters
        ----------
        name : string
            the name of the parameter
        defaultValue : double
            the default value of the parameter

        Returns
        -------
        int
            the index of the parameter that was added
        """
        return _openmm.NonbondedForce_addGlobalParameter(self, name, defaultValue)

    def getGlobalParameterName(self, index):
        r"""
        getGlobalParameterName(self, index) -> std::string const &
        Get the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the name

        Returns
        -------
        string
            the parameter name
        """
        return _openmm.NonbondedForce_getGlobalParameterName(self, index)

    def setGlobalParameterName(self, index, name):
        r"""
        setGlobalParameterName(self, index, name)
        Set the name of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the name
        name : string
            the name of the parameter
        """
        return _openmm.NonbondedForce_setGlobalParameterName(self, index, name)

    def getGlobalParameterDefaultValue(self, index):
        r"""
        getGlobalParameterDefaultValue(self, index) -> double
        Get the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to get the default value

        Returns
        -------
        double
            the parameter default value
        """
        return _openmm.NonbondedForce_getGlobalParameterDefaultValue(self, index)

    def setGlobalParameterDefaultValue(self, index, defaultValue):
        r"""
        setGlobalParameterDefaultValue(self, index, defaultValue)
        Set the default value of a global parameter.

        Parameters
        ----------
        index : int
            the index of the parameter for which to set the default value
        defaultValue : double
            the default value of the parameter
        """
        return _openmm.NonbondedForce_setGlobalParameterDefaultValue(self, index, defaultValue)

    def addParticleParameterOffset(self, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale):
        r"""
        addParticleParameterOffset(self, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale) -> int
        Add an offset to the per-particle parameters of a particular particle, based on a global parameter.

        Parameters
        ----------
        parameter : string
            the name of the global parameter. It must have already been added with addGlobalParameter(). Its value can be modified at any time by calling Context::setParameter().
        particleIndex : int
            the index of the particle whose parameters are affected
        chargeScale : double
            this value multiplied by the parameter value is added to the particle's charge
        sigmaScale : double
            this value multiplied by the parameter value is added to the particle's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the particle's epsilon

        Returns
        -------
        int
            the index of the offset that was added
        """
        return _openmm.NonbondedForce_addParticleParameterOffset(self, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale)

    def getParticleParameterOffset(self, index):
        r"""
        getParticleParameterOffset(self, index)
        Get the offset added to the per-particle parameters of a particular particle, based on a global parameter.

        Parameters
        ----------
        index : int
            the index of the offset to query, as returned by addParticleParameterOffset()
        parameter : string
            the name of the global parameter
        particleIndex : int
            the index of the particle whose parameters are affected
        chargeScale : double
            this value multiplied by the parameter value is added to the particle's charge
        sigmaScale : double
            this value multiplied by the parameter value is added to the particle's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the particle's epsilon
        """
        return _openmm.NonbondedForce_getParticleParameterOffset(self, index)

    def setParticleParameterOffset(self, index, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale):
        r"""
        setParticleParameterOffset(self, index, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale)
        Set the offset added to the per-particle parameters of a particular particle, based on a global parameter.

        Parameters
        ----------
        index : int
            the index of the offset to modify, as returned by addParticleParameterOffset()
        parameter : string
            the name of the global parameter. It must have already been added with addGlobalParameter(). Its value can be modified at any time by calling Context::setParameter().
        particleIndex : int
            the index of the particle whose parameters are affected
        chargeScale : double
            this value multiplied by the parameter value is added to the particle's charge
        sigmaScale : double
            this value multiplied by the parameter value is added to the particle's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the particle's epsilon
        """
        return _openmm.NonbondedForce_setParticleParameterOffset(self, index, parameter, particleIndex, chargeScale, sigmaScale, epsilonScale)

    def addExceptionParameterOffset(self, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale):
        r"""
        addExceptionParameterOffset(self, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale) -> int
        Add an offset to the parameters of a particular exception, based on a global parameter.

        Parameters
        ----------
        parameter : string
            the name of the global parameter. It must have already been added with addGlobalParameter(). Its value can be modified at any time by calling Context::setParameter().
        exceptionIndex : int
            the index of the exception whose parameters are affected
        chargeProdScale : double
            this value multiplied by the parameter value is added to the exception's charge product
        sigmaScale : double
            this value multiplied by the parameter value is added to the exception's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the exception's epsilon

        Returns
        -------
        int
            the index of the offset that was added
        """
        return _openmm.NonbondedForce_addExceptionParameterOffset(self, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale)

    def getExceptionParameterOffset(self, index):
        r"""
        getExceptionParameterOffset(self, index)
        Get the offset added to the parameters of a particular exception, based on a global parameter.

        Parameters
        ----------
        index : int
            the index of the offset to query, as returned by addExceptionParameterOffset()
        parameter : string
            the name of the global parameter
        exceptionIndex : int
            the index of the exception whose parameters are affected
        chargeProdScale : double
            this value multiplied by the parameter value is added to the exception's charge product
        sigmaScale : double
            this value multiplied by the parameter value is added to the exception's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the exception's epsilon
        """
        return _openmm.NonbondedForce_getExceptionParameterOffset(self, index)

    def setExceptionParameterOffset(self, index, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale):
        r"""
        setExceptionParameterOffset(self, index, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale)
        Set the offset added to the parameters of a particular exception, based on a global parameter.

        Parameters
        ----------
        index : int
            the index of the offset to modify, as returned by addExceptionParameterOffset()
        parameter : string
            the name of the global parameter. It must have already been added with addGlobalParameter(). Its value can be modified at any time by calling Context::setParameter().
        exceptionIndex : int
            the index of the exception whose parameters are affected
        chargeProdScale : double
            this value multiplied by the parameter value is added to the exception's charge product
        sigmaScale : double
            this value multiplied by the parameter value is added to the exception's sigma
        epsilonScale : double
            this value multiplied by the parameter value is added to the exception's epsilon
        """
        return _openmm.NonbondedForce_setExceptionParameterOffset(self, index, parameter, exceptionIndex, chargeProdScale, sigmaScale, epsilonScale)

    def getUseDispersionCorrection(self):
        r"""
        getUseDispersionCorrection(self) -> bool
        Get whether to add a contribution to the energy that approximately represents the effect of Lennard-Jones interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding this contribution can improve the quality of results.
        """
        return _openmm.NonbondedForce_getUseDispersionCorrection(self)

    def setUseDispersionCorrection(self, useCorrection):
        r"""
        setUseDispersionCorrection(self, useCorrection)
        Set whether to add a contribution to the energy that approximately represents the effect of Lennard-Jones interactions beyond the cutoff distance. The energy depends on the volume of the periodic box, and is only applicable when periodic boundary conditions are used. When running simulations at constant pressure, adding this contribution can improve the quality of results.
        """
        return _openmm.NonbondedForce_setUseDispersionCorrection(self, useCorrection)

    def getReciprocalSpaceForceGroup(self):
        r"""
        getReciprocalSpaceForceGroup(self) -> int
        Get the force group that reciprocal space interactions for Ewald or PME are included in. This allows multiple time step integrators to evaluate direct and reciprocal space interactions at different intervals: getForceGroup() specifies the group for direct space, and getReciprocalSpaceForceGroup() specifies the group for reciprocal space. If this is -1 (the default value), the same force group is used for reciprocal space as for direct space.
        """
        return _openmm.NonbondedForce_getReciprocalSpaceForceGroup(self)

    def setReciprocalSpaceForceGroup(self, group):
        r"""
        setReciprocalSpaceForceGroup(self, group)
        Set the force group that reciprocal space interactions for Ewald or PME are included in. This allows multiple time step integrators to evaluate direct and reciprocal space interactions at different intervals: setForceGroup() specifies the group for direct space, and setReciprocalSpaceForceGroup() specifies the group for reciprocal space. If this is -1 (the default value), the same force group is used for reciprocal space as for direct space.

        Parameters
        ----------
        group : int
            the group index. Legal values are between 0 and 31 (inclusive), or -1 to use the same force group that is specified for direct space.
        """
        return _openmm.NonbondedForce_setReciprocalSpaceForceGroup(self, group)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the particle and exception parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setParticleParameters() and setExceptionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        This method has several limitations. The only information it updates is the parameters of particles and exceptions. All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. Furthermore, only the chargeProd, sigma, and epsilon values of an exception can be changed; the pair of particles involved in the exception cannot change. Finally, this method cannot be used to add new particles or exceptions, only to change the parameters of existing ones.
        """
        return _openmm.NonbondedForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.NonbondedForce_usesPeriodicBoundaryConditions(self)

    def getExceptionsUsePeriodicBoundaryConditions(self):
        r"""
        getExceptionsUsePeriodicBoundaryConditions(self) -> bool
        Get whether periodic boundary conditions should be applied to exceptions. Usually this is not appropriate, because exceptions are normally used to represent bonded interactions (1-2, 1-3, and 1-4 pairs), but there are situations when it does make sense. For example, you may want to simulate an infinite chain where one end of a molecule is bonded to the opposite end of the next periodic copy.

        Regardless of this value, periodic boundary conditions are only applied to exceptions if they also are applied to other interactions. If the nonbonded method is NoCutoff or CutoffNonPeriodic, this value is ignored. Also note that cutoffs are never applied to exceptions, again because they are normally used to represent bonded interactions.
        """
        return _openmm.NonbondedForce_getExceptionsUsePeriodicBoundaryConditions(self)

    def setExceptionsUsePeriodicBoundaryConditions(self, periodic):
        r"""
        setExceptionsUsePeriodicBoundaryConditions(self, periodic)
        Set whether periodic boundary conditions should be applied to exceptions. Usually this is not appropriate, because exceptions are normally used to represent bonded interactions (1-2, 1-3, and 1-4 pairs), but there are situations when it does make sense. For example, you may want to simulate an infinite chain where one end of a molecule is bonded to the opposite end of the next periodic copy.

        Regardless of this value, periodic boundary conditions are only applied to exceptions if they also get applied to other interactions. If the nonbonded method is NoCutoff or CutoffNonPeriodic, this value is ignored. Also note that cutoffs are never applied to exceptions, again because they are normally used to represent bonded interactions.
        """
        return _openmm.NonbondedForce_setExceptionsUsePeriodicBoundaryConditions(self, periodic)

    def addParticle_usingRVdw(self, charge, rVDW, epsilon):
        """Add particle using elemetrary charge.  Rvdw and epsilon,
           which is consistent with AMBER parameter file usage.
           Note that the sum of the radii of the two interacting atoms is
           the minimum energy point in the Lennard Jones potential and
           is often called rMin.  The conversion from sigma follows:
           rVDW = 2^1/6 * sigma/2
        """
        return self.addParticle(charge, rVDW/RVDW_PER_SIGMA, epsilon)

    def addException_usingRMin(self, particle1, particle2,
                               chargeProd, rMin, epsilon):
        """Add interaction exception using the product of the two atoms'
           elementary charges, rMin and epsilon, which is standard for AMBER
           force fields.  Note that rMin is the minimum energy point in the
           Lennard Jones potential.  The conversion from sigma is:
           rMin = 2^1/6 * sigma.
        """
        return self.addException(particle1, particle2,
                                 chargeProd, rMin/RMIN_PER_SIGMA, epsilon)


    def __init__(self, *args):
        r"""
        __init__(self) -> NonbondedForce
        __init__(self, other) -> NonbondedForce
        Create a NonbondedForce.
        """
        _openmm.NonbondedForce_swiginit(self, _openmm.new_NonbondedForce(*args))
    __swig_destroy__ = _openmm.delete_NonbondedForce

# Register NonbondedForce in _openmm:
_openmm.NonbondedForce_swigregister(NonbondedForce)

class NoseHooverChain(object):
    r"""
    This class defines a chain of Nose-Hoover particles to be used as a heat bath to scale the velocities of a collection of particles subject to thermostating. The heat bath is propagated using the multi time step approach detailed in

    G. J. Martyna, M. E. Tuckerman, D. J. Tobias and M. L. Klein, Mol. Phys. 87, 1117 (1996).

    where the total number of timesteps used to propagate the chain in each step is the number of MTS steps multiplied by the number of terms in the Yoshida-Suzuki decomposition.

    Two types of NHC may be created. The first is a simple thermostat that couples with a given subset of the atoms within a system, controling their absolute motion. The second is more elaborate and can thermostat tethered pairs of atoms and in this case two thermostats are created: one that controls the absolute center of mass velocity of each pair and another that controls their motion relative to one another.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath for treating absolute particle motion (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin.
        """
        val = _openmm.NoseHooverChain_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temperature):
        r"""
        setTemperature(self, temperature)
        Set the temperature of the heat bath for treating absolute particle motion. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath (in Kelvin)
        """
        return _openmm.NoseHooverChain_setTemperature(self, temperature)

    def getRelativeTemperature(self):
        r"""
        getRelativeTemperature(self) -> double
        Get the temperature of the heat bath for treating relative particle motion (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin.
        """
        val = _openmm.NoseHooverChain_getRelativeTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setRelativeTemperature(self, temperature):
        r"""
        setRelativeTemperature(self, temperature)
        Set the temperature of the heat bath for treating relative motion if this thermostat has been set up to treat connected pairs of atoms. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath for relative motion (in Kelvin)
        """
        return _openmm.NoseHooverChain_setRelativeTemperature(self, temperature)

    def getCollisionFrequency(self):
        r"""
        getCollisionFrequency(self) -> double
        Get the collision frequency for treating absolute particle motion (in 1/ps).

        Returns
        -------
        double
            the collision frequency, measured in 1/ps.
        """
        val = _openmm.NoseHooverChain_getCollisionFrequency(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setCollisionFrequency(self, frequency):
        r"""
        setCollisionFrequency(self, frequency)
        Set the collision frequency for treating absolute particle motion. This will affect any new Contexts you create, but not those that already exist.

        Parameters
        ----------
        frequency : double
            the collision frequency (in 1/ps)
        """
        return _openmm.NoseHooverChain_setCollisionFrequency(self, frequency)

    def getRelativeCollisionFrequency(self):
        r"""
        getRelativeCollisionFrequency(self) -> double
        Get the collision frequency for treating relative particle motion (in 1/ps).

        Returns
        -------
        double
            the collision frequency, measured in 1/ps.
        """
        val = _openmm.NoseHooverChain_getRelativeCollisionFrequency(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setRelativeCollisionFrequency(self, frequency):
        r"""
        setRelativeCollisionFrequency(self, frequency)
        Set the collision frequency for treating relative particle motion if this thermostat has been set up to handle connected pairs of atoms. This will affect any new Contexts you create, but not those that already exist.

        Parameters
        ----------
        frequency : double
            the collision frequency (in 1/ps)
        """
        return _openmm.NoseHooverChain_setRelativeCollisionFrequency(self, frequency)

    def getNumDegreesOfFreedom(self):
        r"""
        getNumDegreesOfFreedom(self) -> int
        Get the number of degrees of freedom in the particles controled by this heat bath.

        Returns
        -------
        int
            the number of degrees of freedom.
        """
        return _openmm.NoseHooverChain_getNumDegreesOfFreedom(self)

    def setNumDegreesOfFreedom(self, numDOF):
        r"""
        setNumDegreesOfFreedom(self, numDOF)
        Set the number of degrees of freedom in the particles controled by this heat bath. This will affect any new Contexts you create, but not those that already exist.

        Parameters
        ----------
        numDOF : int
            the number of degrees of freedom.
        """
        return _openmm.NoseHooverChain_setNumDegreesOfFreedom(self, numDOF)

    def getChainLength(self):
        r"""
        getChainLength(self) -> int
        Get the chain length of this heat bath.

        Returns
        -------
        int
            the chain length.
        """
        return _openmm.NoseHooverChain_getChainLength(self)

    def getNumMultiTimeSteps(self):
        r"""
        getNumMultiTimeSteps(self) -> int
        Get the number of steps used in the multi time step propagation.

        Returns
        -------
        int
            the number of multi time steps.
        """
        return _openmm.NoseHooverChain_getNumMultiTimeSteps(self)

    def getNumYoshidaSuzukiTimeSteps(self):
        r"""
        getNumYoshidaSuzukiTimeSteps(self) -> int
        Get the number of steps used in the Yoshida-Suzuki decomposition for multi time step propagation.

        Returns
        -------
        int
            the number of multi time steps in the Yoshida-Suzuki decomposition.
        """
        return _openmm.NoseHooverChain_getNumYoshidaSuzukiTimeSteps(self)

    def getChainID(self):
        r"""
        getChainID(self) -> int
        Get the chain id used to identify this chain

        Returns
        -------
        int
            the chain id
        """
        return _openmm.NoseHooverChain_getChainID(self)

    def getThermostatedAtoms(self):
        r"""
        getThermostatedAtoms(self) -> vectori
        Get the atom ids of all atoms that are thermostated

        Returns
        -------
        vector< int >
            ids of all atoms that are being handled by this thermostat
        """
        return _openmm.NoseHooverChain_getThermostatedAtoms(self)

    def setThermostatedAtoms(self, atomIDs):
        r"""
        setThermostatedAtoms(self, atomIDs)
        Set list of atoms that are handled by this thermostat

        Parameters
        ----------
        atomIDs : vector< int >
        """
        return _openmm.NoseHooverChain_setThermostatedAtoms(self, atomIDs)

    def getThermostatedPairs(self):
        r"""
        getThermostatedPairs(self) -> vectorpairii
        Get the list of any connected pairs to be handled by this thermostat. If this is a regular thermostat, returns an empty vector.

        Returns
        -------
        vector< std::pair< int, int > >
            list of connected pairs.
        """
        return _openmm.NoseHooverChain_getThermostatedPairs(self)

    def setThermostatedPairs(self, pairIDs):
        r"""
        setThermostatedPairs(self, pairIDs)
        In case this thermostat handles the kinetic energy of Drude particles set the atom IDs of all parent atoms.

        Parameters
        ----------
        pairIDs : vector< std::pair< int, int > >
            the list of connected pairs to thermostat.
        """
        return _openmm.NoseHooverChain_setThermostatedPairs(self, pairIDs)

    def getYoshidaSuzukiWeights(self):
        r"""
        getYoshidaSuzukiWeights(self) -> vectord
        Get the weights used in the Yoshida Suzuki multi time step decomposition (dimensionless)

        Returns
        -------
        vector< double >
            the weights for the Yoshida-Suzuki integration
        """
        return _openmm.NoseHooverChain_getYoshidaSuzukiWeights(self)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.NoseHooverChain_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, relativeTemperature, collisionFrequency, relativeCollisionFrequency, numDOFs, chainLength, numMTS, numYoshidaSuzuki, chainID, thermostatedAtoms, thermostatedPairs) -> NoseHooverChain
        __init__(self, other) -> NoseHooverChain
        Create a NoseHooverChain.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath for absolute motion (in Kelvin)
        collisionFrequency : double
            the collision frequency for absolute motion (in 1/ps)
        relativeTemperature : double
            the temperature of the heat bath for relative motion(in Kelvin). This is only used if the list of thermostated pairs is not empty.
        relativeCollisionFrequency : double
            the collision frequency for relative motion(in 1/ps). This is only used if the list of thermostated pairs is not empty.
        numDOFs : int
            the number of degrees of freedom in the particles that interact with this chain
        chainLength : int
            the length of (number of particles in) this heat bath
        numMTS : int
            the number of multi time steps used to propagate this chain
        numYoshidaSuzuki : int
            the number of Yoshida Suzuki steps used to propagate this chain (1, 3, 5, or 7).
        chainID : int
            the chain id used to distinguish this Nose-Hoover chain from others that may be used to control a different set of particles, e.g. for Drude oscillators
        thermostatedAtoms : vector< int >
            the list of atoms to be handled by this thermostat
        thermostatedPairs : vector< std::pair< int, int > >
            the list of connected pairs to be thermostated; their absolute center of mass motion will be thermostated independently from their motion relative to one another.
        """
        _openmm.NoseHooverChain_swiginit(self, _openmm.new_NoseHooverChain(*args))
    __swig_destroy__ = _openmm.delete_NoseHooverChain

# Register NoseHooverChain in _openmm:
_openmm.NoseHooverChain_swigregister(NoseHooverChain)

class OutOfPlaneSite(VirtualSite):
    r"""
    This is a VirtualSite that computes the particle location based on three other particles' locations. If r<sub>1</sub> is the location of particle 1, r<sub>12</sub> is the vector from particle 1 to particle 2, and r<sub>13</sub> is the vector from particle 1 to particle 3, then the virtual site location is given by

    r<sub>1</sub> + w<sub>12</sub>r<sub>12</sub> + w<sub>13</sub>r<sub>13</sub> + w<sub>cross</sub>(r<sub>12</sub> x r<sub>13</sub>)

    The three weight factors are user-specified. This allows the virtual site location to be out of the plane of the three particles.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getWeight12(self):
        r"""
        getWeight12(self) -> double
        Get the weight factor for the vector from particle1 to particle2.
        """
        return _openmm.OutOfPlaneSite_getWeight12(self)

    def getWeight13(self):
        r"""
        getWeight13(self) -> double
        Get the weight factor for the vector from particle1 to particle3.
        """
        return _openmm.OutOfPlaneSite_getWeight13(self)

    def getWeightCross(self):
        r"""
        getWeightCross(self) -> double
        Get the weight factor for the cross product.
        """
        return _openmm.OutOfPlaneSite_getWeightCross(self)

    def __init__(self, *args):
        r"""
        __init__(self, particle1, particle2, particle3, weight12, weight13, weightCross) -> OutOfPlaneSite
        __init__(self, other) -> OutOfPlaneSite
        Create a new OutOfPlaneSite virtual site.

        Parameters
        ----------
        particle1 : int
            the index of the first particle
        particle2 : int
            the index of the second particle
        particle3 : int
            the index of the third particle
        weight12 : double
            the weight factor for the vector from particle1 to particle2
        weight13 : double
            the weight factor for the vector from particle1 to particle3
        weightCross : double
            the weight factor for the cross product
        """
        _openmm.OutOfPlaneSite_swiginit(self, _openmm.new_OutOfPlaneSite(*args))
    __swig_destroy__ = _openmm.delete_OutOfPlaneSite

# Register OutOfPlaneSite in _openmm:
_openmm.OutOfPlaneSite_swigregister(OutOfPlaneSite)

class PeriodicTorsionForce(Force):
    r"""This class implements an interaction between groups of four particles that varies periodically with the torsion angle between them. To use it, create a PeriodicTorsionForce object then call addTorsion() once for each torsion. After a torsion has been added, you can modify its force field parameters by calling setTorsionParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext()."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumTorsions(self):
        r"""
        getNumTorsions(self) -> int
        Get the number of periodic torsion terms in the potential function
        """
        return _openmm.PeriodicTorsionForce_getNumTorsions(self)

    def addTorsion(self, particle1, particle2, particle3, particle4, periodicity, phase, k):
        r"""
        addTorsion(self, particle1, particle2, particle3, particle4, periodicity, phase, k) -> int
        Add a periodic torsion term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        periodicity : int
            the periodicity of the torsion
        phase : double
            the phase offset of the torsion, measured in radians
        k : double
            the force constant for the torsion

        Returns
        -------
        int
            the index of the torsion that was added
        """
        return _openmm.PeriodicTorsionForce_addTorsion(self, particle1, particle2, particle3, particle4, periodicity, phase, k)

    def getTorsionParameters(self, index):
        r"""
        getTorsionParameters(self, index)
        Get the force field parameters for a periodic torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        periodicity : int
            the periodicity of the torsion
        phase : double
            the phase offset of the torsion, measured in radians
        k : double
            the force constant for the torsion
        """
        val = _openmm.PeriodicTorsionForce_getTorsionParameters(self, index)

        val[5]=unit.Quantity(val[5], unit.radian)
        val[6]=unit.Quantity(val[6], unit.kilojoule_per_mole)


        return val


    def setTorsionParameters(self, index, particle1, particle2, particle3, particle4, periodicity, phase, k):
        r"""
        setTorsionParameters(self, index, particle1, particle2, particle3, particle4, periodicity, phase, k)
        Set the force field parameters for a periodic torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to set parameters
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        periodicity : int
            the periodicity of the torsion
        phase : double
            the phase offset of the torsion, measured in radians
        k : double
            the force constant for the torsion
        """
        return _openmm.PeriodicTorsionForce_setTorsionParameters(self, index, particle1, particle2, particle3, particle4, periodicity, phase, k)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-torsion parameters. The set of particles involved in a torsion cannot be changed, nor can new torsions be added.
        """
        return _openmm.PeriodicTorsionForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.PeriodicTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.PeriodicTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> PeriodicTorsionForce
        __init__(self, other) -> PeriodicTorsionForce
        Create a PeriodicTorsionForce.
        """
        _openmm.PeriodicTorsionForce_swiginit(self, _openmm.new_PeriodicTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_PeriodicTorsionForce

# Register PeriodicTorsionForce in _openmm:
_openmm.PeriodicTorsionForce_swigregister(PeriodicTorsionForce)

class Platform(object):
    r"""
    A Platform defines an implementation of all the kernels needed to perform some calculation. More precisely, a Platform object acts as a registry for a set of KernelFactory objects which together implement the kernels. The Platform class, in turn, provides a static registry of all available Platform objects.

    To get a Platform object, call

    <pre>
    Platform& platform = Platform::findPlatform(kernelNames);
    </pre>

    passing in the names of all kernels that will be required for the calculation you plan to perform. It will return the fastest available Platform which provides implementations of all the specified kernels. You can then call createKernel() to construct particular kernels as needed.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_Platform

    @staticmethod
    def registerPlatform(platform):
        r"""
        registerPlatform(platform)
        Register a new Platform.
        """

        if not platform.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.Platform_registerPlatform(platform)

        platform.thisown=0


        return val

    @staticmethod
    def getNumPlatforms():
        r"""
        getNumPlatforms() -> int
        Get the number of Platforms that have been registered.
        """
        return _openmm.Platform_getNumPlatforms()

    @staticmethod
    def getPlatform(index):
        r"""
        getPlatform(index) -> Platform
        Get a registered Platform by index.
        """
        return _openmm.Platform_getPlatform(index)

    @staticmethod
    def getPluginLoadFailures():
        r"""
        getPluginLoadFailures() -> vectorstring
        Get any failures caused during the last call to loadPluginsFromDirectory
        """
        return _openmm.Platform_getPluginLoadFailures()

    @staticmethod
    def getPlatformByName(name):
        r"""
        getPlatformByName(name) -> Platform
        Get the registered Platform with a particular name. If no Platform with that name has been registered, this throws an exception.
        """
        return _openmm.Platform_getPlatformByName(name)

    @staticmethod
    def findPlatform(kernelNames):
        r"""
        findPlatform(kernelNames) -> Platform
        Find a Platform which can be used to perform a calculation.

        Parameters
        ----------
        kernelNames : vector< std::string >
            the names of all kernels which will be needed for the calculation

        Returns
        -------
        Platform
            the fastest registered Platform which supports all of the requested kernels. If no Platform exists which supports all of them, this will throw an exception.
        """
        return _openmm.Platform_findPlatform(kernelNames)

    @staticmethod
    def loadPluginLibrary(file):
        r"""
        loadPluginLibrary(file)
        Load a dynamic library (DLL) which contains an OpenMM plugin. Typically, each Platform is distributed as a separate dynamic library. This method can then be called at runtime to load each available library. Each library should contain an initializer function to register any Platforms and KernelFactories that it contains.

        If the file does not exist or cannot be loaded, an exception is thrown.

        Parameters
        ----------
        file : string
            the path to the dynamic library file. This is interpreted using the operating system's rules for loading libraries. Typically it may be either an absolute path or relative to a set of standard locations.
        """
        return _openmm.Platform_loadPluginLibrary(file)

    @staticmethod
    def loadPluginsFromDirectory(directory):
        r"""
        loadPluginsFromDirectory(directory) -> vectorstring
        Load multiple dynamic libraries (DLLs) which contain OpenMM plugins from one or more directories. Multiple fully-qualified paths can be joined together with ':' on unix-like systems (or ';' on windows-like systems); each will be searched for plugins, in-order. For example, '/foo/plugins:/bar/plugins' will search both <tt>/foo/plugins</tt> and <tt>/bar/plugins</tt>. If an identically-named plugin is encountered twice it will be loaded at both points; be careful!!!

        This method loops over every file contained in the specified directories and calls loadPluginLibrary() for each one. If an error occurs while trying to load a particular file, that file is simply ignored. You can retrieve a list of all such errors by calling getPluginLoadFailures().

        Parameters
        ----------
        directory : string
            a ':' (unix) or ';' (windows) deliminated list of paths containing libraries to load

        Returns
        -------
        vector< std::string >
            the names of all files which were successfully loaded as libraries
        """
        return _openmm.Platform_loadPluginsFromDirectory(directory)

    @staticmethod
    def getDefaultPluginsDirectory():
        r"""
        getDefaultPluginsDirectory() -> std::string const &
        Get the default directory from which to load plugins. If the environment variable OPENMM_PLUGIN_DIR is set, this returns its value. Otherwise, it returns a platform specific default location.

        Returns
        -------
        string
            the path to the default plugin directory
        """
        return _openmm.Platform_getDefaultPluginsDirectory()

    @staticmethod
    def getOpenMMVersion():
        r"""
        getOpenMMVersion() -> std::string const &
        Get a string containing the version number of the OpenMM library.
        """
        return _openmm.Platform_getOpenMMVersion()

    def getName(self):
        r"""
        getName(self) -> std::string const &
        Get the name of this platform. This should be a unique identifier which can be used to recognized it.
        """
        return _openmm.Platform_getName(self)

    def getSpeed(self):
        r"""
        getSpeed(self) -> double
        Get an estimate of how fast this Platform class is. This need not be precise. It only is expected to return an order or magnitude estimate of the relative performance of different Platform classes. An unoptimized reference implementation should return 1.0, and all other Platforms should return a larger value that is an estimate of how many times faster they are than the reference implementation.
        """
        return _openmm.Platform_getSpeed(self)

    def supportsDoublePrecision(self):
        r"""
        supportsDoublePrecision(self) -> bool
        Get whether this Platform supports double precision arithmetic. If this returns false, the platform is permitted to represent double precision values internally as single precision.

         @deprecated This method is not well defined, and is too simplistic to describe the actual behavior of some Platforms, such as ones that offer multiple precision modes. It will be removed in a future release.
        """
        return _openmm.Platform_supportsDoublePrecision(self)

    def getPropertyNames(self):
        r"""
        getPropertyNames(self) -> vectorstring
        Get the names of all Platform-specific properties this Platform supports.
        """
        return _openmm.Platform_getPropertyNames(self)

    def getPropertyValue(self, context, property):
        r"""
        getPropertyValue(self, context, property) -> std::string const &
        Get the value of a Platform-specific property for a Context.

        Parameters
        ----------
        context : Context
            the Context for which to get the property
        property : string
            the name of the property to get

        Returns
        -------
        string
            the value of the property
        """
        return _openmm.Platform_getPropertyValue(self, context, property)

    def setPropertyValue(self, context, property, value):
        r"""
        setPropertyValue(self, context, property, value)
        Set the value of a Platform-specific property for a Context.

        Parameters
        ----------
        context : Context
            the Context for which to set the property
        property : string
            the name of the property to set
        value : string
            the value to set for the property
        """
        return _openmm.Platform_setPropertyValue(self, context, property, value)

    def getPropertyDefaultValue(self, property):
        r"""
        getPropertyDefaultValue(self, property) -> std::string const &
        Get the default value of a Platform-specific property. This is the value that will be used for newly created Contexts.

        Parameters
        ----------
        property : string
            the name of the property to get

        Returns
        -------
        string
            the default value of the property
        """
        return _openmm.Platform_getPropertyDefaultValue(self, property)

    def setPropertyDefaultValue(self, property, value):
        r"""
        setPropertyDefaultValue(self, property, value)
        Set the default value of a Platform-specific property. This is the value that will be used for newly created Contexts.

        Parameters
        ----------
        property : string
            the name of the property to set
        value : string
            the value to set for the property
        """
        return _openmm.Platform_setPropertyDefaultValue(self, property, value)

    def linkedContextCreated(self, context, originalContext):
        r"""
        linkedContextCreated(self, context, originalContext)
        This is called whenever a new Context is created using ContextImpl::createLinkedContext(). It gives the Platform a chance to initialize the context and store platform-specific data in it.

        Parameters
        ----------
        context : ContextImpl
            the newly created context
        originalContext : ContextImpl
            the original context it is linked to
        """
        return _openmm.Platform_linkedContextCreated(self, context, originalContext)

    def supportsKernels(self, kernelNames):
        r"""
        supportsKernels(self, kernelNames) -> bool
        Determine whether this Platforms provides implementations of a set of kernels.

        Parameters
        ----------
        kernelNames : vector< std::string >
            the names of the kernels of interests

        Returns
        -------
        bool
            true if this Platform provides implementations of all the kernels in the list, false if there are any which it does not support
        """
        return _openmm.Platform_supportsKernels(self, kernelNames)

# Register Platform in _openmm:
_openmm.Platform_swigregister(Platform)

def Platform_registerPlatform(platform):
    r"""
    Platform_registerPlatform(platform)
    Register a new Platform.
    """

    if not platform.thisown:
        s = ("the %s object does not own its corresponding OpenMM object"
             % self.__class__.__name__)
        raise Exception(s)


    val = _openmm.Platform_registerPlatform(platform)

    platform.thisown=0


    return val

def Platform_getNumPlatforms():
    r"""
    Platform_getNumPlatforms() -> int
    Get the number of Platforms that have been registered.
    """
    return _openmm.Platform_getNumPlatforms()

def Platform_getPlatform(index):
    r"""
    Platform_getPlatform(index) -> Platform
    Get a registered Platform by index.
    """
    return _openmm.Platform_getPlatform(index)

def Platform_getPluginLoadFailures():
    r"""
    Platform_getPluginLoadFailures() -> vectorstring
    Get any failures caused during the last call to loadPluginsFromDirectory
    """
    return _openmm.Platform_getPluginLoadFailures()

def Platform_getPlatformByName(name):
    r"""
    Platform_getPlatformByName(name) -> Platform
    Get the registered Platform with a particular name. If no Platform with that name has been registered, this throws an exception.
    """
    return _openmm.Platform_getPlatformByName(name)

def Platform_findPlatform(kernelNames):
    r"""
    Platform_findPlatform(kernelNames) -> Platform
    Find a Platform which can be used to perform a calculation.

    Parameters
    ----------
    kernelNames : vector< std::string >
        the names of all kernels which will be needed for the calculation

    Returns
    -------
    Platform
        the fastest registered Platform which supports all of the requested kernels. If no Platform exists which supports all of them, this will throw an exception.
    """
    return _openmm.Platform_findPlatform(kernelNames)

def Platform_loadPluginLibrary(file):
    r"""
    Platform_loadPluginLibrary(file)
    Load a dynamic library (DLL) which contains an OpenMM plugin. Typically, each Platform is distributed as a separate dynamic library. This method can then be called at runtime to load each available library. Each library should contain an initializer function to register any Platforms and KernelFactories that it contains.

    If the file does not exist or cannot be loaded, an exception is thrown.

    Parameters
    ----------
    file : string
        the path to the dynamic library file. This is interpreted using the operating system's rules for loading libraries. Typically it may be either an absolute path or relative to a set of standard locations.
    """
    return _openmm.Platform_loadPluginLibrary(file)

def Platform_loadPluginsFromDirectory(directory):
    r"""
    Platform_loadPluginsFromDirectory(directory) -> vectorstring
    Load multiple dynamic libraries (DLLs) which contain OpenMM plugins from one or more directories. Multiple fully-qualified paths can be joined together with ':' on unix-like systems (or ';' on windows-like systems); each will be searched for plugins, in-order. For example, '/foo/plugins:/bar/plugins' will search both <tt>/foo/plugins</tt> and <tt>/bar/plugins</tt>. If an identically-named plugin is encountered twice it will be loaded at both points; be careful!!!

    This method loops over every file contained in the specified directories and calls loadPluginLibrary() for each one. If an error occurs while trying to load a particular file, that file is simply ignored. You can retrieve a list of all such errors by calling getPluginLoadFailures().

    Parameters
    ----------
    directory : string
        a ':' (unix) or ';' (windows) deliminated list of paths containing libraries to load

    Returns
    -------
    vector< std::string >
        the names of all files which were successfully loaded as libraries
    """
    return _openmm.Platform_loadPluginsFromDirectory(directory)

def Platform_getDefaultPluginsDirectory():
    r"""
    Platform_getDefaultPluginsDirectory() -> std::string const &
    Get the default directory from which to load plugins. If the environment variable OPENMM_PLUGIN_DIR is set, this returns its value. Otherwise, it returns a platform specific default location.

    Returns
    -------
    string
        the path to the default plugin directory
    """
    return _openmm.Platform_getDefaultPluginsDirectory()

def Platform_getOpenMMVersion():
    r"""
    Platform_getOpenMMVersion() -> std::string const &
    Get a string containing the version number of the OpenMM library.
    """
    return _openmm.Platform_getOpenMMVersion()

class RBTorsionForce(Force):
    r"""This class implements an interaction between groups of four particles that varies with the torsion angle between them according to the Ryckaert-Bellemans potential. To use it, create an RBTorsionForce object then call addTorsion() once for each torsion. After a torsion has been added, you can modify its force field parameters by calling setTorsionParameters(). This will have no effect on Contexts that already exist unless you call updateParametersInContext()."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumTorsions(self):
        r"""
        getNumTorsions(self) -> int
        Get the number of Ryckaert-Bellemans torsion terms in the potential function
        """
        return _openmm.RBTorsionForce_getNumTorsions(self)

    def addTorsion(self, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5):
        r"""
        addTorsion(self, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5) -> int
        Add a Ryckaert-Bellemans torsion term to the force field.

        Parameters
        ----------
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        c0 : double
            the coefficient of the constant term, measured in kJ/mol
        c1 : double
            the coefficient of the 1st order term, measured in kJ/mol
        c2 : double
            the coefficient of the 2nd order term, measured in kJ/mol
        c3 : double
            the coefficient of the 3rd order term, measured in kJ/mol
        c4 : double
            the coefficient of the 4th order term, measured in kJ/mol
        c5 : double
            the coefficient of the 5th order term, measured in kJ/mol

        Returns
        -------
        int
            the index of the torsion that was added
        """
        return _openmm.RBTorsionForce_addTorsion(self, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5)

    def getTorsionParameters(self, index):
        r"""
        getTorsionParameters(self, index)
        Get the force field parameters for a Ryckaert-Bellemans torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        c0 : double
            the coefficient of the constant term, measured in kJ/mol
        c1 : double
            the coefficient of the 1st order term, measured in kJ/mol
        c2 : double
            the coefficient of the 2nd order term, measured in kJ/mol
        c3 : double
            the coefficient of the 3rd order term, measured in kJ/mol
        c4 : double
            the coefficient of the 4th order term, measured in kJ/mol
        c5 : double
            the coefficient of the 5th order term, measured in kJ/mol
        """
        val = _openmm.RBTorsionForce_getTorsionParameters(self, index)

        val[4]=unit.Quantity(val[4], unit.kilojoules_per_mole)
        val[5]=unit.Quantity(val[5], unit.kilojoules_per_mole)
        val[6]=unit.Quantity(val[6], unit.kilojoules_per_mole)
        val[7]=unit.Quantity(val[7], unit.kilojoules_per_mole)
        val[8]=unit.Quantity(val[8], unit.kilojoules_per_mole)
        val[9]=unit.Quantity(val[9], unit.kilojoules_per_mole)


        return val


    def setTorsionParameters(self, index, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5):
        r"""
        setTorsionParameters(self, index, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5)
        Set the force field parameters for a Ryckaert-Bellemans torsion term.

        Parameters
        ----------
        index : int
            the index of the torsion for which to set parameters
        particle1 : int
            the index of the first particle forming the torsion
        particle2 : int
            the index of the second particle forming the torsion
        particle3 : int
            the index of the third particle forming the torsion
        particle4 : int
            the index of the fourth particle forming the torsion
        c0 : double
            the coefficient of the constant term, measured in kJ/mol
        c1 : double
            the coefficient of the 1st order term, measured in kJ/mol
        c2 : double
            the coefficient of the 2nd order term, measured in kJ/mol
        c3 : double
            the coefficient of the 3rd order term, measured in kJ/mol
        c4 : double
            the coefficient of the 4th order term, measured in kJ/mol
        c5 : double
            the coefficient of the 5th order term, measured in kJ/mol
        """
        return _openmm.RBTorsionForce_setTorsionParameters(self, index, particle1, particle2, particle3, particle4, c0, c1, c2, c3, c4, c5)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.

        The only information this method updates is the values of per-torsion parameters. The set of particles involved in a torsion cannot be changed, nor can new torsions be added.
        """
        return _openmm.RBTorsionForce_updateParametersInContext(self, context)

    def setUsesPeriodicBoundaryConditions(self, periodic):
        r"""
        setUsesPeriodicBoundaryConditions(self, periodic)
        Set whether this force should apply periodic boundary conditions when calculating displacements. Usually this is not appropriate for bonded forces, but there are situations when it can be useful.
        """
        return _openmm.RBTorsionForce_setUsesPeriodicBoundaryConditions(self, periodic)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.RBTorsionForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> RBTorsionForce
        __init__(self, other) -> RBTorsionForce
        Create a RBTorsionForce.
        """
        _openmm.RBTorsionForce_swiginit(self, _openmm.new_RBTorsionForce(*args))
    __swig_destroy__ = _openmm.delete_RBTorsionForce

# Register RBTorsionForce in _openmm:
_openmm.RBTorsionForce_swigregister(RBTorsionForce)

class RMSDForce(Force):
    r"""
    This is a force whose energy equals the root mean squared deviation (RMSD) between the current coordinates and a reference structure. It is intended for use with CustomCVForce. You will not normally want a force that exactly equals the RMSD, but there are many situations where it is useful to have a restraining or biasing force that depends on the RMSD in some way.

    The force is computed by first aligning the particle positions to the reference structure, then computing the RMSD between the aligned positions and the reference. The computation can optionally be done based on only a subset of the particles in the system.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getReferencePositions(self):
        r"""
        getReferencePositions(self) -> std::vector< Vec3,std::allocator< Vec3 > > const &
        Get the reference positions to compute the deviation from.
        """
        val = _openmm.RMSDForce_getReferencePositions(self)

        val=unit.Quantity(val, unit.nanometer)


        return val


    def setReferencePositions(self, positions):
        r"""
        setReferencePositions(self, positions)
        Set the reference positions to compute the deviation from.
        """
        return _openmm.RMSDForce_setReferencePositions(self, positions)

    def getParticles(self):
        r"""
        getParticles(self) -> vectori
        Get the indices of the particles to use when computing the RMSD. If this is empty, all particles in the system will be used.
        """
        return _openmm.RMSDForce_getParticles(self)

    def setParticles(self, particles):
        r"""
        setParticles(self, particles)
        Set the indices of the particles to use when computing the RMSD. If this is empty, all particles in the system will be used.
        """
        return _openmm.RMSDForce_setParticles(self, particles)

    def updateParametersInContext(self, context):
        r"""
        updateParametersInContext(self, context)
        Update the reference positions and particle indices in a Context to match those stored in this Force object. This method provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. Simply call setReferencePositions() and setParticles() to modify this object's parameters, then call updateParametersInContext() to copy them over to the Context.
        """
        return _openmm.RMSDForce_updateParametersInContext(self, context)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.RMSDForce_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, referencePositions, particles=std::vector< int >()) -> RMSDForce
        __init__(self, other) -> RMSDForce
        Create an RMSDForce.

        Parameters
        ----------
        referencePositions : vector< Vec3 >
            the reference positions to compute the deviation from. The length of this vector must equal the number of particles in the system, even if not all particles are used in computing the RMSD.
        particles : vector< int >
            the indices of the particles to use when computing the RMSD. If this is empty (the default), all particles in the system will be used.
        """
        _openmm.RMSDForce_swiginit(self, _openmm.new_RMSDForce(*args))
    __swig_destroy__ = _openmm.delete_RMSDForce

# Register RMSDForce in _openmm:
_openmm.RMSDForce_swigregister(RMSDForce)

class RPMDIntegrator(Integrator):
    r"""
    This is an Integrator which simulates a System using ring polymer molecular dynamics (RPMD). It simulates many copies of the System, with successive copies connected by harmonic springs to form a ring. This allows certain quantum mechanical effects to be efficiently simulated.

    By default this Integrator applies a PILE thermostat to the system to simulate constant temperature dynamics. You can disable the thermostat by calling setApplyThermostat(false).

    Because this Integrator simulates many copies of the System at once, it must be used differently from other Integrators. Instead of setting positions and velocities by calling methods of the Context, you should use the corresponding methods of the Integrator to set them for specific copies of the System. Similarly, you should retrieve state information for particular copies by calling getState() on the Integrator. Do not query the Context for state information.

    You can optionally specify a set of "ring polymer contractions", by which different force groups are evaluated on different numbers of copies, instead of computing every force on every copy. This can be much more efficient, since different forces may vary widely in how many times they must be evaluated to produce sufficient accuracy. For example, you might simulate a 32 copy ring polymer and evaluate bonded forces on every copy, but contract it down to only 6 copies for computing nonbonded interactions, and down to only a single copy (the centroid) for computing the reciprocal space part of PME.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getNumCopies(self):
        r"""
        getNumCopies(self) -> int
        Get the number of copies of the system being simulated.
        """
        return _openmm.RPMDIntegrator_getNumCopies(self)

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.RPMDIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.RPMDIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.RPMDIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.RPMDIntegrator_setFriction(self, coeff)

    def getApplyThermostat(self):
        r"""
        getApplyThermostat(self) -> bool
        Get whether a thermostat is applied to the system.
        """
        return _openmm.RPMDIntegrator_getApplyThermostat(self)

    def setApplyThermostat(self, apply):
        r"""
        setApplyThermostat(self, apply)
        Set whether a thermostat is applied to the system.
        """
        return _openmm.RPMDIntegrator_setApplyThermostat(self, apply)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.RPMDIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.RPMDIntegrator_setRandomNumberSeed(self, seed)

    def getContractions(self):
        r"""
        getContractions(self) -> mapii
        Get the ring polymer contractions to use for evaluating different force groups. Each key in the map is the index of a force group, and the corresponding value is the number of copies to evaluate that force group on. If no entry is provided for a force group, it is evaluated independently on every copy.
        """
        return _openmm.RPMDIntegrator_getContractions(self)

    def setPositions(self, copy, positions):
        r"""
        setPositions(self, copy, positions)
        Set the positions of all particles in one copy of the system.

        Parameters
        ----------
        copy : int
            the index of the copy for which to set positions
        positions : vector< Vec3 >
            the positions of all particles in the system
        """
        return _openmm.RPMDIntegrator_setPositions(self, copy, positions)

    def setVelocities(self, copy, velocities):
        r"""
        setVelocities(self, copy, velocities)
        Get the velocities of all particles in one copy of the system.

        Parameters
        ----------
        copy : int
            the index of the copy for which to set velocities
        velocities : vector< Vec3 >
            the velocities of all particles in the system
        """
        return _openmm.RPMDIntegrator_setVelocities(self, copy, velocities)

    def getState(self, *args):
        r"""
        getState(self, copy, types, enforcePeriodicBox=False, groups=0xFFFFFFFF) -> State
        Get a State object recording the current state information about one copy of the system.

        Parameters
        ----------
        copy : int
            the index of the copy for which to retrieve state information
        types : int
            the set of data types which should be stored in the State object. This should be a union of DataType values, e.g. (State::Positions | State::Velocities).
        enforcePeriodicBox : bool
            if false, the position of each particle will be whatever position is stored by the integrator, regardless of periodic boundary conditions. If true, particle positions will be translated so the center of every molecule lies in the same periodic box.
        groups : int
            a set of bit flags for which force groups to include when computing forces and energies. Group i will be included if (groups&(1<<i)) != 0. The default value includes all groups.
        """
        return _openmm.RPMDIntegrator_getState(self, *args)

    def getTotalEnergy(self):
        r"""
        getTotalEnergy(self) -> double
        Get the total energy of the ring polymer. This includes the potential and kinetic energies of all copies, plus the potential energy of the harmonic springs that link copies together.
        """
        val = _openmm.RPMDIntegrator_getTotalEnergy(self)

        val=unit.Quantity(val, unit.kilojoules_per_mole)


        return val


    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.RPMDIntegrator_step(self, steps)

    def getState(self,
                 copy,
                 getPositions=False,
                 getVelocities=False,
                 getForces=False,
                 getEnergy=False,
                 getParameters=False,
                 getParameterDerivatives=False,
                 enforcePeriodicBox=False,
                 groups=-1):
        """Get a State object recording the current state information about one copy of the system.

        Parameters
        ----------
        copy : int
            the index of the copy for which to retrieve state information
        getPositions : bool=False
            whether to store particle positions in the State
        getVelocities : bool=False
            whether to store particle velocities in the State
        getForces : bool=False
            whether to store the forces acting on particles in the State
        getEnergy : bool=False
            whether to store potential and kinetic energy in the State
        getParameters : bool=False
            whether to store context parameters in the State
        getParameterDerivatives : bool=False
            whether to store parameter derivatives in the State
        enforcePeriodicBox : bool=False
            if false, the position of each particle will be whatever position
            is stored in the Context, regardless of periodic boundary conditions.
            If true, particle positions will be translated so the center of
            every molecule lies in the same periodic box.
        groups : set={0,1,2,...,31}
            a set of indices for which force groups to include when computing
            forces and energies. The default value includes all groups. groups
            can also be passed as an unsigned integer interpreted as a bitmask,
            in which case group i will be included if (groups&(1<<i)) != 0.
        """
        getP, getV, getF, getE, getPa, getPd, enforcePeriodic = map(bool,
            (getPositions, getVelocities, getForces, getEnergy, getParameters,
             getParameterDerivatives, enforcePeriodicBox))

        try:
    # is the input integer-like?
            groups_mask = int(groups)
        except TypeError:
            if isinstance(groups, set):
                groups_mask = functools.reduce(operator.or_,
                        ((1<<x) & 0xffffffff for x in groups))
            else:
                raise TypeError('%s is neither an int nor set' % groups)
        if groups_mask >= 0x80000000:
            groups_mask -= 0x100000000
        types = 0
        if getPositions:
            types += State.Positions
        if getVelocities:
            types += State.Velocities
        if getForces:
            types += State.Forces
        if getEnergy:
            types += State.Energy
        if getParameters:
            types += State.Parameters
        if getParameterDerivatives:
            types += State.ParameterDerivatives
        state = _openmm.RPMDIntegrator_getState(self, copy, types, enforcePeriodicBox, groups_mask)
        return state


    def __init__(self, *args):
        r"""
        __init__(self, numCopies, temperature, frictionCoeff, stepSize) -> RPMDIntegrator
        __init__(self, numCopies, temperature, frictionCoeff, stepSize, contractions) -> RPMDIntegrator
        __init__(self, other) -> RPMDIntegrator
        Create a RPMDIntegrator.

        Parameters
        ----------
        numCopies : int
            the number of copies of the system that should be simulated
        temperature : double
            the temperature of the heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
        stepSize : double
            the step size with which to integrator the system (in picoseconds)
        contractions : map< int, int >
            the ring polymer contractions to use for evaluating different force groups. Each key in the map is the index of a force group, and the corresponding value is the number of copies to evaluate that force group on. If no entry is provided for a force group (the default), it is evaluated independently on every copy.
        """
        _openmm.RPMDIntegrator_swiginit(self, _openmm.new_RPMDIntegrator(*args))
    __swig_destroy__ = _openmm.delete_RPMDIntegrator

# Register RPMDIntegrator in _openmm:
_openmm.RPMDIntegrator_swigregister(RPMDIntegrator)

class RPMDMonteCarloBarostat(Force):
    r"""This class is very similar to MonteCarloBarostat, but it is specifically designed for use with RPMDIntegrator. For each trial move, it scales all copies of the system by the same amount, then accepts or rejects the move based on the change to the total energy of the ring polymer (as returned by the integrator's getTotalEnergy() method)."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    @staticmethod
    def Pressure():
        r"""
        Pressure() -> std::string const &
        This is the name of the parameter which stores the current pressure acting on the system (in bar).
        """
        return _openmm.RPMDMonteCarloBarostat_Pressure()

    def getDefaultPressure(self):
        r"""
        getDefaultPressure(self) -> double
        Get the default pressure acting on the system (in bar).

        Returns
        -------
        double
            the default pressure acting on the system, measured in bar.
        """
        val = _openmm.RPMDMonteCarloBarostat_getDefaultPressure(self)

        val=unit.Quantity(val, unit.bar)


        return val


    def setDefaultPressure(self, pressure):
        r"""
        setDefaultPressure(self, pressure)
        Set the default pressure acting on the system. This will affect any new Contexts you create, but not ones that already exist.

        Parameters
        ----------
        pressure : double
            the default pressure acting on the system, measured in bar.
        """

        if unit.is_quantity(pressure):
            pressure = pressure.value_in_unit(unit.bar)


        return _openmm.RPMDMonteCarloBarostat_setDefaultPressure(self, pressure)


    def getFrequency(self):
        r"""
        getFrequency(self) -> int
        Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.RPMDMonteCarloBarostat_getFrequency(self)

    def setFrequency(self, freq):
        r"""
        setFrequency(self, freq)
        Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to 0, the barostat is disabled.
        """
        return _openmm.RPMDMonteCarloBarostat_setFrequency(self, freq)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.RPMDMonteCarloBarostat_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. It is guaranteed that if two simulations are run with different random number seeds, the sequence of Monte Carlo steps will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.RPMDMonteCarloBarostat_setRandomNumberSeed(self, seed)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            true if force uses PBC and false otherwise
        """
        return _openmm.RPMDMonteCarloBarostat_usesPeriodicBoundaryConditions(self)

    def __init__(self, *args):
        r"""
        __init__(self, defaultPressure, frequency=25) -> RPMDMonteCarloBarostat
        __init__(self, other) -> RPMDMonteCarloBarostat
        Create a MonteCarloBarostat.

        Parameters
        ----------
        defaultPressure : double
            the default pressure acting on the system (in bar)
        frequency : int
            the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
        """
        _openmm.RPMDMonteCarloBarostat_swiginit(self, _openmm.new_RPMDMonteCarloBarostat(*args))
    __swig_destroy__ = _openmm.delete_RPMDMonteCarloBarostat

# Register RPMDMonteCarloBarostat in _openmm:
_openmm.RPMDMonteCarloBarostat_swigregister(RPMDMonteCarloBarostat)

def RPMDMonteCarloBarostat_Pressure():
    r"""
    RPMDMonteCarloBarostat_Pressure() -> std::string const &
    This is the name of the parameter which stores the current pressure acting on the system (in bar).
    """
    return _openmm.RPMDMonteCarloBarostat_Pressure()

class SerializationNode(object):
    r"""
    A SerializationNode stores information about an object during serialization or deserialization.

    When an object is serialized, its SerializationProxy is first called to copy information about the object into a SerializationNode. That information can then be written to the output stream in the desired format.

    When an object is deserialized, the input stream is read and the information is stored into a SerializationNode. The appropriate SerializationProxy is then called to reconstruct the object.

    SerializationNodes are arranged in a tree. There will often be a one-to-one correspondence between objects and SerializationNodes, but that need not always be true. A proxy is free to create whatever child nodes it wants and store information in them using whatever organization is most convenient.

    Each SerializationNode can store an arbitrary set of "properties", represented as key-value pairs. The key is always a string, while the value may be a string, an int, or a double. If a value is specified using one data type and then accessed as a different data type, the node will attempt to convert the value in an appropriate way. For example, it is always reasonable to call getStringProperty() to access a property as a string. Similarly, you can use setStringProperty() to specify a property and then access it using getIntProperty(). This will produce the expected result if the original value was, in fact, the string representation of an int, but if the original string was non-numeric, the result is undefined.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def getName(self):
        r"""
        getName(self) -> std::string const &
        Get the name of this SerializationNode.
        """
        return _openmm.SerializationNode_getName(self)

    def setName(self, name):
        r"""
        setName(self, name)
        Set the name of this SerializationNode.

        Parameters
        ----------
        name : string
            the new name of the SerializationNode
        """
        return _openmm.SerializationNode_setName(self, name)

    def getChildren(self, *args):
        r"""
        getChildren(self) -> std::vector< OpenMM::SerializationNode,std::allocator< OpenMM::SerializationNode > > const
        getChildren(self) -> std::vector< OpenMM::SerializationNode,std::allocator< OpenMM::SerializationNode > > &
        Get a reference to this node's child nodes.
        """
        return _openmm.SerializationNode_getChildren(self, *args)

    def getChildNode(self, *args):
        r"""
        getChildNode(self, name) -> SerializationNode
        getChildNode(self, name) -> SerializationNode
        Get a reference to the child node with a particular name. If there is no child with the specified name, this throws an exception.

        Parameters
        ----------
        the : string
            name of the child node to get
        """
        return _openmm.SerializationNode_getChildNode(self, *args)

    def getProperties(self):
        r"""
        getProperties(self) -> mapstringstring
        Get a map containing all of this node's properties.
        """
        return _openmm.SerializationNode_getProperties(self)

    def hasProperty(self, name):
        r"""
        hasProperty(self, name) -> bool
        Determine whether this node has a property with a particular node.

        Parameters
        ----------
        name : string
            the name of the property to check for
        """
        return _openmm.SerializationNode_hasProperty(self, name)

    def getStringProperty(self, *args):
        r"""
        getStringProperty(self, name) -> std::string const
        getStringProperty(self, name, defaultValue) -> std::string const &
        Get the property with a particular name, specified as a string. If there is no property with the specified name, a default value is returned instead.

        Parameters
        ----------
        name : string
            the name of the property to get
        defaultValue : string
            the value to return if the specified property does not exist
        """
        return _openmm.SerializationNode_getStringProperty(self, *args)

    def setStringProperty(self, name, value):
        r"""
        setStringProperty(self, name, value) -> SerializationNode
        Set the value of a property, specified as a string.

        Parameters
        ----------
        name : string
            the name of the property to set
        value : string
            the value to set for the property
        """
        return _openmm.SerializationNode_setStringProperty(self, name, value)

    def getIntProperty(self, *args):
        r"""
        getIntProperty(self, name) -> int
        getIntProperty(self, name, defaultValue) -> int
        Get the property with a particular name, specified as an int. If there is no property with the specified name, a default value is returned instead.

        Parameters
        ----------
        name : string
            the name of the property to get
        defaultValue : int
            the value to return if the specified property does not exist
        """
        return _openmm.SerializationNode_getIntProperty(self, *args)

    def setIntProperty(self, name, value):
        r"""
        setIntProperty(self, name, value) -> SerializationNode
        Set the value of a property, specified as an int.

        Parameters
        ----------
        name : string
            the name of the property to set
        value : int
            the value to set for the property
        """
        return _openmm.SerializationNode_setIntProperty(self, name, value)

    def getBoolProperty(self, *args):
        r"""
        getBoolProperty(self, name) -> bool
        getBoolProperty(self, name, defaultValue) -> bool
        Get the property with a particular name, specified as a bool. If there is no property with the specified name, a default value is returned instead.

        Parameters
        ----------
        name : string
            the name of the property to get
        defaultValue : bool
            the value to return if the specified property does not exist
        """
        return _openmm.SerializationNode_getBoolProperty(self, *args)

    def setBoolProperty(self, name, value):
        r"""
        setBoolProperty(self, name, value) -> SerializationNode
        Set the value of a property, specified as a bool.

        Parameters
        ----------
        name : string
            the name of the property to set
        value : bool
            the value to set for the property
        """
        return _openmm.SerializationNode_setBoolProperty(self, name, value)

    def getDoubleProperty(self, *args):
        r"""
        getDoubleProperty(self, name) -> double
        getDoubleProperty(self, name, defaultValue) -> double
        Get the property with a particular name, specified as a double. If there is no property with the specified name, a default value is returned instead.

        Parameters
        ----------
        name : string
            the name of the property to get
        defaultValue : double
            the value to return if the specified property does not exist
        """
        return _openmm.SerializationNode_getDoubleProperty(self, *args)

    def setDoubleProperty(self, name, value):
        r"""
        setDoubleProperty(self, name, value) -> SerializationNode
        Set the value of a property, specified as a double.

        Parameters
        ----------
        name : string
            the name of the property to set
        value : double
            the value to set for the property
        """
        return _openmm.SerializationNode_setDoubleProperty(self, name, value)

    def createChildNode(self, name):
        r"""
        createChildNode(self, name) -> SerializationNode
        Create a new child node by serializing an object. A SerializationProxy is automatically selected based on the object's type, then invoked to populate the newly created node.

        Note that, while this method is templatized based on the type of object being serialized, the typeid() operator is used to select the proxy. This means the template argument may be a base class, and the correct proxies will still be selected for objects of different subclasses.

        Parameters
        ----------
        name : string
            the name of the new node to create
        object : T *
            a pointer to the object to serialize

        Returns
        -------
        SerializationNode
            a reference to the newly created node
        """
        return _openmm.SerializationNode_createChildNode(self, name)
    __swig_destroy__ = _openmm.delete_SerializationNode

# Register SerializationNode in _openmm:
_openmm.SerializationNode_swigregister(SerializationNode)

class SerializationProxy(object):
    r"""
    A SerializationProxy is an object that knows how to serialize and deserialize objects of a particular type. This is an abstract class. Subclasses implement the logic for serializing particular types of logic.

    A global registry maintains the list of what SerializationProxy to use for each type of object. Call registerProxy() to register the proxy for a particular type. This is typically done at application startup or by a dynamic library's initialization code.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_SerializationProxy

    @staticmethod
    def registerProxy(type, proxy):
        r"""
        registerProxy(type, proxy)
        Register a SerializationProxy to be used for objects of a particular type.

        Parameters
        ----------
        type : type_info
            the type_info for the object type
        proxy : SerializationProxy *
            the proxy to use for objects of the specified type
        """
        return _openmm.SerializationProxy_registerProxy(type, proxy)

    @staticmethod
    def getProxy(*args):
        r"""
        getProxy(typeName) -> SerializationProxy
        getProxy(type) -> SerializationProxy
        Get the SerializationProxy to use for objects of a particular type, specified by type_info.

        Parameters
        ----------
        type : type_info
            the type_info of the object type to get a proxy for
        """
        return _openmm.SerializationProxy_getProxy(*args)

    def getTypeName(self):
        r"""
        getTypeName(self) -> std::string const &
        Get the name of the object type this proxy manipulates, as passed to the constructor.
        """
        return _openmm.SerializationProxy_getTypeName(self)

    def serialize(self, object, node):
        r"""
        serialize(self, object, node)
        Subclasses implement this method to record information about an object being serialized.

        Parameters
        ----------
        object : void *
            a pointer to the object being serialized
        node : SerializationNode
            all data to be serialized should be stored into this node, either directly as properties or indirectly by adding child nodes to it
        """
        return _openmm.SerializationProxy_serialize(self, object, node)

    def deserialize(self, node):
        r"""
        deserialize(self, node) -> void *
        Reconstruct an object from its serialized data.

        Parameters
        ----------
        node : SerializationNode
            a SerializationNode containing the object's description

        Returns
        -------
        void *
            a pointer to a new object created from the data. The caller assumes ownership of the object.
        """
        return _openmm.SerializationProxy_deserialize(self, node)

# Register SerializationProxy in _openmm:
_openmm.SerializationProxy_swigregister(SerializationProxy)

def SerializationProxy_registerProxy(type, proxy):
    r"""
    SerializationProxy_registerProxy(type, proxy)
    Register a SerializationProxy to be used for objects of a particular type.

    Parameters
    ----------
    type : type_info
        the type_info for the object type
    proxy : SerializationProxy *
        the proxy to use for objects of the specified type
    """
    return _openmm.SerializationProxy_registerProxy(type, proxy)

def SerializationProxy_getProxy(*args):
    r"""
    SerializationProxy_getProxy(typeName) -> SerializationProxy
    SerializationProxy_getProxy(type) -> SerializationProxy
    Get the SerializationProxy to use for objects of a particular type, specified by type_info.

    Parameters
    ----------
    type : type_info
        the type_info of the object type to get a proxy for
    """
    return _openmm.SerializationProxy_getProxy(*args)

class State(object):
    r"""
    A State object records a snapshot of the current state of a simulation at a point in time. You create it by calling getState() on a Context.

    When a State is created, you specify what information should be stored in it. This saves time and memory by only copying in the information that you actually want. This is especially important for forces and energies, since they may need to be calculated. If you query a State object for a piece of information which is not available (because it was not requested when the State was created), it will throw an exception.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    Positions = _openmm.State_Positions
    
    Velocities = _openmm.State_Velocities
    
    Forces = _openmm.State_Forces
    
    Energy = _openmm.State_Energy
    
    Parameters = _openmm.State_Parameters
    
    ParameterDerivatives = _openmm.State_ParameterDerivatives
    
    IntegratorParameters = _openmm.State_IntegratorParameters
    

    def getTime(self):
        r"""
        getTime(self) -> double
        Get the time for which this State was created.
        """
        val = _openmm.State_getTime(self)

        val=unit.Quantity(val, unit.picosecond)


        return val


    def getKineticEnergy(self):
        r"""
        getKineticEnergy(self) -> double
        Get the total kinetic energy of the system. If this State does not contain energies, this will throw an exception.

        Note that this may be different from simply mv/2 summed over all particles. For example, a leapfrog integrator will store velocities offset by half a step, so they must be adjusted before computing the kinetic energy. This routine returns the kinetic energy at the current time, computed in a way that is appropriate for whatever Integrator is being used.
        """
        val = _openmm.State_getKineticEnergy(self)

        val=unit.Quantity(val, unit.kilojoules_per_mole)


        return val


    def getPotentialEnergy(self):
        r"""
        getPotentialEnergy(self) -> double
        Get the total potential energy of the system. If this State does not contain energies, this will throw an exception.
        """
        val = _openmm.State_getPotentialEnergy(self)

        val=unit.Quantity(val, unit.kilojoules_per_mole)


        return val


    def getPeriodicBoxVectors(self):
        r"""
        getPeriodicBoxVectors(self)
        Get the vectors defining the axes of the periodic box (measured in nm).

        Returns
        -------
        a : Vec3
            the vector defining the first edge of the periodic box
        b : Vec3
            the vector defining the second edge of the periodic box
        c : Vec3
            the vector defining the third edge of the periodic box
        """
        val = _openmm.State_getPeriodicBoxVectors(self)

        val=unit.Quantity(val, unit.nanometers)


        return val


    def getPeriodicBoxVolume(self):
        r"""
        getPeriodicBoxVolume(self) -> double
        Get the volume of the periodic box (measured in nm^3).
        """
        val = _openmm.State_getPeriodicBoxVolume(self)

        val=unit.Quantity(val, unit.nanometers**3)


        return val


    def getParameters(self):
        r"""
        getParameters(self) -> mapstringdouble
        Get a map containing the values of all parameters. If this State does not contain parameters, this will throw an exception.
        """
        return _openmm.State_getParameters(self)

    def getEnergyParameterDerivatives(self):
        r"""
        getEnergyParameterDerivatives(self) -> mapstringdouble
        Get a map containing derivatives of the potential energy with respect to context parameters. In most cases derivatives are only calculated if the corresponding Force objects have been specifically told to compute them. Otherwise, the values in the map will be zero. Likewise, if multiple Forces depend on the same parameter but only some have been told to compute derivatives with respect to it, the returned value will include only the contributions from the Forces that were told to compute it.

        If this State does not contain parameter derivatives, this will throw an exception.
        """
        return _openmm.State_getEnergyParameterDerivatives(self)

    def getDataTypes(self):
        r"""
        getDataTypes(self) -> int
        Get which data types are stored in this State. The return value is a sum of DataType flags.
        """
        return _openmm.State_getDataTypes(self)

    def __getstate__(self):
        serializationString = XmlSerializer.serialize(self)
        return serializationString

    def __setstate__(self, serializationString):
        system = XmlSerializer.deserialize(serializationString)
        self.this = system.this

    def __deepcopy__(self, memo):
        return self.__copy__()

    def getPeriodicBoxVectors(self, asNumpy=False):
        """Get the vectors defining the axes of the periodic box."""
        vectors = _openmm.State_getPeriodicBoxVectors(self)
        if asNumpy:
            vectors = numpy.array(vectors)
        return vectors*unit.nanometers

    def getPositions(self, asNumpy=False):
        """Get the position of each particle with units.
           Raises an exception if positions where not requested in
           the context.getState() call.
           Returns a list of Vec3s, unless asNumpy is True, in
           which  case a Numpy array of arrays will be returned.
           """
        if asNumpy:
            if '_positionsNumpy' not in dir(self):
                self._positionsNumpy = numpy.empty([self._getNumParticles(), 3], numpy.float64)
                self._getVectorAsNumpy(State.Positions, self._positionsNumpy)
                self._positionsNumpy = self._positionsNumpy*unit.nanometers
            return self._positionsNumpy
        if '_positions' not in dir(self):
            self._positions = self._getVectorAsVec3(State.Positions)*unit.nanometers
        return self._positions

    def getVelocities(self, asNumpy=False):
        """Get the velocity of each particle with units.
           Raises an exception if velocities where not requested in
           the context.getState() call.
           Returns a list of Vec3s if asNumpy is False, or a Numpy
           array if asNumpy is True.
           """
        if asNumpy:
            if '_velocitiesNumpy' not in dir(self):
                self._velocitiesNumpy = numpy.empty([self._getNumParticles(), 3], numpy.float64)
                self._getVectorAsNumpy(State.Velocities, self._velocitiesNumpy)
                self._velocitiesNumpy = self._velocitiesNumpy*unit.nanometers/unit.picosecond
            return self._velocitiesNumpy
        if '_velocities' not in dir(self):
            self._velocities = self._getVectorAsVec3(State.Velocities)*unit.nanometers/unit.picosecond
        return self._velocities

    def getForces(self, asNumpy=False):
        """Get the force acting on each particle with units.
           Raises an exception if forces where not requested in
           the context.getState() call.
           Returns a list of Vec3s if asNumpy is False, or a Numpy
           array if asNumpy is True.
           """
        if asNumpy:
            if '_forcesNumpy' not in dir(self):
                self._forcesNumpy = numpy.empty([self._getNumParticles(), 3], numpy.float64)
                self._getVectorAsNumpy(State.Forces, self._forcesNumpy)
                self._forcesNumpy = self._forcesNumpy*unit.kilojoules_per_mole/unit.nanometer
            return self._forcesNumpy
        if '_forces' not in dir(self):
            self._forces = self._getVectorAsVec3(State.Forces)*unit.kilojoules_per_mole/unit.nanometer
        return self._forces


    def _getNumParticles(self):
        r"""_getNumParticles(self) -> int"""
        return _openmm.State__getNumParticles(self)

    def _getVectorAsVec3(self, type):
        r"""_getVectorAsVec3(self, type) -> PyObject *"""
        return _openmm.State__getVectorAsVec3(self, type)

    def _getVectorAsNumpy(self, type, output):
        r"""_getVectorAsNumpy(self, type, output)"""
        return _openmm.State__getVectorAsNumpy(self, type, output)

    def __copy__(self):
        r"""__copy__(self) -> State"""
        return _openmm.State___copy__(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> State
        __init__(self, other) -> State
        Construct an empty State containing no data. This exists so State objects can be used in STL containers.
        """
        _openmm.State_swiginit(self, _openmm.new_State(*args))
    __swig_destroy__ = _openmm.delete_State

# Register State in _openmm:
_openmm.State_swigregister(State)

class System(object):
    r"""
    This class represents a molecular system. The definition of a System involves four elements:




    The particles and constraints are defined directly by the System object, while forces are defined by objects that extend the Force class. After creating a System, call addParticle() once for each particle, addConstraint() for each constraint, and addForce() for each Force.

    In addition, particles may be designated as "virtual sites". These are particles whose positions are computed automatically based on the positions of other particles. To define a virtual site, call setVirtualSite(), passing in a VirtualSite object that defines the rules for computing its position.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_System

    def getNumParticles(self):
        r"""
        getNumParticles(self) -> int
        Get the number of particles in this System.
        """
        return _openmm.System_getNumParticles(self)

    def addParticle(self, mass):
        r"""
        addParticle(self, mass) -> int
        Add a particle to the System. If the mass is 0, Integrators will ignore the particle and not modify its position or velocity. This is most often used for virtual sites, but can also be used as a way to prevent a particle from moving.

        Parameters
        ----------
        mass : double
            the mass of the particle (in atomic mass units)

        Returns
        -------
        int
            the index of the particle that was added
        """
        return _openmm.System_addParticle(self, mass)

    def getParticleMass(self, index):
        r"""
        getParticleMass(self, index) -> double
        Get the mass (in atomic mass units) of a particle. If the mass is 0, Integrators will ignore the particle and not modify its position or velocity. This is most often used for virtual sites, but can also be used as a way to prevent a particle from moving.

        Parameters
        ----------
        index : int
            the index of the particle for which to get the mass
        """
        val = _openmm.System_getParticleMass(self, index)

        val=unit.Quantity(val, unit.amu)


        return val


    def setParticleMass(self, index, mass):
        r"""
        setParticleMass(self, index, mass)
        Set the mass (in atomic mass units) of a particle. If the mass is 0, Integrators will ignore the particle and not modify its position or velocity. This is most often used for virtual sites, but can also be used as a way to prevent a particle from moving.

        Parameters
        ----------
        index : int
            the index of the particle for which to set the mass
        mass : double
            the mass of the particle
        """
        return _openmm.System_setParticleMass(self, index, mass)

    def setVirtualSite(self, index, virtualSite):
        r"""
        setVirtualSite(self, index, virtualSite)
        Set a particle to be a virtual site. The VirtualSite object should have been created on the heap with the "new" operator. The System takes over ownership of it, and deletes it when the System itself is deleted.

        Parameters
        ----------
        index : int
            the index of the particle that should be treated as a virtual site
        virtualSite : VirtualSite *
            a pointer to the VirtualSite object describing it
        """

        if not virtualSite.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.System_setVirtualSite(self, index, virtualSite)

        virtualSite.thisown=0


        return val


    def isVirtualSite(self, index):
        r"""
        isVirtualSite(self, index) -> bool
        Get whether a particle is a VirtualSite.

        Parameters
        ----------
        index : int
            the index of the particle to check
        """
        return _openmm.System_isVirtualSite(self, index)

    def getVirtualSite(self, index):
        r"""
        getVirtualSite(self, index) -> VirtualSite
        Get VirtualSite object for a particle. If the particle is not a virtual site, this throws an exception.

        Parameters
        ----------
        index : int
            the index of the particle to get
        """
        return _openmm.System_getVirtualSite(self, index)

    def getNumConstraints(self):
        r"""
        getNumConstraints(self) -> int
        Get the number of distance constraints in this System.
        """
        return _openmm.System_getNumConstraints(self)

    def addConstraint(self, particle1, particle2, distance):
        r"""
        addConstraint(self, particle1, particle2, distance) -> int
        Add a constraint to the System. Particles whose mass is 0 cannot participate in constraints.

        Parameters
        ----------
        particle1 : int
            the index of the first particle involved in the constraint
        particle2 : int
            the index of the second particle involved in the constraint
        distance : double
            the required distance between the two particles, measured in nm

        Returns
        -------
        int
            the index of the constraint that was added
        """
        return _openmm.System_addConstraint(self, particle1, particle2, distance)

    def getConstraintParameters(self, index):
        r"""
        getConstraintParameters(self, index)
        Get the parameters defining a distance constraint.

        Parameters
        ----------
        index : int
            the index of the constraint for which to get parameters

        Returns
        -------
        particle1 : int
            the index of the first particle involved in the constraint
        particle2 : int
            the index of the second particle involved in the constraint
        distance : double
            the required distance between the two particles, measured in nm
        """
        val = _openmm.System_getConstraintParameters(self, index)

        val[2]=unit.Quantity(val[2], unit.nanometer)


        return val


    def setConstraintParameters(self, index, particle1, particle2, distance):
        r"""
        setConstraintParameters(self, index, particle1, particle2, distance)
        Set the parameters defining a distance constraint. Particles whose mass is 0 cannot participate in constraints.

        Parameters
        ----------
        index : int
            the index of the constraint for which to set parameters
        particle1 : int
            the index of the first particle involved in the constraint
        particle2 : int
            the index of the second particle involved in the constraint
        distance : double
            the required distance between the two particles, measured in nm
        """
        return _openmm.System_setConstraintParameters(self, index, particle1, particle2, distance)

    def removeConstraint(self, index):
        r"""
        removeConstraint(self, index)
        Remove a constraint from the System.

        Parameters
        ----------
        index : int
            the index of the constraint to remove
        """
        return _openmm.System_removeConstraint(self, index)

    def addForce(self, force):
        r"""
        addForce(self, force) -> int
        Add a Force to the System. The Force should have been created on the heap with the "new" operator. The System takes over ownership of it, and deletes the Force when the System itself is deleted.

        Parameters
        ----------
        force : Force *
            a pointer to the Force object to be added

        Returns
        -------
        int
            the index within the System of the Force that was added
        """

        if not force.thisown:
            s = ("the %s object does not own its corresponding OpenMM object"
                 % self.__class__.__name__)
            raise Exception(s)


        val = _openmm.System_addForce(self, force)

        force.thisown=0


        return val


    def getNumForces(self):
        r"""
        getNumForces(self) -> int
        Get the number of Force objects that have been added to the System.
        """
        return _openmm.System_getNumForces(self)

    def getForce(self, *args):
        r"""
        getForce(self, index) -> Force
        getForce(self, index) -> Force
        Get a writable reference to one of the Forces in this System.

        Parameters
        ----------
        index : int
            the index of the Force to get
        """
        return _openmm.System_getForce(self, *args)

    def removeForce(self, index):
        r"""
        removeForce(self, index)
        Remove a Force from the System. The memory associated with the removed Force object is deleted.

        Parameters
        ----------
        index : int
            the index of the Force to remove
        """
        return _openmm.System_removeForce(self, index)

    def getDefaultPeriodicBoxVectors(self):
        r"""
        getDefaultPeriodicBoxVectors(self)
        Get the default values of the vectors defining the axes of the periodic box (measured in nm). Any newly created Context will have its box vectors set to these. They will affect any Force added to the System that uses periodic boundary conditions.

        Returns
        -------
        a : Vec3
            the vector defining the first edge of the periodic box
        b : Vec3
            the vector defining the second edge of the periodic box
        c : Vec3
            the vector defining the third edge of the periodic box
        """
        val = _openmm.System_getDefaultPeriodicBoxVectors(self)

        val[0]=unit.Quantity(val[0], unit.nanometer)
        val[1]=unit.Quantity(val[1], unit.nanometer)
        val[2]=unit.Quantity(val[2], unit.nanometer)


        return val


    def setDefaultPeriodicBoxVectors(self, a, b, c):
        r"""
        setDefaultPeriodicBoxVectors(self, a, b, c)
        Set the default values of the vectors defining the axes of the periodic box (measured in nm). Any newly created Context will have its box vectors set to these. They will affect any Force added to the System that uses periodic boundary conditions.

        Triclinic boxes are supported, but the vectors must satisfy certain requirements. In particular, a must point in the x direction, b must point "mostly" in the y direction, and c must point "mostly" in the z direction. See the documentation for details.

        Parameters
        ----------
        a : Vec3
            the vector defining the first edge of the periodic box
        b : Vec3
            the vector defining the second edge of the periodic box
        c : Vec3
            the vector defining the third edge of the periodic box
        """
        return _openmm.System_setDefaultPeriodicBoxVectors(self, a, b, c)

    def usesPeriodicBoundaryConditions(self):
        r"""
        usesPeriodicBoundaryConditions(self) -> bool
        Returns whether or not any forces in this System use periodic boundaries.

        If a force in this System does not implement usesPeriodicBoundaryConditions a OpenMM::OpenMMException is thrown

        Returns
        -------
        bool
            true if at least one force uses PBC and false otherwise
        """
        return _openmm.System_usesPeriodicBoundaryConditions(self)

    def __getstate__(self):
        serializationString = XmlSerializer.serializeSystem(self)
        return serializationString

    def __setstate__(self, serializationString):
        system = XmlSerializer.deserializeSystem(serializationString)
        self.this = system.this
    def __deepcopy__(self, memo):
        return self.__copy__()
    def getForces(self):
        """Get the list of Forces in this System"""
        return [self.getForce(i) for i in range(self.getNumForces())]


    def __copy__(self):
        r"""__copy__(self) -> System"""
        return _openmm.System___copy__(self)

    def __init__(self, *args):
        r"""
        __init__(self) -> System
        __init__(self, other) -> System
        Create a new System.
        """
        _openmm.System_swiginit(self, _openmm.new_System(*args))

# Register System in _openmm:
_openmm.System_swigregister(System)

class ThreeParticleAverageSite(VirtualSite):
    r"""This is a VirtualSite that computes the particle location as a weighted average of three other particle's locations. Assuming the weights add up to 1, this means the virtual site is in the plane of the three particles."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getWeight(self, particle):
        r"""
        getWeight(self, particle) -> double
        Get the weight factor used for a particle this virtual site depends on.

        Parameters
        ----------
        particle : int
            the particle to get (between 0 and getNumParticles())

        Returns
        -------
        double
            the weight factor used for that particle
        """
        return _openmm.ThreeParticleAverageSite_getWeight(self, particle)

    def __init__(self, *args):
        r"""
        __init__(self, particle1, particle2, particle3, weight1, weight2, weight3) -> ThreeParticleAverageSite
        __init__(self, other) -> ThreeParticleAverageSite
        Create a new ThreeParticleAverageSite virtual site. Normally the weights should add up to 1, although this is not strictly required.

        Parameters
        ----------
        particle1 : int
            the index of the first particle
        particle2 : int
            the index of the second particle
        particle3 : int
            the index of the third particle
        weight1 : double
            the weight factor (between 0 and 1) for the first particle
        weight2 : double
            the weight factor (between 0 and 1) for the second particle
        weight3 : double
            the weight factor (between 0 and 1) for the third particle
        """
        _openmm.ThreeParticleAverageSite_swiginit(self, _openmm.new_ThreeParticleAverageSite(*args))
    __swig_destroy__ = _openmm.delete_ThreeParticleAverageSite

# Register ThreeParticleAverageSite in _openmm:
_openmm.ThreeParticleAverageSite_swigregister(ThreeParticleAverageSite)

class TwoParticleAverageSite(VirtualSite):
    r"""This is a VirtualSite that computes the particle location as a weighted average of two other particle's locations. Assuming the weights add up to 1, this means the virtual site is on the line passing through the two particles."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getWeight(self, particle):
        r"""
        getWeight(self, particle) -> double
        Get the weight factor used for a particle this virtual site depends on.

        Parameters
        ----------
        particle : int
            the particle to get (between 0 and getNumParticles())

        Returns
        -------
        double
            the weight factor used for that particle
        """
        return _openmm.TwoParticleAverageSite_getWeight(self, particle)

    def __init__(self, *args):
        r"""
        __init__(self, particle1, particle2, weight1, weight2) -> TwoParticleAverageSite
        __init__(self, other) -> TwoParticleAverageSite
        Create a new TwoParticleAverageSite virtual site. Normally weight1 and weight2 should add up to 1, although this is not strictly required.

        Parameters
        ----------
        particle1 : int
            the index of the first particle
        particle2 : int
            the index of the second particle
        weight1 : double
            the weight factor (between 0 and 1) for the first particle
        weight2 : double
            the weight factor (between 0 and 1) for the second particle
        """
        _openmm.TwoParticleAverageSite_swiginit(self, _openmm.new_TwoParticleAverageSite(*args))
    __swig_destroy__ = _openmm.delete_TwoParticleAverageSite

# Register TwoParticleAverageSite in _openmm:
_openmm.TwoParticleAverageSite_swigregister(TwoParticleAverageSite)

class VariableLangevinIntegrator(Integrator):
    r"""
    This is an error controlled, variable time step Integrator that simulates a System using Langevin dynamics. It compares the result of the Langevin integrator to that of an explicit Euler integrator, takes the difference between the two as a measure of the integration error in each time step, and continuously adjusts the step size to keep the error below a specified tolerance. This both improves the stability of the integrator and allows it to take larger steps on average, while still maintaining comparable accuracy to a fixed step size integrator.

    It is best not to think of the error tolerance as having any absolute meaning. It is just an adjustable parameter that affects the step size and integration accuracy. You should try different values to find the largest one that produces a trajectory sufficiently accurate for your purposes. 0.001 is often a good starting point.

    You can optionally set a maximum step size it will ever use. This is useful to prevent it from taking excessively large steps in usual situations, such as when the system is right at a local energy minimum.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getTemperature(self):
        r"""
        getTemperature(self) -> double
        Get the temperature of the heat bath (in Kelvin).

        Returns
        -------
        double
            the temperature of the heat bath, measured in Kelvin
        """
        val = _openmm.VariableLangevinIntegrator_getTemperature(self)

        val=unit.Quantity(val, unit.kelvin)


        return val


    def setTemperature(self, temp):
        r"""
        setTemperature(self, temp)
        Set the temperature of the heat bath (in Kelvin).

        Parameters
        ----------
        temp : double
            the temperature of the heat bath, measured in Kelvin
        """
        return _openmm.VariableLangevinIntegrator_setTemperature(self, temp)

    def getFriction(self):
        r"""
        getFriction(self) -> double
        Get the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Returns
        -------
        double
            the friction coefficient, measured in 1/ps
        """
        val = _openmm.VariableLangevinIntegrator_getFriction(self)

        val=unit.Quantity(val, 1/unit.picosecond)


        return val


    def setFriction(self, coeff):
        r"""
        setFriction(self, coeff)
        Set the friction coefficient which determines how strongly the system is coupled to the heat bath (in inverse ps).

        Parameters
        ----------
        coeff : double
            the friction coefficient, measured in 1/ps
        """
        return _openmm.VariableLangevinIntegrator_setFriction(self, coeff)

    def getErrorTolerance(self):
        r"""
        getErrorTolerance(self) -> double
        Get the error tolerance.
        """
        return _openmm.VariableLangevinIntegrator_getErrorTolerance(self)

    def setErrorTolerance(self, tol):
        r"""
        setErrorTolerance(self, tol)
        Set the error tolerance.
        """
        return _openmm.VariableLangevinIntegrator_setErrorTolerance(self, tol)

    def getMaximumStepSize(self):
        r"""
        getMaximumStepSize(self) -> double
        Get the maximum step size the integrator will ever use, in ps. If this is 0 (the default), no limit will be applied to step sizes.
        """
        val = _openmm.VariableLangevinIntegrator_getMaximumStepSize(self)

        val=unit.Quantity(val, unit.picosecond)


        return val


    def setMaximumStepSize(self, size):
        r"""
        setMaximumStepSize(self, size)
        Set the maximum step size the integrator will ever use, in ps. If this is 0 (the default), no limit will be applied to step sizes.
        """
        return _openmm.VariableLangevinIntegrator_setMaximumStepSize(self, size)

    def getRandomNumberSeed(self):
        r"""
        getRandomNumberSeed(self) -> int
        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.VariableLangevinIntegrator_getRandomNumberSeed(self)

    def setRandomNumberSeed(self, seed):
        r"""
        setRandomNumberSeed(self, seed)
        Set the random number seed. The precise meaning of this parameter is undefined, and is left up to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations are run with different random number seeds, the sequence of random forces will be different. On the other hand, no guarantees are made about the behavior of simulations that use the same seed. In particular, Platforms are permitted to use non-deterministic algorithms which produce different results on successive runs, even if those runs were initialized identically.

        If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context is created from this Force. This is done to ensure that each Context receives unique random seeds without you needing to set them explicitly.
        """
        return _openmm.VariableLangevinIntegrator_setRandomNumberSeed(self, seed)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.VariableLangevinIntegrator_step(self, steps)

    def stepTo(self, time):
        r"""
        stepTo(self, time)
        Advance a simulation through time by taking a series of steps until a specified time is reached. When this method returns, the simulation time will exactly equal the time which was specified. If you call this method and specify a time that is earlier than the current time, it will return without doing anything.

        Parameters
        ----------
        time : double
            the time to which the simulation should be advanced
        """
        return _openmm.VariableLangevinIntegrator_stepTo(self, time)

    def __init__(self, *args):
        r"""
        __init__(self, temperature, frictionCoeff, errorTol) -> VariableLangevinIntegrator
        __init__(self, other) -> VariableLangevinIntegrator
        Create a VariableLangevinIntegrator.

        Parameters
        ----------
        temperature : double
            the temperature of the heat bath (in Kelvin)
        frictionCoeff : double
            the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
        errorTol : double
            the error tolerance
        """
        _openmm.VariableLangevinIntegrator_swiginit(self, _openmm.new_VariableLangevinIntegrator(*args))
    __swig_destroy__ = _openmm.delete_VariableLangevinIntegrator

# Register VariableLangevinIntegrator in _openmm:
_openmm.VariableLangevinIntegrator_swigregister(VariableLangevinIntegrator)

class VariableVerletIntegrator(Integrator):
    r"""
    This is an error controlled, variable time step Integrator that simulates a System using the leap-frog Verlet algorithm. It compares the result of the Verlet integrator to that of an explicit Euler integrator, takes the difference between the two as a measure of the integration error in each time step, and continuously adjusts the step size to keep the error below a specified tolerance. This both improves the stability of the integrator and allows it to take larger steps on average, while still maintaining comparable accuracy to a fixed step size integrator.

    It is best not to think of the error tolerance as having any absolute meaning. It is just an adjustable parameter that affects the step size and integration accuracy. You should try different values to find the largest one that produces a trajectory sufficiently accurate for your purposes. 0.001 is often a good starting point.

    Unlike a fixed step size Verlet integrator, variable step size Verlet is not symplectic. This means that at a given accuracy level, energy is not as precisely conserved over long time periods. This makes it most appropriate for constant temperate simulations. In constant energy simulations where precise energy conservation over long time periods is important, a fixed step size Verlet integrator may be more appropriate.

    You can optionally set a maximum step size it will ever use. This is useful to prevent it from taking excessively large steps in usual situations, such as when the system is right at a local energy minimum.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getErrorTolerance(self):
        r"""
        getErrorTolerance(self) -> double
        Get the error tolerance.
        """
        return _openmm.VariableVerletIntegrator_getErrorTolerance(self)

    def setErrorTolerance(self, tol):
        r"""
        setErrorTolerance(self, tol)
        Set the error tolerance.
        """
        return _openmm.VariableVerletIntegrator_setErrorTolerance(self, tol)

    def getMaximumStepSize(self):
        r"""
        getMaximumStepSize(self) -> double
        Get the maximum step size the integrator will ever use, in ps. If this is 0 (the default), no limit will be applied to step sizes.
        """
        val = _openmm.VariableVerletIntegrator_getMaximumStepSize(self)

        val=unit.Quantity(val, unit.picosecond)


        return val


    def setMaximumStepSize(self, size):
        r"""
        setMaximumStepSize(self, size)
        Set the maximum step size the integrator will ever use, in ps. If this is 0 (the default), no limit will be applied to step sizes.
        """
        return _openmm.VariableVerletIntegrator_setMaximumStepSize(self, size)

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.VariableVerletIntegrator_step(self, steps)

    def stepTo(self, time):
        r"""
        stepTo(self, time)
        Advance a simulation through time by taking a series of steps until a specified time is reached. When this method returns, the simulation time will exactly equal the time which was specified. If you call this method and specify a time that is earlier than the current time, it will return without doing anything.

        Parameters
        ----------
        time : double
            the time to which the simulation should be advanced
        """
        return _openmm.VariableVerletIntegrator_stepTo(self, time)

    def __init__(self, *args):
        r"""
        __init__(self, errorTol) -> VariableVerletIntegrator
        __init__(self, other) -> VariableVerletIntegrator
        Create a VariableVerletIntegrator.

        Parameters
        ----------
        errorTol : double
            the error tolerance
        """
        _openmm.VariableVerletIntegrator_swiginit(self, _openmm.new_VariableVerletIntegrator(*args))
    __swig_destroy__ = _openmm.delete_VariableVerletIntegrator

# Register VariableVerletIntegrator in _openmm:
_openmm.VariableVerletIntegrator_swigregister(VariableVerletIntegrator)

class VerletIntegrator(Integrator):
    r"""This is an Integrator which simulates a System using the leap-frog Verlet algorithm."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def step(self, steps):
        r"""
        step(self, steps)
        Advance a simulation through time by taking a series of time steps.

        Parameters
        ----------
        steps : int
            the number of time steps to take
        """
        return _openmm.VerletIntegrator_step(self, steps)

    def __init__(self, *args):
        r"""
        __init__(self, stepSize) -> VerletIntegrator
        __init__(self, other) -> VerletIntegrator
        Create a VerletIntegrator.

        Parameters
        ----------
        stepSize : double
            the step size with which to integrate the system (in picoseconds)
        """
        _openmm.VerletIntegrator_swiginit(self, _openmm.new_VerletIntegrator(*args))
    __swig_destroy__ = _openmm.delete_VerletIntegrator

# Register VerletIntegrator in _openmm:
_openmm.VerletIntegrator_swigregister(VerletIntegrator)

class XmlSerializer(object):
    r"""XmlSerializer is used for serializing objects as XML, and for reconstructing them again."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    @staticmethod
    def serializeSystem(object):
        r"""
        serializeSystem(object) -> std::string
        This method exists only for backward compatibility.
        @deprecated Use serialize() instead.
        """
        return _openmm.XmlSerializer_serializeSystem(object)

    @staticmethod
    def deserializeSystem(inputString):
        r"""
        deserializeSystem(inputString) -> System
        This method exists only for backward compatibility.
        @deprecated Use deserialize() instead.
        """
        return _openmm.XmlSerializer_deserializeSystem(inputString)

    @staticmethod
    def _serializeForce(object):
        r"""_serializeForce(object) -> std::string"""
        return _openmm.XmlSerializer__serializeForce(object)

    @staticmethod
    def _deserializeForce(inputString):
        r"""_deserializeForce(inputString) -> Force"""
        return _openmm.XmlSerializer__deserializeForce(inputString)

    @staticmethod
    def _serializeIntegrator(object):
        r"""_serializeIntegrator(object) -> std::string"""
        return _openmm.XmlSerializer__serializeIntegrator(object)

    @staticmethod
    def _deserializeIntegrator(inputString):
        r"""_deserializeIntegrator(inputString) -> Integrator"""
        return _openmm.XmlSerializer__deserializeIntegrator(inputString)

    @staticmethod
    def _serializeTabulatedFunction(object):
        r"""_serializeTabulatedFunction(object) -> std::string"""
        return _openmm.XmlSerializer__serializeTabulatedFunction(object)

    @staticmethod
    def _deserializeTabulatedFunction(inputString):
        r"""_deserializeTabulatedFunction(inputString) -> TabulatedFunction"""
        return _openmm.XmlSerializer__deserializeTabulatedFunction(inputString)

    @staticmethod
    def _serializeState(object):
        r"""_serializeState(object) -> std::string"""
        return _openmm.XmlSerializer__serializeState(object)

    @staticmethod
    def _deserializeState(inputString):
        r"""_deserializeState(inputString) -> State"""
        return _openmm.XmlSerializer__deserializeState(inputString)

    @staticmethod
    def serialize(object):
      """Serialize an object as XML."""
      if isinstance(object, System):
        return XmlSerializer.serializeSystem(object)
      elif isinstance(object, Force):
        return XmlSerializer._serializeForce(object)
      elif isinstance(object, Integrator):
        return XmlSerializer._serializeIntegrator(object)
      elif isinstance(object, State):
        return XmlSerializer._serializeState(object)
      elif isinstance(object, TabulatedFunction):
        return XmlSerializer._serializeTabulatedFunction(object)
      raise ValueError("Unsupported object type")

    @staticmethod
    def deserialize(inputString):
      """Reconstruct an object that has been serialized as XML."""
      import re
      match = re.search("<([^?]\S*)", inputString)
      if match is None:
        raise ValueError("Invalid input string")
      type = match.groups()[0]
      if type == "System":
        return XmlSerializer.deserializeSystem(inputString)
      if type == "Force":
        return XmlSerializer._deserializeForce(inputString)
      if type == "Integrator":
        return XmlSerializer._deserializeIntegrator(inputString)
      if type == "State":
        return XmlSerializer._deserializeState(inputString)
      if type == "TabulatedFunction":
        return XmlSerializer._deserializeTabulatedFunction(inputString)
      raise ValueError("Unsupported object type")

    __swig_destroy__ = _openmm.delete_XmlSerializer

# Register XmlSerializer in _openmm:
_openmm.XmlSerializer_swigregister(XmlSerializer)

def XmlSerializer_serializeSystem(object):
    r"""
    XmlSerializer_serializeSystem(object) -> std::string
    This method exists only for backward compatibility.
    @deprecated Use serialize() instead.
    """
    return _openmm.XmlSerializer_serializeSystem(object)

def XmlSerializer_deserializeSystem(inputString):
    r"""
    XmlSerializer_deserializeSystem(inputString) -> System
    This method exists only for backward compatibility.
    @deprecated Use deserialize() instead.
    """
    return _openmm.XmlSerializer_deserializeSystem(inputString)

def XmlSerializer__serializeForce(object):
    r"""XmlSerializer__serializeForce(object) -> std::string"""
    return _openmm.XmlSerializer__serializeForce(object)

def XmlSerializer__deserializeForce(inputString):
    r"""XmlSerializer__deserializeForce(inputString) -> Force"""
    return _openmm.XmlSerializer__deserializeForce(inputString)

def XmlSerializer__serializeIntegrator(object):
    r"""XmlSerializer__serializeIntegrator(object) -> std::string"""
    return _openmm.XmlSerializer__serializeIntegrator(object)

def XmlSerializer__deserializeIntegrator(inputString):
    r"""XmlSerializer__deserializeIntegrator(inputString) -> Integrator"""
    return _openmm.XmlSerializer__deserializeIntegrator(inputString)

def XmlSerializer__serializeTabulatedFunction(object):
    r"""XmlSerializer__serializeTabulatedFunction(object) -> std::string"""
    return _openmm.XmlSerializer__serializeTabulatedFunction(object)

def XmlSerializer__deserializeTabulatedFunction(inputString):
    r"""XmlSerializer__deserializeTabulatedFunction(inputString) -> TabulatedFunction"""
    return _openmm.XmlSerializer__deserializeTabulatedFunction(inputString)

def XmlSerializer__serializeState(object):
    r"""XmlSerializer__serializeState(object) -> std::string"""
    return _openmm.XmlSerializer__serializeState(object)

def XmlSerializer__deserializeState(inputString):
    r"""XmlSerializer__deserializeState(inputString) -> State"""
    return _openmm.XmlSerializer__deserializeState(inputString)


  # when we import * from the python module, we only want to import the
  # actual classes, and not the swigregistration methods, which have already
  # been called, and are now unneeded by the user code, and only pollute the
  # namespace
__all__ = [k for k in locals().keys() if not (k.endswith('_swigregister') or k.startswith('_'))]



