# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.7
#
# 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
if version_info >= (2, 6, 0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_openmm', [dirname(__file__)])
        except ImportError:
            import _openmm
            return _openmm
        if fp is not None:
            try:
                _mod = imp.load_module('_openmm', fp, pathname, description)
            finally:
                fp.close()
            return _mod
    _openmm = swig_import_helper()
    del swig_import_helper
else:
    import _openmm
del version_info
try:
    _swig_property = property
except NameError:
    pass  # Python < 2.2 doesn't have 'property'.


def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
    if (name == "thisown"):
        return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name, None)
    if method:
        return method(self, value)
    if (not static):
        if _newclass:
            object.__setattr__(self, name, value)
        else:
            self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr_nondynamic(self, class_type, name, static=1):
    if (name == "thisown"):
        return self.this.own()
    method = class_type.__swig_getmethods__.get(name, None)
    if method:
        return method(self)
    if (not static):
        return object.__getattr__(self, name)
    else:
        raise AttributeError(name)

def _swig_getattr(self, class_type, name):
    return _swig_getattr_nondynamic(self, class_type, name, 0)


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

try:
    _object = object
    _newclass = 1
except AttributeError:
    class _object:
        pass
    _newclass = 0


class ios_base(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, ios_base, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, ios_base, name)

    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)
    __swig_getmethods__["sync_with_stdio"] = lambda x: _openmm.ios_base_sync_with_stdio
    if _newclass:
        sync_with_stdio = staticmethod(_openmm.ios_base_sync_with_stdio)

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

    def getloc(self):
        return _openmm.ios_base_getloc(self)
    __swig_getmethods__["xalloc"] = lambda x: _openmm.ios_base_xalloc
    if _newclass:
        xalloc = staticmethod(_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
    __del__ = lambda self: None
ios_base_swigregister = _openmm.ios_base_swigregister
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)
ios_base_sync_with_stdio = _openmm.ios_base_sync_with_stdio

def ios_base_xalloc():
    return _openmm.ios_base_xalloc()
ios_base_xalloc = _openmm.ios_base_xalloc

class ios(ios_base):
    __swig_setmethods__ = {}
    for _s in [ios_base]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, ios, name, value)
    __swig_getmethods__ = {}
    for _s in [ios_base]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, ios, name)
    __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):
        this = _openmm.new_ios(__sb)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_ios
    __del__ = lambda self: None

    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)
ios_swigregister = _openmm.ios_swigregister
ios_swigregister(ios)

class ostream(ios):
    __swig_setmethods__ = {}
    for _s in [ios]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, ostream, name, value)
    __swig_getmethods__ = {}
    for _s in [ios]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, ostream, name)
    __repr__ = _swig_repr

    def __init__(self, __sb):
        this = _openmm.new_ostream(__sb)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_ostream
    __del__ = lambda self: None

    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)
ostream_swigregister = _openmm.ostream_swigregister
ostream_swigregister(ostream)
cin = cvar.cin
cout = cvar.cout
cerr = cvar.cerr
clog = cvar.clog

class istream(ios):
    __swig_setmethods__ = {}
    for _s in [ios]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, istream, name, value)
    __swig_getmethods__ = {}
    for _s in [ios]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, istream, name)
    __repr__ = _swig_repr

    def __init__(self, __sb):
        this = _openmm.new_istream(__sb)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_istream
    __del__ = lambda self: None

    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)
istream_swigregister = _openmm.istream_swigregister
istream_swigregister(istream)

class iostream(istream, ostream):
    __swig_setmethods__ = {}
    for _s in [istream, ostream]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, iostream, name, value)
    __swig_getmethods__ = {}
    for _s in [istream, ostream]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, iostream, name)
    __repr__ = _swig_repr

    def __init__(self, __sb):
        this = _openmm.new_iostream(__sb)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_iostream
    __del__ = lambda self: None
iostream_swigregister = _openmm.iostream_swigregister
iostream_swigregister(iostream)


_openmm.endl_cb_ptr_swigconstant(_openmm)
endl_cb_ptr = _openmm.endl_cb_ptr

def endl(arg1):
    return _openmm.endl(arg1)
endl = _openmm.endl

_openmm.ends_cb_ptr_swigconstant(_openmm)
ends_cb_ptr = _openmm.ends_cb_ptr

def ends(arg1):
    return _openmm.ends(arg1)
ends = _openmm.ends

_openmm.flush_cb_ptr_swigconstant(_openmm)
flush_cb_ptr = _openmm.flush_cb_ptr

def flush(arg1):
    return _openmm.flush(arg1)
flush = _openmm.flush
class SwigPyIterator(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SwigPyIterator, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SwigPyIterator, name)

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

    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
SwigPyIterator_swigregister = _openmm.SwigPyIterator_swigregister
SwigPyIterator_swigregister(SwigPyIterator)

class pairii(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, pairii, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, pairii, name)
    __repr__ = _swig_repr

    def __init__(self, *args):
        this = _openmm.new_pairii(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_setmethods__["first"] = _openmm.pairii_first_set
    __swig_getmethods__["first"] = _openmm.pairii_first_get
    if _newclass:
        first = _swig_property(_openmm.pairii_first_get, _openmm.pairii_first_set)
    __swig_setmethods__["second"] = _openmm.pairii_second_set
    __swig_getmethods__["second"] = _openmm.pairii_second_get
    if _newclass:
        second = _swig_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
    __del__ = lambda self: None
pairii_swigregister = _openmm.pairii_swigregister
pairii_swigregister(pairii)

class vectord(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectord, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectord, name)
    __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 pop(self):
        return _openmm.vectord_pop(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 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 clear(self):
        return _openmm.vectord_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectord_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectord(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectord_swigregister = _openmm.vectord_swigregister
vectord_swigregister(vectord)

class vectorddd(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectorddd, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectorddd, name)
    __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 pop(self):
        return _openmm.vectorddd_pop(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 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 clear(self):
        return _openmm.vectorddd_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectorddd_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectorddd(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectorddd_swigregister = _openmm.vectorddd_swigregister
vectorddd_swigregister(vectorddd)

class vectori(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectori, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectori, name)
    __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 pop(self):
        return _openmm.vectori_pop(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 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 clear(self):
        return _openmm.vectori_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectori_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectori(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectori_swigregister = _openmm.vectori_swigregister
vectori_swigregister(vectori)

class vectorii(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectorii, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectorii, name)
    __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 pop(self):
        return _openmm.vectorii_pop(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 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 clear(self):
        return _openmm.vectorii_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectorii_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectorii(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectorii_swigregister = _openmm.vectorii_swigregister
vectorii_swigregister(vectorii)

class vectorpairii(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectorpairii, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectorpairii, name)
    __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 pop(self):
        return _openmm.vectorpairii_pop(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 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 clear(self):
        return _openmm.vectorpairii_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectorpairii_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectorpairii(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectorpairii_swigregister = _openmm.vectorpairii_swigregister
vectorpairii_swigregister(vectorpairii)

class vectorstring(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, vectorstring, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, vectorstring, name)
    __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 pop(self):
        return _openmm.vectorstring_pop(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 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 clear(self):
        return _openmm.vectorstring_clear(self)

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

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

    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 pop_back(self):
        return _openmm.vectorstring_pop_back(self)

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

    def __init__(self, *args):
        this = _openmm.new_vectorstring(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
vectorstring_swigregister = _openmm.vectorstring_swigregister
vectorstring_swigregister(vectorstring)

class mapstringstring(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, mapstringstring, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, mapstringstring, name)
    __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):
        this = _openmm.new_mapstringstring(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

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

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

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

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

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

    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 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
    __del__ = lambda self: None
mapstringstring_swigregister = _openmm.mapstringstring_swigregister
mapstringstring_swigregister(mapstringstring)

class mapstringdouble(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, mapstringdouble, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, mapstringdouble, name)
    __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):
        this = _openmm.new_mapstringdouble(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

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

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

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

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

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

    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 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
    __del__ = lambda self: None
mapstringdouble_swigregister = _openmm.mapstringdouble_swigregister
mapstringdouble_swigregister(mapstringdouble)

class mapii(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, mapii, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, mapii, name)
    __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):
        this = _openmm.new_mapii(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

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

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

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

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

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

    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 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
    __del__ = lambda self: None
mapii_swigregister = _openmm.mapii_swigregister
mapii_swigregister(mapii)

class seti(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, seti, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, seti, name)
    __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):
        this = _openmm.new_seti(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

    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
    __del__ = lambda self: None
seti_swigregister = _openmm.seti_swigregister
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 State(_object):
    """
     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
     return None.

     In general return values are Python Units
     (https://simtk.org/home/python_units).
     Among other things Python Units provides a
     container class, Quantity, which holds a
     value and a representation of the value's
     unit.  Values can be integers, floats,
     lists, numarrays, etc.  Quantity objects
     can be used in arithmetic operation just
     like number, except they also keep track
     of units.   To extract the value from a
     quantity, us the value_in_unit() method.
     For example, to extract the value from a
     length quantity, in units of nanometers,
     do the following:
     myLengthQuantity.value_in_unit(unit.nanometer)

"""
    def __init__(self,
                 simTime=None,
                 energy=None,
                 coordList=None,
                 velList=None,
                 forceList=None,
                 periodicBoxVectorsList=None,
                 paramMap=None):
        self._simTime=simTime
        self._periodicBoxVectorsList=periodicBoxVectorsList
        self._periodicBoxVectorsListNumpy=None
        if energy:
            self._eK0=energy[0]
            self._eP0=energy[1]
        else:
            self._eK0=None
            self._eP0=None
        self._coordList=coordList
        self._coordListNumpy=None
        self._velList=velList
        self._velListNumpy=None
        self._forceList=forceList
        self._forceListNumpy=None
        self._paramMap=paramMap

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

    def __setstate__(self, serializationString):
        dState = XmlSerializer.deserialize(serializationString)
# Safe provided no __slots__ or other weird things are used
        self.__dict__.update(dState.__dict__)

    def getTime(self):
        """Get the time for which this State was created."""
        return self._simTime * unit.picosecond

    def getPeriodicBoxVectors(self, asNumpy=False):
        """Get the three periodic box vectors if this state is from a
           simulation using PBC ."""
        if self._periodicBoxVectorsList is None:
            raise TypeError('periodic box vectors were not available.')

        if asNumpy:
            if self._periodicBoxVectorsListNumpy is None:
                self._periodicBoxVectorsListNumpy = \
                     numpy.array(self._periodicBoxVectorsList)
            returnValue=self._periodicBoxVectorsListNumpy
        else:
            returnValue=self._periodicBoxVectorsList

        returnValue = unit.Quantity(returnValue, unit.nanometers)
        return returnValue

    def getPeriodicBoxVolume(self):
        """Get the volume of the periodic box."""
        a = self._periodicBoxVectorsList[0]
        b = self._periodicBoxVectorsList[1]
        c = self._periodicBoxVectorsList[2]
        bcrossc = Vec3(b[1]*c[2]-b[2]*c[1], b[2]*c[0]-b[0]*c[2], b[0]*c[1]-b[1]*c[0])
        return unit.Quantity(unit.dot(a, bcrossc), unit.nanometers*unit.nanometers*unit.nanometers)

    def getPositions(self, asNumpy=False):
        """Get the position of each particle with units.
           Raises an exception if postions where not requested in
           the context.getState() call.
           Returns a list of tuples, unless asNumpy is True, in
           which  case a Numpy array of arrays will be returned.
           To remove the units, divide return value by unit.angstrom
           or unit.nanometer.  See the following for details:
           https://simtk.org/home/python_units
           """
        if self._coordList is None:
            raise TypeError('Positions were not requested in getState() call, so are not available.')

        if asNumpy:
            if self._coordListNumpy is None:
                self._coordListNumpy=numpy.array(self._coordList)
            returnValue=self._coordListNumpy
        else:
            returnValue=self._coordList

        returnValue = unit.Quantity(returnValue, unit.nanometers)
        return returnValue

    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 tuples, unless asNumpy is True, in
           which  case a Numpy array of arrays will be returned.
           To remove the units, you can divide the return value by
           unit.angstrom/unit.picosecond or unit.meter/unit.second,
           etc.  See the following for details:
           https://simtk.org/home/python_units
           """
        if self._velList is None:
            raise TypeError('Velocities were not requested in getState() call, so are not available.')

        if asNumpy:
            if self._velListNumpy is None:
                self._velListNumpy=numpy.array(self._velList)
            returnValue=self._velListNumpy
        else:
            returnValue=self._velList

        returnValue = unit.Quantity(returnValue, unit.nanometers/unit.picosecond)
        return returnValue

    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 tuples, unless asNumpy is True, in
           which  case a Numpy array of arrays will be returned.
           To remove the units, you can divide the return value by
           unit.kilojoule_per_mole/unit.angstrom or
           unit.calorie_per_mole/unit.nanometer, etc.
           See the following for details:
           https://simtk.org/home/python_units
           """
        if self._forceList is None:
            raise TypeError('Forces were not requested in getState() call, so are not available.')

        if asNumpy:
            if self._forceListNumpy is None:
                self._forceListNumpy=numpy.array(self._forceList)
            returnValue=self._forceListNumpy
        else:
            returnValue=self._forceList

        returnValue = unit.Quantity(returnValue,
                                    unit.kilojoule_per_mole/unit.nanometer)
        return returnValue

    def getKineticEnergy(self):
        """Get the total kinetic energy of the system with units.
           To remove the units, you can divide the return value by
           unit.kilojoule_per_mole or unit.calorie_per_mole, etc.
           See the following for details:
           https://simtk.org/home/python_units
        """
        if self._eK0 is None:
            raise TypeError('Energy was not requested in getState() call, so it is not available.')
        return self._eK0 * unit.kilojoule_per_mole

    def getPotentialEnergy(self):
        """Get the total potential energy of the system with units.
           To remove the units, you can divide the return value by
           unit.kilojoule_per_mole or unit.kilocalorie_per_mole, etc.
           See the following for details:
           https://simtk.org/home/python_units
        """
        if self._eP0 is None:
            raise TypeError('Energy was not requested in getState() call, so it is not available.')
        return self._eP0 * unit.kilojoule_per_mole

    def getParameters(self):
        """Get a map containing the values of all parameters.
        """
        if self._paramMap is None:
            raise TypeError('Parameters were not requested in getState() call, so are not available.')
        return self._paramMap


class Force(_object):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Force, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Force, name)

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

    def getForceGroup(self):
        """
        getForceGroup(self) -> int

        Get the force group this Force belongs to.
        """
        return _openmm.Force_getForceGroup(self)


    def setForceGroup(self, group):
        """
        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):
        """
        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):
        """__copy__(self) -> Force"""
        return _openmm.Force___copy__(self)

Force_swigregister = _openmm.Force_swigregister
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):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaAngleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaAngleForce, name)
    __repr__ = _swig_repr

    def getNumAngles(self):
        """
        getNumAngles(self) -> int

        Get the number of angle stretch terms in the potential function
        """
        return _openmm.AmoebaAngleForce_getNumAngles(self)


    def setAmoebaGlobalAngleCubic(self, cubicK):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaAngleForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaAngleForce
        __init__(self, other) -> AmoebaAngleForce

        Create an AmoebaAngleForce.
        """
        this = _openmm.new_AmoebaAngleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaAngleForce
    __del__ = lambda self: None
AmoebaAngleForce_swigregister = _openmm.AmoebaAngleForce_swigregister
AmoebaAngleForce_swigregister(AmoebaAngleForce)

class AmoebaBondForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaBondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaBondForce, name)
    __repr__ = _swig_repr

    def getNumBonds(self):
        """
        getNumBonds(self) -> int

        Get the number of bond stretch terms in the potential function
        """
        return _openmm.AmoebaBondForce_getNumBonds(self)


    def setAmoebaGlobalBondCubic(self, cubicK):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaBondForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaBondForce
        __init__(self, other) -> AmoebaBondForce

        Create an AmoebaBondForce.
        """
        this = _openmm.new_AmoebaBondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaBondForce
    __del__ = lambda self: None
AmoebaBondForce_swigregister = _openmm.AmoebaBondForce_swigregister
AmoebaBondForce_swigregister(AmoebaBondForce)

class AmoebaGeneralizedKirkwoodForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaGeneralizedKirkwoodForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaGeneralizedKirkwoodForce, name)
    __repr__ = _swig_repr

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles in the system.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getNumParticles(self)


    def addParticle(self, charge, radius, scalingFactor):
        """
        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):
        """
        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):
        """
        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):
        """
        getSolventDielectric(self) -> double

        Get the dielectric constant for the solvent.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getSolventDielectric(self)


    def setSolventDielectric(self, dielectric):
        """
        setSolventDielectric(self, dielectric)

        Set the dielectric constant for the solvent.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setSolventDielectric(self, dielectric)


    def getSoluteDielectric(self):
        """
        getSoluteDielectric(self) -> double

        Get the dielectric constant for the solute.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getSoluteDielectric(self)


    def setSoluteDielectric(self, dielectric):
        """
        setSoluteDielectric(self, dielectric)

        Set the dielectric constant for the solute.
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_setSoluteDielectric(self, dielectric)


    def getIncludeCavityTerm(self):
        """
        getIncludeCavityTerm(self) -> int

        Get the flag signaling whether the cavity term should be included
        """
        return _openmm.AmoebaGeneralizedKirkwoodForce_getIncludeCavityTerm(self)


    def setIncludeCavityTerm(self, includeCavityTerm):
        """
        setIncludeCavityTerm(self, includeCavityTerm)

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


    def getProbeRadius(self):
        """
        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):
        """
        setProbeRadius(self, probeRadius)

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


    def getSurfaceAreaFactor(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __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().
        """
        this = _openmm.new_AmoebaGeneralizedKirkwoodForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaGeneralizedKirkwoodForce
    __del__ = lambda self: None
AmoebaGeneralizedKirkwoodForce_swigregister = _openmm.AmoebaGeneralizedKirkwoodForce_swigregister
AmoebaGeneralizedKirkwoodForce_swigregister(AmoebaGeneralizedKirkwoodForce)

class AmoebaInPlaneAngleForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaInPlaneAngleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaInPlaneAngleForce, name)
    __repr__ = _swig_repr

    def getNumAngles(self):
        """
        getNumAngles(self) -> int

        Get the number of in-plane angle terms in the potential function
        """
        return _openmm.AmoebaInPlaneAngleForce_getNumAngles(self)


    def setAmoebaGlobalInPlaneAngleCubic(self, cubicK):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaInPlaneAngleForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaInPlaneAngleForce
        __init__(self, other) -> AmoebaInPlaneAngleForce

        Create an AmoebaAngleForce.
        """
        this = _openmm.new_AmoebaInPlaneAngleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaInPlaneAngleForce
    __del__ = lambda self: None
AmoebaInPlaneAngleForce_swigregister = _openmm.AmoebaInPlaneAngleForce_swigregister
AmoebaInPlaneAngleForce_swigregister(AmoebaInPlaneAngleForce)

class AmoebaMultipoleForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaMultipoleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaMultipoleForce, name)
    __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):
        """
        getNumMultipoles(self) -> int

        Get the number of particles in the potential function
        """
        return _openmm.AmoebaMultipoleForce_getNumMultipoles(self)


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::AmoebaMultipoleForce::NonbondedMethod

        Get the method used for handling long-range nonbonded interactions.
        """
        return _openmm.AmoebaMultipoleForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

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


    def getPolarizationType(self):
        """
        getPolarizationType(self) -> OpenMM::AmoebaMultipoleForce::PolarizationType

        Get polarization type
        """
        return _openmm.AmoebaMultipoleForce_getPolarizationType(self)


    def setPolarizationType(self, type):
        """
        setPolarizationType(self, type)

        Set the polarization type
        """
        return _openmm.AmoebaMultipoleForce_setPolarizationType(self, type)


    def getCutoffDistance(self):
        """
        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):
        """
        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 getAEwald(self):
        """
        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.

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

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


        return val


    def setAEwald(self, aewald):
        """
        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.

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


    def getPmeBSplineOrder(self):
        """
        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):
        """
        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.

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


    def setPmeGridDimensions(self, gridDimension):
        """
        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.

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


    def getPMEParametersInContext(self, context):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 getInducedDipoles(self, context):
        """
        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 getElectrostaticPotential(self, inputGrid, context):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __init__(self) -> AmoebaMultipoleForce
        __init__(self, other) -> AmoebaMultipoleForce

        Create an AmoebaMultipoleForce.
        """
        this = _openmm.new_AmoebaMultipoleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaMultipoleForce
    __del__ = lambda self: None
AmoebaMultipoleForce_swigregister = _openmm.AmoebaMultipoleForce_swigregister
AmoebaMultipoleForce_swigregister(AmoebaMultipoleForce)

class AmoebaOutOfPlaneBendForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaOutOfPlaneBendForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaOutOfPlaneBendForce, name)
    __repr__ = _swig_repr

    def getNumOutOfPlaneBends(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaOutOfPlaneBendForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaOutOfPlaneBendForce
        __init__(self, other) -> AmoebaOutOfPlaneBendForce

        Create an AmoebaOutOfPlaneBendForce.
        """
        this = _openmm.new_AmoebaOutOfPlaneBendForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaOutOfPlaneBendForce
    __del__ = lambda self: None
AmoebaOutOfPlaneBendForce_swigregister = _openmm.AmoebaOutOfPlaneBendForce_swigregister
AmoebaOutOfPlaneBendForce_swigregister(AmoebaOutOfPlaneBendForce)

class AmoebaPiTorsionForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaPiTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaPiTorsionForce, name)
    __repr__ = _swig_repr

    def getNumPiTorsions(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaPiTorsionForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaPiTorsionForce
        __init__(self, other) -> AmoebaPiTorsionForce

        Create an AmoebaPiTorsionForce.
        """
        this = _openmm.new_AmoebaPiTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaPiTorsionForce
    __del__ = lambda self: None
AmoebaPiTorsionForce_swigregister = _openmm.AmoebaPiTorsionForce_swigregister
AmoebaPiTorsionForce_swigregister(AmoebaPiTorsionForce)

class AmoebaStretchBendForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaStretchBendForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaStretchBendForce, name)
    __repr__ = _swig_repr

    def getNumStretchBends(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaStretchBendForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaStretchBendForce
        __init__(self, other) -> AmoebaStretchBendForce

        Create an AmoebaStretchBendForce.
        """
        this = _openmm.new_AmoebaStretchBendForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaStretchBendForce
    __del__ = lambda self: None
AmoebaStretchBendForce_swigregister = _openmm.AmoebaStretchBendForce_swigregister
AmoebaStretchBendForce_swigregister(AmoebaStretchBendForce)

class AmoebaTorsionTorsionForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaTorsionTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaTorsionTorsionForce, name)
    __repr__ = _swig_repr

    def getNumTorsionTorsions(self):
        """
        getNumTorsionTorsions(self) -> int

        Get the number of torsion-torsion terms in the potential function
        """
        return _openmm.AmoebaTorsionTorsionForce_getNumTorsionTorsions(self)


    def getNumTorsionTorsionGrids(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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.AmoebaTorsionTorsionForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> AmoebaTorsionTorsionForce
        __init__(self, other) -> AmoebaTorsionTorsionForce

        Create an AmoebaTorsionTorsionForce.
        """
        this = _openmm.new_AmoebaTorsionTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaTorsionTorsionForce
    __del__ = lambda self: None
AmoebaTorsionTorsionForce_swigregister = _openmm.AmoebaTorsionTorsionForce_swigregister
AmoebaTorsionTorsionForce_swigregister(AmoebaTorsionTorsionForce)

class AmoebaVdwForce(Force):
    """
    This class implements a buffered 14-7 potential used to model van der Waals forces.

    To use it, create an AmoebaVdwForce 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().

    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaVdwForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaVdwForce, name)
    __repr__ = _swig_repr
    NoCutoff = _openmm.AmoebaVdwForce_NoCutoff
    CutoffPeriodic = _openmm.AmoebaVdwForce_CutoffPeriodic

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles
        """
        return _openmm.AmoebaVdwForce_getNumParticles(self)


    def setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor):
        """
        setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor)

        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
        """
        return _openmm.AmoebaVdwForce_setParticleParameters(self, particleIndex, parentIndex, sigma, epsilon, reductionFactor)


    def getParticleParameters(self, particleIndex):
        """
        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
        """
        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, parentIndex, sigma, epsilon, reductionFactor):
        """
        addParticle(self, parentIndex, sigma, epsilon, reductionFactor) -> int

        Add the force field parameters for a vdw particle.

        Parameters
        ----------
        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

        Returns
        -------
        int
            index of added particle
        """
        return _openmm.AmoebaVdwForce_addParticle(self, parentIndex, sigma, epsilon, reductionFactor)


    def setSigmaCombiningRule(self, sigmaCombiningRule):
        """
        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):
        """
        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):
        """
        setEpsilonCombiningRule(self, epsilonCombiningRule)

        Set epsilon combining rule

        Parameters
        ----------
        epsilonCombiningRule : string
            epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
        """
        return _openmm.AmoebaVdwForce_setEpsilonCombiningRule(self, epsilonCombiningRule)


    def getEpsilonCombiningRule(self):
        """
        getEpsilonCombiningRule(self) -> std::string const &

        Get epsilon combining rule

        Returns
        -------
        string
            epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
        """
        return _openmm.AmoebaVdwForce_getEpsilonCombiningRule(self)


    def getUseDispersionCorrection(self):
        """
        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):
        """
        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 setParticleExclusions(self, particleIndex, exclusions):
        """
        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):
        """
        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 setCutoff(self, cutoff):
        """
        setCutoff(self, cutoff)

        Set the cutoff distance.
        """
        return _openmm.AmoebaVdwForce_setCutoff(self, cutoff)


    def getCutoff(self):
        """
        getCutoff(self) -> double

        Get the cutoff distance.
        """
        val = _openmm.AmoebaVdwForce_getCutoff(self)

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


        return val


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::AmoebaVdwForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.AmoebaVdwForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.AmoebaVdwForce_setNonbondedMethod(self, method)


    def updateParametersInContext(self, context):
        """
        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):
        """
        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):
        """
        __init__(self) -> AmoebaVdwForce
        __init__(self, other) -> AmoebaVdwForce

        Create an Amoeba VdwForce.
        """
        this = _openmm.new_AmoebaVdwForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaVdwForce
    __del__ = lambda self: None
AmoebaVdwForce_swigregister = _openmm.AmoebaVdwForce_swigregister
AmoebaVdwForce_swigregister(AmoebaVdwForce)

class AmoebaWcaDispersionForce(Force):
    """
    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().
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AmoebaWcaDispersionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AmoebaWcaDispersionForce, name)
    __repr__ = _swig_repr

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles
        """
        return _openmm.AmoebaWcaDispersionForce_getNumParticles(self)


    def setParticleParameters(self, particleIndex, radius, epsilon):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """getEpso(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getEpso(self)

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


        return val


    def getEpsh(self):
        """getEpsh(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getEpsh(self)

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


        return val


    def getRmino(self):
        """getRmino(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getRmino(self)

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


        return val


    def getRminh(self):
        """getRminh(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getRminh(self)

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


        return val


    def getAwater(self):
        """getAwater(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getAwater(self)

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


        return val


    def getShctd(self):
        """getShctd(self) -> double"""
        return _openmm.AmoebaWcaDispersionForce_getShctd(self)


    def getDispoff(self):
        """getDispoff(self) -> double"""
        val = _openmm.AmoebaWcaDispersionForce_getDispoff(self)

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


        return val


    def getSlevy(self):
        """getSlevy(self) -> double"""
        return _openmm.AmoebaWcaDispersionForce_getSlevy(self)


    def setEpso(self, inputValue):
        """setEpso(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setEpso(self, inputValue)


    def setEpsh(self, inputValue):
        """setEpsh(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setEpsh(self, inputValue)


    def setRmino(self, inputValue):
        """setRmino(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setRmino(self, inputValue)


    def setRminh(self, inputValue):
        """setRminh(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setRminh(self, inputValue)


    def setAwater(self, inputValue):
        """setAwater(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setAwater(self, inputValue)


    def setShctd(self, inputValue):
        """setShctd(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setShctd(self, inputValue)


    def setDispoff(self, inputValue):
        """setDispoff(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setDispoff(self, inputValue)


    def setSlevy(self, inputValue):
        """setSlevy(self, inputValue)"""
        return _openmm.AmoebaWcaDispersionForce_setSlevy(self, inputValue)


    def usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __init__(self) -> AmoebaWcaDispersionForce
        __init__(self, other) -> AmoebaWcaDispersionForce

        Create an AmoebaWcaDispersionForce.
        """
        this = _openmm.new_AmoebaWcaDispersionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AmoebaWcaDispersionForce
    __del__ = lambda self: None
AmoebaWcaDispersionForce_swigregister = _openmm.AmoebaWcaDispersionForce_swigregister
AmoebaWcaDispersionForce_swigregister(AmoebaWcaDispersionForce)

class AndersenThermostat(Force):
    """This class uses the Andersen method to maintain constant temperature."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, AndersenThermostat, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, AndersenThermostat, name)
    __repr__ = _swig_repr

    def Temperature():
        """
        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()

    if _newclass:
        Temperature = staticmethod(Temperature)
    __swig_getmethods__["Temperature"] = lambda x: Temperature

    def CollisionFrequency():
        """
        CollisionFrequency() -> std::string const &

        This is the name of the parameter which store the current collision frequency (in 1/ps).
        """
        return _openmm.AndersenThermostat_CollisionFrequency()

    if _newclass:
        CollisionFrequency = staticmethod(CollisionFrequency)
    __swig_getmethods__["CollisionFrequency"] = lambda x: CollisionFrequency

    def getDefaultTemperature(self):
        """
        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):
        """
        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)
        """
        return _openmm.AndersenThermostat_setDefaultTemperature(self, temperature)


    def getDefaultCollisionFrequency(self):
        """
        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):
        """
        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):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.AndersenThermostat_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_AndersenThermostat(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_AndersenThermostat
    __del__ = lambda self: None
AndersenThermostat_swigregister = _openmm.AndersenThermostat_swigregister
AndersenThermostat_swigregister(AndersenThermostat)

def AndersenThermostat_Temperature():
    """
    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():
    """
    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):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Integrator, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Integrator, name)

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

    def getStepSize(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 __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):
        """__copy__(self) -> Integrator"""
        return _openmm.Integrator___copy__(self)

Integrator_swigregister = _openmm.Integrator_swigregister
Integrator_swigregister(Integrator)

class BrownianIntegrator(Integrator):
    """This is an Integrator which simulates a System using Brownian dynamics."""
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, BrownianIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, BrownianIntegrator, name)
    __repr__ = _swig_repr

    def getTemperature(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.BrownianIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_BrownianIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_BrownianIntegrator
    __del__ = lambda self: None
BrownianIntegrator_swigregister = _openmm.BrownianIntegrator_swigregister
BrownianIntegrator_swigregister(BrownianIntegrator)

class CMAPTorsionForce(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CMAPTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CMAPTorsionForce, name)
    __repr__ = _swig_repr

    def getNumMaps(self):
        """
        getNumMaps(self) -> int

        Get the number of maps that have been defined.
        """
        return _openmm.CMAPTorsionForce_getNumMaps(self)


    def getNumTorsions(self):
        """
        getNumTorsions(self) -> int

        Get the number of CMAP torsion terms in the potential function
        """
        return _openmm.CMAPTorsionForce_getNumTorsions(self)


    def addMap(self, size, energy):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        usesPeriodicBoundaryConditions(self) -> bool

        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CMAPTorsionForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __init__(self) -> CMAPTorsionForce
        __init__(self, other) -> CMAPTorsionForce

        Create a CMAPTorsionForce.
        """
        this = _openmm.new_CMAPTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CMAPTorsionForce
    __del__ = lambda self: None
CMAPTorsionForce_swigregister = _openmm.CMAPTorsionForce_swigregister
CMAPTorsionForce_swigregister(CMAPTorsionForce)

class CMMotionRemover(Force):
    """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."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CMMotionRemover, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CMMotionRemover, name)
    __repr__ = _swig_repr

    def getFrequency(self):
        """
        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):
        """
        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):
        """
        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):
        """
        __init__(self, frequency=1) -> CMMotionRemover
        __init__(self) -> CMMotionRemover
        __init__(self, other) -> CMMotionRemover

        Create a CMMotionRemover.
        """
        this = _openmm.new_CMMotionRemover(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CMMotionRemover
    __del__ = lambda self: None
CMMotionRemover_swigregister = _openmm.CMMotionRemover_swigregister
CMMotionRemover_swigregister(CMMotionRemover)

class CompoundIntegrator(Integrator):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CompoundIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CompoundIntegrator, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CompoundIntegrator
    __del__ = lambda self: None

    def getNumIntegrators(self):
        """
        getNumIntegrators(self) -> int

        Get the number of Integrators that have been added to this CompoundIntegrator.
        """
        return _openmm.CompoundIntegrator_getNumIntegrators(self)


    def addIntegrator(self, integrator):
        """
        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):
        """
        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):
        """
        getCurrentIntegrator(self) -> int

        Get the index of the current Integrator.
        """
        return _openmm.CompoundIntegrator_getCurrentIntegrator(self)


    def setCurrentIntegrator(self, index):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __init__(self) -> CompoundIntegrator
        __init__(self, other) -> CompoundIntegrator

        Create a CompoundIntegrator.
        """
        this = _openmm.new_CompoundIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CompoundIntegrator_swigregister = _openmm.CompoundIntegrator_swigregister
CompoundIntegrator_swigregister(CompoundIntegrator)

class Context(_object):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Context, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Context, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_Context
    __del__ = lambda self: None

    def getSystem(self):
        """
        getSystem(self) -> System

        Get System being simulated in this context.
        """
        return _openmm.Context_getSystem(self)


    def getIntegrator(self, *args):
        """
        getIntegrator(self) -> Integrator
        getIntegrator(self) -> Integrator

        Get Integrator being used to by this context.
        """
        return _openmm.Context_getIntegrator(self, *args)


    def getPlatform(self, *args):
        """
        getPlatform(self) -> Platform
        getPlatform(self) -> Platform

        Get the Platform being used for calculations.
        """
        return _openmm.Context_getPlatform(self, *args)


    def setTime(self, time):
        """
        setTime(self, time)

        Set the current time of the simulation (in picoseconds).
        """
        return _openmm.Context_setTime(self, time)


    def setPositions(self, positions):
        """
        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):
        """
        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):
        """
        setVelocitiesToTemperature(self, temperature, randomSeed)
        setVelocitiesToTemperature(self, temperature)

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        reinitialize(self)

        When a Context is created, it may cache 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 might not see all of 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.
        """
        return _openmm.Context_reinitialize(self)


    def getMolecules(self):
        """
        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 _getStateAsLists(self, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups):
        """_getStateAsLists(self, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups) -> PyObject *"""
        return _openmm.Context__getStateAsLists(self, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups)


    def getState(self, getPositions=False, getVelocities=False,
                 getForces=False, getEnergy=False, getParameters=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
        getParameter : bool=False
            whether to store context 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.
        """
        getP, getV, getF, getE, getPa, enforcePeriodic = map(bool,
            (getPositions, getVelocities, getForces, getEnergy, getParameters,
             enforcePeriodicBox))

        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)

        (simTime, periodicBoxVectorsList, energy, coordList, velList,
         forceList, paramMap) = \
            self._getStateAsLists(getP, getV, getF, getE, getPa, enforcePeriodic, groups_mask)

        state = State(simTime=simTime,
                      energy=energy,
                      coordList=coordList,
                      velList=velList,
                      forceList=forceList,
                      periodicBoxVectorsList=periodicBoxVectorsList,
                      paramMap=paramMap)
        return state

    def setState(self, state):
        """
        setState(Context self, State 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.
        """
        self.setTime(state._simTime)
        self.setPeriodicBoxVectors(state._periodicBoxVectorsList[0], state._periodicBoxVectorsList[1], state._periodicBoxVectorsList[2])
        if state._coordList is not None:
             self.setPositions(state._coordList)
        if state._velList is not None:
             self.setVelocities(state._velList)
        if state._paramMap is not None:
             for param in state._paramMap:
                 self.setParameter(param, state._paramMap[param])


    def createCheckpoint(self):
        """
        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):
        """
        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):
        """
        __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.
        """
        this = _openmm.new_Context(*args)
        try:
            self.this.append(this)
        except:
            self.this = this

        self._system = args[0]
        self._integrator = args[1]



Context_swigregister = _openmm.Context_swigregister
Context_swigregister(Context)

class TabulatedFunction(_object):
    """
    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.


    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, TabulatedFunction, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, TabulatedFunction, name)

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

    def Copy(self):
        """Copy(self) -> TabulatedFunction"""
        return _openmm.TabulatedFunction_Copy(self)

TabulatedFunction_swigregister = _openmm.TabulatedFunction_swigregister
TabulatedFunction_swigregister(TabulatedFunction)

class Continuous1DFunction(TabulatedFunction):
    """This is a TabulatedFunction that computes a continuous one dimensional function."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Continuous1DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Continuous1DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, values, min, max):
        """
        __init__(self, values, min, max) -> Continuous1DFunction

        This is a TabulatedFunction that computes a continuous one dimensional function.
        """
        this = _openmm.new_Continuous1DFunction(values, min, max)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Continuous1DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, values, min, max):
        """setFunctionParameters(self, values, min, max)"""
        return _openmm.Continuous1DFunction_setFunctionParameters(self, values, min, max)


    def Copy(self):
        """Copy(self) -> Continuous1DFunction"""
        return _openmm.Continuous1DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Continuous1DFunction
    __del__ = lambda self: None
Continuous1DFunction_swigregister = _openmm.Continuous1DFunction_swigregister
Continuous1DFunction_swigregister(Continuous1DFunction)

class Continuous2DFunction(TabulatedFunction):
    """This is a TabulatedFunction that computes a continuous two dimensional function."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Continuous2DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Continuous2DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, values, xmin, xmax, ymin, ymax):
        """
        __init__(self, xsize, ysize, values, xmin, xmax, ymin, ymax) -> Continuous2DFunction

        This is a TabulatedFunction that computes a continuous two dimensional function.
        """
        this = _openmm.new_Continuous2DFunction(xsize, ysize, values, xmin, xmax, ymin, ymax)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Continuous2DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax):
        """setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax)"""
        return _openmm.Continuous2DFunction_setFunctionParameters(self, xsize, ysize, values, xmin, xmax, ymin, ymax)


    def Copy(self):
        """Copy(self) -> Continuous2DFunction"""
        return _openmm.Continuous2DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Continuous2DFunction
    __del__ = lambda self: None
Continuous2DFunction_swigregister = _openmm.Continuous2DFunction_swigregister
Continuous2DFunction_swigregister(Continuous2DFunction)

class Continuous3DFunction(TabulatedFunction):
    """This is a TabulatedFunction that computes a continuous three dimensional function."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Continuous3DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Continuous3DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax):
        """
        __init__(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax) -> Continuous3DFunction

        This is a TabulatedFunction that computes a continuous three dimensional function.
        """
        this = _openmm.new_Continuous3DFunction(xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Continuous3DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, xsize, ysize, zsize, values, xmin, xmax, ymin, ymax, zmin, zmax):
        """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):
        """Copy(self) -> Continuous3DFunction"""
        return _openmm.Continuous3DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Continuous3DFunction
    __del__ = lambda self: None
Continuous3DFunction_swigregister = _openmm.Continuous3DFunction_swigregister
Continuous3DFunction_swigregister(Continuous3DFunction)

class CustomAngleForce(Force):
    """
    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>

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomAngleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomAngleForce, name)
    __repr__ = _swig_repr

    def getNumAngles(self):
        """
        getNumAngles(self) -> int

        Get the number of angles for which force field parameters have been defined.
        """
        return _openmm.CustomAngleForce_getNumAngles(self)


    def getNumPerAngleParameters(self):
        """
        getNumPerAngleParameters(self) -> int

        Get the number of per-angle parameters that the interaction depends on.
        """
        return _openmm.CustomAngleForce_getNumPerAngleParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomAngleForce_getNumGlobalParameters(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addAngle(self, *args):
        """
        addAngle(self, particle1, particle2, particle3, parameters) -> int
        addAngle(self, particle1, particle2, particle3) -> 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):
        """
        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):
        """
        setAngleParameters(self, index, particle1, particle2, particle3, parameters)
        setAngleParameters(self, index, particle1, particle2, particle3)

        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        usesPeriodicBoundaryConditions(self) -> bool

        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CustomAngleForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_CustomAngleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomAngleForce
    __del__ = lambda self: None
CustomAngleForce_swigregister = _openmm.CustomAngleForce_swigregister
CustomAngleForce_swigregister(CustomAngleForce)

class CustomBondForce(Force):
    """
    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>

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomBondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomBondForce, name)
    __repr__ = _swig_repr

    def getNumBonds(self):
        """
        getNumBonds(self) -> int

        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomBondForce_getNumBonds(self)


    def getNumPerBondParameters(self):
        """
        getNumPerBondParameters(self) -> int

        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomBondForce_getNumPerBondParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomBondForce_getNumGlobalParameters(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addBond(self, *args):
        """
        addBond(self, particle1, particle2, parameters) -> int
        addBond(self, particle1, particle2) -> 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):
        """
        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):
        """
        setBondParameters(self, index, particle1, particle2, parameters)
        setBondParameters(self, index, particle1, particle2)

        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        usesPeriodicBoundaryConditions(self) -> bool

        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CustomBondForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_CustomBondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomBondForce
    __del__ = lambda self: None
CustomBondForce_swigregister = _openmm.CustomBondForce_swigregister
CustomBondForce_swigregister(CustomBondForce)

class CustomCentroidBondForce(Force):
    """
    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>

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomCentroidBondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomCentroidBondForce, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CustomCentroidBondForce
    __del__ = lambda self: None

    def getNumGroupsPerBond(self):
        """
        getNumGroupsPerBond(self) -> int

        Get the number of groups used to define each bond.
        """
        return _openmm.CustomCentroidBondForce_getNumGroupsPerBond(self)


    def getNumGroups(self):
        """
        getNumGroups(self) -> int

        Get the number of particle groups that have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumGroups(self)


    def getNumBonds(self):
        """
        getNumBonds(self) -> int

        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumBonds(self)


    def getNumPerBondParameters(self):
        """
        getNumPerBondParameters(self) -> int

        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomCentroidBondForce_getNumPerBondParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomCentroidBondForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumTabulatedFunctions(self)


    def getNumFunctions(self):
        """
        getNumFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCentroidBondForce_getNumFunctions(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addGroup(self, *args):
        """
        addGroup(self, particles, weights) -> int
        addGroup(self, particles) -> 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):
        """
        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):
        """
        setGroupParameters(self, index, particles, weights)
        setGroupParameters(self, index, particles)

        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):
        """
        addBond(self, groups, parameters) -> int
        addBond(self, groups) -> 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):
        """
        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):
        """
        setBondParameters(self, index, groups, parameters)
        setBondParameters(self, index, groups)

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        usesPeriodicBoundaryConditions(self) -> bool

        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CustomCentroidBondForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_CustomCentroidBondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CustomCentroidBondForce_swigregister = _openmm.CustomCentroidBondForce_swigregister
CustomCentroidBondForce_swigregister(CustomCentroidBondForce)

class CustomCompoundBondForce(Force):
    """
    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.

    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>

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomCompoundBondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomCompoundBondForce, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_CustomCompoundBondForce
    __del__ = lambda self: None

    def getNumParticlesPerBond(self):
        """
        getNumParticlesPerBond(self) -> int

        Get the number of particles used to define each bond.
        """
        return _openmm.CustomCompoundBondForce_getNumParticlesPerBond(self)


    def getNumBonds(self):
        """
        getNumBonds(self) -> int

        Get the number of bonds for which force field parameters have been defined.
        """
        return _openmm.CustomCompoundBondForce_getNumBonds(self)


    def getNumPerBondParameters(self):
        """
        getNumPerBondParameters(self) -> int

        Get the number of per-bond parameters that the interaction depends on.
        """
        return _openmm.CustomCompoundBondForce_getNumPerBondParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomCompoundBondForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCompoundBondForce_getNumTabulatedFunctions(self)


    def getNumFunctions(self):
        """
        getNumFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomCompoundBondForce_getNumFunctions(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addBond(self, *args):
        """
        addBond(self, particles, parameters) -> int
        addBond(self, particles) -> 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):
        """
        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):
        """
        setBondParameters(self, index, particles, parameters)
        setBondParameters(self, index, particles)

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addFunction(self, name, values, min, max) -> int

        Add a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomCompoundBondForce_addFunction(self, name, values, min, max)


    def getFunctionParameters(self, index):
        """
        getFunctionParameters(self, index)

        Get the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomCompoundBondForce_getFunctionParameters(self, index)


    def setFunctionParameters(self, index, name, values, min, max):
        """
        setFunctionParameters(self, index, name, values, min, max)

        Set the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomCompoundBondForce_setFunctionParameters(self, index, name, values, min, max)


    def updateParametersInContext(self, context):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        usesPeriodicBoundaryConditions(self) -> bool

        Returns whether or not this force makes use of periodic boundary conditions.

        Returns
        -------
        bool
            false
        """
        return _openmm.CustomCompoundBondForce_usesPeriodicBoundaryConditions(self)


    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_CustomCompoundBondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CustomCompoundBondForce_swigregister = _openmm.CustomCompoundBondForce_swigregister
CustomCompoundBondForce_swigregister(CustomCompoundBondForce)

class CustomExternalForce(Force):
    """
    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomExternalForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomExternalForce, name)
    __repr__ = _swig_repr

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomExternalForce_getNumParticles(self)


    def getNumPerParticleParameters(self):
        """
        getNumPerParticleParameters(self) -> int

        Get the number of per-particle parameters that the force depends on
        """
        return _openmm.CustomExternalForce_getNumPerParticleParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the force depends on.
        """
        return _openmm.CustomExternalForce_getNumGlobalParameters(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the force may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addParticle(self, particle, parameters) -> int
        addParticle(self, particle) -> 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):
        """
        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):
        """
        setParticleParameters(self, index, particle, parameters)
        setParticleParameters(self, index, particle)

        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):
        """
        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):
        """
        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):
        """
        __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
        """
        this = _openmm.new_CustomExternalForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomExternalForce
    __del__ = lambda self: None
CustomExternalForce_swigregister = _openmm.CustomExternalForce_swigregister
CustomExternalForce_swigregister(CustomExternalForce)

class CustomGBForce(Force):
    """
    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.

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomGBForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomGBForce, name)
    __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
    __del__ = lambda self: None

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomGBForce_getNumParticles(self)


    def getNumExclusions(self):
        """
        getNumExclusions(self) -> int

        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomGBForce_getNumExclusions(self)


    def getNumPerParticleParameters(self):
        """
        getNumPerParticleParameters(self) -> int

        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumPerParticleParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomGBForce_getNumTabulatedFunctions(self)


    def getNumFunctions(self):
        """
        getNumFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomGBForce_getNumFunctions(self)


    def getNumComputedValues(self):
        """
        getNumComputedValues(self) -> int

        Get the number of per-particle computed values the interaction depends on.
        """
        return _openmm.CustomGBForce_getNumComputedValues(self)


    def getNumEnergyTerms(self):
        """
        getNumEnergyTerms(self) -> int

        Get the number of terms in the energy computation.
        """
        return _openmm.CustomGBForce_getNumEnergyTerms(self)


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::CustomGBForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomGBForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomGBForce_setNonbondedMethod(self, method)


    def getCutoffDistance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addParticle(self, *args):
        """
        addParticle(self, parameters) -> int
        addParticle(self) -> 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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addFunction(self, name, values, min, max) -> int

        Add a tabulated function that may appear in expressions.
        """
        return _openmm.CustomGBForce_addFunction(self, name, values, min, max)


    def getFunctionParameters(self, index):
        """
        getFunctionParameters(self, index)

        Get the parameters for a tabulated function that may appear in expressions.
        """
        return _openmm.CustomGBForce_getFunctionParameters(self, index)


    def setFunctionParameters(self, index, name, values, min, max):
        """
        setFunctionParameters(self, index, name, values, min, max)

        Set the parameters for a tabulated function that may appear in expressions.
        """
        return _openmm.CustomGBForce_setFunctionParameters(self, index, name, values, min, max)


    def updateParametersInContext(self, context):
        """
        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):
        """
        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):
        """
        __init__(self) -> CustomGBForce
        __init__(self, other) -> CustomGBForce

        Create a CustomGBForce.
        """
        this = _openmm.new_CustomGBForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CustomGBForce_swigregister = _openmm.CustomGBForce_swigregister
CustomGBForce_swigregister(CustomGBForce)

class CustomHbondForce(Force):
    """
    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomHbondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomHbondForce, name)
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomHbondForce_NoCutoff
    CutoffNonPeriodic = _openmm.CustomHbondForce_CutoffNonPeriodic
    CutoffPeriodic = _openmm.CustomHbondForce_CutoffPeriodic
    __swig_destroy__ = _openmm.delete_CustomHbondForce
    __del__ = lambda self: None

    def getNumDonors(self):
        """
        getNumDonors(self) -> int

        Get the number of donors for which force field parameters have been defined.
        """
        return _openmm.CustomHbondForce_getNumDonors(self)


    def getNumAcceptors(self):
        """
        getNumAcceptors(self) -> int

        Get the number of acceptors for which force field parameters have been defined.
        """
        return _openmm.CustomHbondForce_getNumAcceptors(self)


    def getNumExclusions(self):
        """
        getNumExclusions(self) -> int

        Get the number of donor-acceptor pairs whose interactions should be excluded.
        """
        return _openmm.CustomHbondForce_getNumExclusions(self)


    def getNumPerDonorParameters(self):
        """
        getNumPerDonorParameters(self) -> int

        Get the number of per-donor parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumPerDonorParameters(self)


    def getNumPerAcceptorParameters(self):
        """
        getNumPerAcceptorParameters(self) -> int

        Get the number of per-acceptor parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumPerAcceptorParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomHbondForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomHbondForce_getNumTabulatedFunctions(self)


    def getNumFunctions(self):
        """
        getNumFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomHbondForce_getNumFunctions(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        getNonbondedMethod(self) -> OpenMM::CustomHbondForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomHbondForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomHbondForce_setNonbondedMethod(self, method)


    def getCutoffDistance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addDonor(self, d1, d2, d3, parameters) -> int
        addDonor(self, d1, d2, d3) -> 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):
        """
        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):
        """
        setDonorParameters(self, index, d1, d2, d3, parameters)
        setDonorParameters(self, index, d1, d2, d3)

        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):
        """
        addAcceptor(self, a1, a2, a3, parameters) -> int
        addAcceptor(self, a1, a2, a3) -> 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):
        """
        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):
        """
        setAcceptorParameters(self, index, a1, a2, a3, parameters)
        setAcceptorParameters(self, index, a1, a2, a3)

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addFunction(self, name, values, min, max) -> int

        Add a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomHbondForce_addFunction(self, name, values, min, max)


    def getFunctionParameters(self, index):
        """
        getFunctionParameters(self, index)

        Get the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomHbondForce_getFunctionParameters(self, index)


    def setFunctionParameters(self, index, name, values, min, max):
        """
        setFunctionParameters(self, index, name, values, min, max)

        Set the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomHbondForce_setFunctionParameters(self, index, name, values, min, max)


    def updateParametersInContext(self, context):
        """
        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):
        """
        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):
        """
        __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
        """
        this = _openmm.new_CustomHbondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CustomHbondForce_swigregister = _openmm.CustomHbondForce_swigregister
CustomHbondForce_swigregister(CustomHbondForce)

class CustomIntegrator(Integrator):
    """
    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.computePerDof("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.

    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 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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomIntegrator, name)
    __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

    def getNumGlobalVariables(self):
        """
        getNumGlobalVariables(self) -> int

        Get the number of global variables that have been defined.
        """
        return _openmm.CustomIntegrator_getNumGlobalVariables(self)


    def getNumPerDofVariables(self):
        """
        getNumPerDofVariables(self) -> int

        Get the number of per-DOF variables that have been defined.
        """
        return _openmm.CustomIntegrator_getNumPerDofVariables(self)


    def getNumComputations(self):
        """
        getNumComputations(self) -> int

        Get the number of computation steps that have been added.
        """
        return _openmm.CustomIntegrator_getNumComputations(self)


    def addGlobalVariable(self, name, initialValue):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 getKineticEnergyExpression(self):
        """
        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):
        """
        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):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.CustomIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        getPerDofVariable(self, index)
        getPerDofVariable(self, index) -> PyObject *
        """
        return _openmm.CustomIntegrator_getPerDofVariable(self, *args)


    def __init__(self, *args):
        """
        __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)
        """
        this = _openmm.new_CustomIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomIntegrator
    __del__ = lambda self: None
CustomIntegrator_swigregister = _openmm.CustomIntegrator_swigregister
CustomIntegrator_swigregister(CustomIntegrator)

class CustomManyParticleForce(Force):
    """
    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomManyParticleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomManyParticleForce, name)
    __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
    __del__ = lambda self: None

    def getNumParticlesPerSet(self):
        """
        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):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomManyParticleForce_getNumParticles(self)


    def getNumExclusions(self):
        """
        getNumExclusions(self) -> int

        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomManyParticleForce_getNumExclusions(self)


    def getNumPerParticleParameters(self):
        """
        getNumPerParticleParameters(self) -> int

        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomManyParticleForce_getNumPerParticleParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomManyParticleForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomManyParticleForce_getNumTabulatedFunctions(self)


    def getEnergyFunction(self):
        """
        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):
        """
        setEnergyFunction(self, energy)

        Set the algebraic expression that gives the interaction energy of each bond
        """
        return _openmm.CustomManyParticleForce_setEnergyFunction(self, energy)


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::CustomManyParticleForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomManyParticleForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomManyParticleForce_setNonbondedMethod(self, method)


    def getPermutationMode(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addParticle(self, parameters, type=0) -> int
        addParticle(self, parameters) -> int
        addParticle(self) -> 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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __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
        """
        this = _openmm.new_CustomManyParticleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
CustomManyParticleForce_swigregister = _openmm.CustomManyParticleForce_swigregister
CustomManyParticleForce_swigregister(CustomManyParticleForce)

class CustomNonbondedForce(Force):
    """
    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.

    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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomNonbondedForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomNonbondedForce, name)
    __repr__ = _swig_repr
    NoCutoff = _openmm.CustomNonbondedForce_NoCutoff
    CutoffNonPeriodic = _openmm.CustomNonbondedForce_CutoffNonPeriodic
    CutoffPeriodic = _openmm.CustomNonbondedForce_CutoffPeriodic

    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_CustomNonbondedForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomNonbondedForce
    __del__ = lambda self: None

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumParticles(self)


    def getNumExclusions(self):
        """
        getNumExclusions(self) -> int

        Get the number of particle pairs whose interactions should be excluded.
        """
        return _openmm.CustomNonbondedForce_getNumExclusions(self)


    def getNumPerParticleParameters(self):
        """
        getNumPerParticleParameters(self) -> int

        Get the number of per-particle parameters that the interaction depends on.
        """
        return _openmm.CustomNonbondedForce_getNumPerParticleParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomNonbondedForce_getNumGlobalParameters(self)


    def getNumTabulatedFunctions(self):
        """
        getNumTabulatedFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumTabulatedFunctions(self)


    def getNumFunctions(self):
        """
        getNumFunctions(self) -> int

        Get the number of tabulated functions that have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumFunctions(self)


    def getNumInteractionGroups(self):
        """
        getNumInteractionGroups(self) -> int

        Get the number of interaction groups that have been defined.
        """
        return _openmm.CustomNonbondedForce_getNumInteractionGroups(self)


    def getEnergyFunction(self):
        """
        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):
        """
        setEnergyFunction(self, energy)

        Set the algebraic expression that gives the interaction energy between two particles
        """
        return _openmm.CustomNonbondedForce_setEnergyFunction(self, energy)


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::CustomNonbondedForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomNonbondedForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.CustomNonbondedForce_setNonbondedMethod(self, method)


    def getCutoffDistance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addParticle(self, *args):
        """
        addParticle(self, parameters) -> int
        addParticle(self) -> 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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addFunction(self, name, values, min, max) -> int

        Add a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomNonbondedForce_addFunction(self, name, values, min, max)


    def getFunctionParameters(self, index):
        """
        getFunctionParameters(self, index)

        Get the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomNonbondedForce_getFunctionParameters(self, index)


    def setFunctionParameters(self, index, name, values, min, max):
        """
        setFunctionParameters(self, index, name, values, min, max)

        Set the parameters for a tabulated function that may appear in the energy expression.
        """
        return _openmm.CustomNonbondedForce_setFunctionParameters(self, index, name, values, min, max)


    def addInteractionGroup(self, set1, set2):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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)

CustomNonbondedForce_swigregister = _openmm.CustomNonbondedForce_swigregister
CustomNonbondedForce_swigregister(CustomNonbondedForce)

class CustomTorsionForce(Force):
    """
    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().

    As an example, the following code creates a CustomTorsionForce that implements a harmonic potential:

    <tt>CustomTorsionForce* force = new CustomTorsionForce("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->addPerTorsionParameter("k");
    force->addPerTorsionParameter("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, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, CustomTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, CustomTorsionForce, name)
    __repr__ = _swig_repr

    def getNumTorsions(self):
        """
        getNumTorsions(self) -> int

        Get the number of torsions for which force field parameters have been defined.
        """
        return _openmm.CustomTorsionForce_getNumTorsions(self)


    def getNumPerTorsionParameters(self):
        """
        getNumPerTorsionParameters(self) -> int

        Get the number of per-torsion parameters that the interaction depends on.
        """
        return _openmm.CustomTorsionForce_getNumPerTorsionParameters(self)


    def getNumGlobalParameters(self):
        """
        getNumGlobalParameters(self) -> int

        Get the number of global parameters that the interaction depends on.
        """
        return _openmm.CustomTorsionForce_getNumGlobalParameters(self)


    def getEnergyFunction(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        addGlobalParameter(self, name, defaultValue) -> int

        Add a new global parameter that the interaction may depend on.

        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 addTorsion(self, *args):
        """
        addTorsion(self, particle1, particle2, particle3, particle4, parameters) -> int
        addTorsion(self, particle1, particle2, particle3, particle4) -> 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):
        """
        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):
        """
        setTorsionParameters(self, index, particle1, particle2, particle3, particle4, parameters)
        setTorsionParameters(self, index, particle1, particle2, particle3, particle4)

        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __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
        """
        this = _openmm.new_CustomTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_CustomTorsionForce
    __del__ = lambda self: None
CustomTorsionForce_swigregister = _openmm.CustomTorsionForce_swigregister
CustomTorsionForce_swigregister(CustomTorsionForce)

class Discrete1DFunction(TabulatedFunction):
    """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."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Discrete1DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Discrete1DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, values):
        """
        __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.
        """
        this = _openmm.new_Discrete1DFunction(values)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Discrete1DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, values):
        """setFunctionParameters(self, values)"""
        return _openmm.Discrete1DFunction_setFunctionParameters(self, values)


    def Copy(self):
        """Copy(self) -> Discrete1DFunction"""
        return _openmm.Discrete1DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Discrete1DFunction
    __del__ = lambda self: None
Discrete1DFunction_swigregister = _openmm.Discrete1DFunction_swigregister
Discrete1DFunction_swigregister(Discrete1DFunction)

class Discrete2DFunction(TabulatedFunction):
    """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."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Discrete2DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Discrete2DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, values):
        """
        __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.
        """
        this = _openmm.new_Discrete2DFunction(xsize, ysize, values)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Discrete2DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, xsize, ysize, values):
        """setFunctionParameters(self, xsize, ysize, values)"""
        return _openmm.Discrete2DFunction_setFunctionParameters(self, xsize, ysize, values)


    def Copy(self):
        """Copy(self) -> Discrete2DFunction"""
        return _openmm.Discrete2DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Discrete2DFunction
    __del__ = lambda self: None
Discrete2DFunction_swigregister = _openmm.Discrete2DFunction_swigregister
Discrete2DFunction_swigregister(Discrete2DFunction)

class Discrete3DFunction(TabulatedFunction):
    """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."""
    __swig_setmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, Discrete3DFunction, name, value)
    __swig_getmethods__ = {}
    for _s in [TabulatedFunction]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, Discrete3DFunction, name)
    __repr__ = _swig_repr

    def __init__(self, xsize, ysize, zsize, values):
        """
        __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.
        """
        this = _openmm.new_Discrete3DFunction(xsize, ysize, zsize, values)
        try:
            self.this.append(this)
        except:
            self.this = this

    def getFunctionParameters(self):
        """getFunctionParameters(self)"""
        return _openmm.Discrete3DFunction_getFunctionParameters(self)


    def setFunctionParameters(self, xsize, ysize, zsize, values):
        """setFunctionParameters(self, xsize, ysize, zsize, values)"""
        return _openmm.Discrete3DFunction_setFunctionParameters(self, xsize, ysize, zsize, values)


    def Copy(self):
        """Copy(self) -> Discrete3DFunction"""
        return _openmm.Discrete3DFunction_Copy(self)

    __swig_destroy__ = _openmm.delete_Discrete3DFunction
    __del__ = lambda self: None
Discrete3DFunction_swigregister = _openmm.Discrete3DFunction_swigregister
Discrete3DFunction_swigregister(Discrete3DFunction)

class DrudeForce(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, DrudeForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, DrudeForce, name)
    __repr__ = _swig_repr

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.DrudeForce_getNumParticles(self)


    def getNumScreenedPairs(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __init__(self) -> DrudeForce
        __init__(self, other) -> DrudeForce

        Create a DrudeForce.
        """
        this = _openmm.new_DrudeForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_DrudeForce
    __del__ = lambda self: None
DrudeForce_swigregister = _openmm.DrudeForce_swigregister
DrudeForce_swigregister(DrudeForce)

class DrudeLangevinIntegrator(Integrator):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, DrudeLangevinIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, DrudeLangevinIntegrator, name)
    __repr__ = _swig_repr

    def getTemperature(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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 getDrudeTemperature(self):
        """
        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.DrudeLangevinIntegrator_getDrudeTemperature(self)

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


        return val


    def setDrudeTemperature(self, temp):
        """
        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.DrudeLangevinIntegrator_setDrudeTemperature(self, temp)


    def getDrudeFriction(self):
        """
        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, 1/unit.picosecond)


        return val


    def setDrudeFriction(self, coeff):
        """
        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 getMaxDrudeDistance(self):
        """
        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.DrudeLangevinIntegrator_getMaxDrudeDistance(self)

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


        return val


    def setMaxDrudeDistance(self, distance):
        """
        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.DrudeLangevinIntegrator_setMaxDrudeDistance(self, distance)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.DrudeLangevinIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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.DrudeLangevinIntegrator_setRandomNumberSeed(self, seed)


    def step(self, steps):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_DrudeLangevinIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_DrudeLangevinIntegrator
    __del__ = lambda self: None
DrudeLangevinIntegrator_swigregister = _openmm.DrudeLangevinIntegrator_swigregister
DrudeLangevinIntegrator_swigregister(DrudeLangevinIntegrator)

class DrudeSCFIntegrator(Integrator):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, DrudeSCFIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, DrudeSCFIntegrator, name)
    __repr__ = _swig_repr

    def getMinimizationErrorTolerance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_DrudeSCFIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_DrudeSCFIntegrator
    __del__ = lambda self: None
DrudeSCFIntegrator_swigregister = _openmm.DrudeSCFIntegrator_swigregister
DrudeSCFIntegrator_swigregister(DrudeSCFIntegrator)

class GBSAOBCForce(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, GBSAOBCForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, GBSAOBCForce, name)
    __repr__ = _swig_repr
    NoCutoff = _openmm.GBSAOBCForce_NoCutoff
    CutoffNonPeriodic = _openmm.GBSAOBCForce_CutoffNonPeriodic
    CutoffPeriodic = _openmm.GBSAOBCForce_CutoffPeriodic

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles in the system.
        """
        return _openmm.GBSAOBCForce_getNumParticles(self)


    def addParticle(self, charge, radius, scalingFactor):
        """
        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):
        """
        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):
        """
        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):
        """
        getSolventDielectric(self) -> double

        Get the dielectric constant for the solvent.
        """
        return _openmm.GBSAOBCForce_getSolventDielectric(self)


    def setSolventDielectric(self, dielectric):
        """
        setSolventDielectric(self, dielectric)

        Set the dielectric constant for the solvent.
        """
        return _openmm.GBSAOBCForce_setSolventDielectric(self, dielectric)


    def getSoluteDielectric(self):
        """
        getSoluteDielectric(self) -> double

        Get the dielectric constant for the solute.
        """
        return _openmm.GBSAOBCForce_getSoluteDielectric(self)


    def setSoluteDielectric(self, dielectric):
        """
        setSoluteDielectric(self, dielectric)

        Set the dielectric constant for the solute.
        """
        return _openmm.GBSAOBCForce_setSoluteDielectric(self, dielectric)


    def getSurfaceAreaEnergy(self):
        """
        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):
        """
        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):
        """
        getNonbondedMethod(self) -> OpenMM::GBSAOBCForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.GBSAOBCForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.GBSAOBCForce_setNonbondedMethod(self, method)


    def getCutoffDistance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        __init__(self) -> GBSAOBCForce
        __init__(self, other) -> GBSAOBCForce

        Create a GBSAOBCForce.
        """
        this = _openmm.new_GBSAOBCForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_GBSAOBCForce
    __del__ = lambda self: None
GBSAOBCForce_swigregister = _openmm.GBSAOBCForce_swigregister
GBSAOBCForce_swigregister(GBSAOBCForce)

class HarmonicAngleForce(Force):
    """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()."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, HarmonicAngleForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, HarmonicAngleForce, name)
    __repr__ = _swig_repr

    def getNumAngles(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __init__(self) -> HarmonicAngleForce
        __init__(self, other) -> HarmonicAngleForce

        Create a HarmonicAngleForce.
        """
        this = _openmm.new_HarmonicAngleForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_HarmonicAngleForce
    __del__ = lambda self: None
HarmonicAngleForce_swigregister = _openmm.HarmonicAngleForce_swigregister
HarmonicAngleForce_swigregister(HarmonicAngleForce)

class HarmonicBondForce(Force):
    """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()."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, HarmonicBondForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, HarmonicBondForce, name)
    __repr__ = _swig_repr

    def getNumBonds(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __init__(self) -> HarmonicBondForce
        __init__(self, other) -> HarmonicBondForce

        Create a HarmonicBondForce.
        """
        this = _openmm.new_HarmonicBondForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_HarmonicBondForce
    __del__ = lambda self: None
HarmonicBondForce_swigregister = _openmm.HarmonicBondForce_swigregister
HarmonicBondForce_swigregister(HarmonicBondForce)

class LangevinIntegrator(Integrator):
    """This is an Integrator which simulates a System using Langevin dynamics."""
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, LangevinIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, LangevinIntegrator, name)
    __repr__ = _swig_repr

    def getTemperature(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.LangevinIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_LangevinIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_LangevinIntegrator
    __del__ = lambda self: None
LangevinIntegrator_swigregister = _openmm.LangevinIntegrator_swigregister
LangevinIntegrator_swigregister(LangevinIntegrator)

class VirtualSite(_object):
    """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."""
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, VirtualSite, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, VirtualSite, name)

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

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles this virtual site depends on.
        """
        return _openmm.VirtualSite_getNumParticles(self)


    def getParticle(self, particle):
        """
        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)

VirtualSite_swigregister = _openmm.VirtualSite_swigregister
VirtualSite_swigregister(VirtualSite)

class LocalCoordinatesSite(VirtualSite):
    """
    This is a VirtualSite that uses the locations of three 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 three 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 three 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 excample, 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
    """
    __swig_setmethods__ = {}
    for _s in [VirtualSite]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, LocalCoordinatesSite, name, value)
    __swig_getmethods__ = {}
    for _s in [VirtualSite]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, LocalCoordinatesSite, name)
    __repr__ = _swig_repr

    def getOriginWeights(self):
        """
        getOriginWeights(self) -> Vec3 const &

        Get the weight factors for the three particles when computing the origin location.
        """
        return _openmm.LocalCoordinatesSite_getOriginWeights(self)


    def getXWeights(self):
        """
        getXWeights(self) -> Vec3 const &

        Get the weight factors for the three particles when computing xdir.
        """
        return _openmm.LocalCoordinatesSite_getXWeights(self)


    def getYWeights(self):
        """
        getYWeights(self) -> Vec3 const &

        Get the weight factors for the three particles when computing ydir.
        """
        return _openmm.LocalCoordinatesSite_getYWeights(self)


    def getLocalPosition(self):
        """
        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):
        """
        __init__(self, particle1, particle2, particle3, originWeights, xWeights, yWeights, localPosition) -> LocalCoordinatesSite
        __init__(self, other) -> LocalCoordinatesSite

        Create a new LocalCoordinatesSite 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
        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
        """
        this = _openmm.new_LocalCoordinatesSite(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_LocalCoordinatesSite
    __del__ = lambda self: None
LocalCoordinatesSite_swigregister = _openmm.LocalCoordinatesSite_swigregister
LocalCoordinatesSite_swigregister(LocalCoordinatesSite)

class LocalEnergyMinimizer(_object):
    """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."""
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, LocalEnergyMinimizer, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, LocalEnergyMinimizer, name)

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

    def minimize(context, tolerance=10, maxIterations=0):
        """
        minimize(context, tolerance=10, maxIterations=0)
        minimize(context, tolerance=10)
        minimize(context)

        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)

    if _newclass:
        minimize = staticmethod(minimize)
    __swig_getmethods__["minimize"] = lambda x: minimize
    __swig_destroy__ = _openmm.delete_LocalEnergyMinimizer
    __del__ = lambda self: None
LocalEnergyMinimizer_swigregister = _openmm.LocalEnergyMinimizer_swigregister
LocalEnergyMinimizer_swigregister(LocalEnergyMinimizer)

def LocalEnergyMinimizer_minimize(context, tolerance=10, maxIterations=0):
    """
    minimize(context, tolerance=10, maxIterations=0)
    minimize(context, tolerance=10)
    LocalEnergyMinimizer_minimize(context)

    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):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, MonteCarloAnisotropicBarostat, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, MonteCarloAnisotropicBarostat, name)
    __repr__ = _swig_repr

    def PressureX():
        """
        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()

    if _newclass:
        PressureX = staticmethod(PressureX)
    __swig_getmethods__["PressureX"] = lambda x: PressureX

    def PressureY():
        """
        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()

    if _newclass:
        PressureY = staticmethod(PressureY)
    __swig_getmethods__["PressureY"] = lambda x: PressureY

    def PressureZ():
        """
        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()

    if _newclass:
        PressureZ = staticmethod(PressureZ)
    __swig_getmethods__["PressureZ"] = lambda x: PressureZ

    def getDefaultPressure(self):
        """
        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):
        """
        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.
        """
        return _openmm.MonteCarloAnisotropicBarostat_setDefaultPressure(self, pressure)


    def getScaleX(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 getTemperature(self):
        """
        getTemperature(self) -> double

        Get the temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloAnisotropicBarostat_getTemperature(self)

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


        return val


    def setTemperature(self, temp):
        """
        setTemperature(self, temp)

        Set the temperature at which the system is being maintained.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """
        return _openmm.MonteCarloAnisotropicBarostat_setTemperature(self, temp)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloAnisotropicBarostat_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __init__(self, defaultPressure, temperature, scaleX=True, scaleY=True, scaleZ=True, frequency=25) -> MonteCarloAnisotropicBarostat
        __init__(self, defaultPressure, temperature, scaleX=True, scaleY=True, scaleZ=True) -> MonteCarloAnisotropicBarostat
        __init__(self, defaultPressure, temperature, scaleX=True, scaleY=True) -> MonteCarloAnisotropicBarostat
        __init__(self, defaultPressure, temperature, scaleX=True) -> MonteCarloAnisotropicBarostat
        __init__(self, defaultPressure, temperature) -> MonteCarloAnisotropicBarostat
        __init__(self, other) -> MonteCarloAnisotropicBarostat

        Create a MonteCarloAnisotropicBarostat.

        Parameters
        ----------
        defaultPressure : Vec3
            The default pressure acting on each axis (in bar)
        temperature : double
            the 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)
        """
        this = _openmm.new_MonteCarloAnisotropicBarostat(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_MonteCarloAnisotropicBarostat
    __del__ = lambda self: None
MonteCarloAnisotropicBarostat_swigregister = _openmm.MonteCarloAnisotropicBarostat_swigregister
MonteCarloAnisotropicBarostat_swigregister(MonteCarloAnisotropicBarostat)

def MonteCarloAnisotropicBarostat_PressureX():
    """
    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():
    """
    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():
    """
    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()

class MonteCarloBarostat(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, MonteCarloBarostat, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, MonteCarloBarostat, name)
    __repr__ = _swig_repr

    def Pressure():
        """
        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()

    if _newclass:
        Pressure = staticmethod(Pressure)
    __swig_getmethods__["Pressure"] = lambda x: Pressure

    def getDefaultPressure(self):
        """
        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):
        """
        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.
        """
        return _openmm.MonteCarloBarostat_setDefaultPressure(self, pressure)


    def getFrequency(self):
        """
        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):
        """
        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 getTemperature(self):
        """
        getTemperature(self) -> double

        Get the temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloBarostat_getTemperature(self)

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


        return val


    def setTemperature(self, temp):
        """
        setTemperature(self, temp)

        Set the temperature at which the system is being maintained.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """
        return _openmm.MonteCarloBarostat_setTemperature(self, temp)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloBarostat_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __init__(self, defaultPressure, temperature, frequency=25) -> MonteCarloBarostat
        __init__(self, defaultPressure, temperature) -> MonteCarloBarostat
        __init__(self, other) -> MonteCarloBarostat

        Create a MonteCarloBarostat.

        Parameters
        ----------
        defaultPressure : double
            the default pressure acting on the system (in bar)
        temperature : double
            the 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)
        """
        this = _openmm.new_MonteCarloBarostat(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_MonteCarloBarostat
    __del__ = lambda self: None
MonteCarloBarostat_swigregister = _openmm.MonteCarloBarostat_swigregister
MonteCarloBarostat_swigregister(MonteCarloBarostat)

def MonteCarloBarostat_Pressure():
    """
    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()

class MonteCarloMembraneBarostat(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, MonteCarloMembraneBarostat, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, MonteCarloMembraneBarostat, name)
    __repr__ = _swig_repr
    XYIsotropic = _openmm.MonteCarloMembraneBarostat_XYIsotropic
    XYAnisotropic = _openmm.MonteCarloMembraneBarostat_XYAnisotropic
    ZFree = _openmm.MonteCarloMembraneBarostat_ZFree
    ZFixed = _openmm.MonteCarloMembraneBarostat_ZFixed
    ConstantVolume = _openmm.MonteCarloMembraneBarostat_ConstantVolume

    def Pressure():
        """
        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()

    if _newclass:
        Pressure = staticmethod(Pressure)
    __swig_getmethods__["Pressure"] = lambda x: Pressure

    def SurfaceTension():
        """
        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()

    if _newclass:
        SurfaceTension = staticmethod(SurfaceTension)
    __swig_getmethods__["SurfaceTension"] = lambda x: SurfaceTension

    def getDefaultPressure(self):
        """
        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):
        """
        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.
        """
        return _openmm.MonteCarloMembraneBarostat_setDefaultPressure(self, pressure)


    def getDefaultSurfaceTension(self):
        """
        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):
        """
        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.
        """
        return _openmm.MonteCarloMembraneBarostat_setDefaultSurfaceTension(self, surfaceTension)


    def getFrequency(self):
        """
        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):
        """
        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 getTemperature(self):
        """
        getTemperature(self) -> double

        Get the temperature at which the system is being maintained, measured in Kelvin.
        """
        val = _openmm.MonteCarloMembraneBarostat_getTemperature(self)

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


        return val


    def setTemperature(self, temp):
        """
        setTemperature(self, temp)

        Set the temperature at which the system is being maintained.

        Parameters
        ----------
        temp : double
            the system temperature, measured in Kelvin.
        """
        return _openmm.MonteCarloMembraneBarostat_setTemperature(self, temp)


    def getXYMode(self):
        """
        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):
        """
        setXYMode(self, mode)

        Set the mode specifying the behavior of the X and Y axes.
        """
        return _openmm.MonteCarloMembraneBarostat_setXYMode(self, mode)


    def getZMode(self):
        """
        getZMode(self) -> OpenMM::MonteCarloMembraneBarostat::ZMode

        Get the mode specifying the behavior of the Z axis.
        """
        return _openmm.MonteCarloMembraneBarostat_getZMode(self)


    def setZMode(self, mode):
        """
        setZMode(self, mode)

        Set the mode specifying the behavior of the Z axis.
        """
        return _openmm.MonteCarloMembraneBarostat_setZMode(self, mode)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.MonteCarloMembraneBarostat_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __init__(self, defaultPressure, defaultSurfaceTension, temperature, xymode, zmode, frequency=25) -> MonteCarloMembraneBarostat
        __init__(self, defaultPressure, defaultSurfaceTension, temperature, xymode, zmode) -> 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)
        temperature : double
            the 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)
        """
        this = _openmm.new_MonteCarloMembraneBarostat(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_MonteCarloMembraneBarostat
    __del__ = lambda self: None
MonteCarloMembraneBarostat_swigregister = _openmm.MonteCarloMembraneBarostat_swigregister
MonteCarloMembraneBarostat_swigregister(MonteCarloMembraneBarostat)

def MonteCarloMembraneBarostat_Pressure():
    """
    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():
    """
    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()

class NonbondedForce(Force):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, NonbondedForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, NonbondedForce, name)
    __repr__ = _swig_repr
    NoCutoff = _openmm.NonbondedForce_NoCutoff
    CutoffNonPeriodic = _openmm.NonbondedForce_CutoffNonPeriodic
    CutoffPeriodic = _openmm.NonbondedForce_CutoffPeriodic
    Ewald = _openmm.NonbondedForce_Ewald
    PME = _openmm.NonbondedForce_PME

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles for which force field parameters have been defined.
        """
        return _openmm.NonbondedForce_getNumParticles(self)


    def getNumExceptions(self):
        """
        getNumExceptions(self) -> int

        Get the number of special interactions that should be calculated differently from other interactions.
        """
        return _openmm.NonbondedForce_getNumExceptions(self)


    def getNonbondedMethod(self):
        """
        getNonbondedMethod(self) -> OpenMM::NonbondedForce::NonbondedMethod

        Get the method used for handling long range nonbonded interactions.
        """
        return _openmm.NonbondedForce_getNonbondedMethod(self)


    def setNonbondedMethod(self, method):
        """
        setNonbondedMethod(self, method)

        Set the method used for handling long range nonbonded interactions.
        """
        return _openmm.NonbondedForce_setNonbondedMethod(self, method)


    def getCutoffDistance(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 setPMEParameters(self, alpha, nx, ny, nz):
        """
        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 getPMEParametersInContext(self, context):
        """
        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 addParticle(self, charge, sigma, epsilon):
        """
        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):
        """
        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):
        """
        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):
        """
        addException(self, particle1, particle2, chargeProd, sigma, epsilon, replace=False) -> int
        addException(self, particle1, particle2, chargeProd, sigma, epsilon) -> 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):
        """
        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):
        """
        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):
        """
        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 getUseDispersionCorrection(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 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):
        """
        __init__(self) -> NonbondedForce
        __init__(self, other) -> NonbondedForce

        Create a NonbondedForce.
        """
        this = _openmm.new_NonbondedForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_NonbondedForce
    __del__ = lambda self: None
NonbondedForce_swigregister = _openmm.NonbondedForce_swigregister
NonbondedForce_swigregister(NonbondedForce)

class OpenMMException(_object):
    """This class is used for all exceptions thrown by OpenMM."""
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, OpenMMException, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, OpenMMException, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_OpenMMException
    __del__ = lambda self: None

    def what(self):
        """what(self) -> char const *"""
        return _openmm.OpenMMException_what(self)


    def __init__(self, *args):
        """
        __init__(self, message) -> OpenMMException
        __init__(self, other) -> OpenMMException

        This class is used for all exceptions thrown by OpenMM.
        """
        this = _openmm.new_OpenMMException(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
OpenMMException_swigregister = _openmm.OpenMMException_swigregister
OpenMMException_swigregister(OpenMMException)

class OutOfPlaneSite(VirtualSite):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [VirtualSite]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, OutOfPlaneSite, name, value)
    __swig_getmethods__ = {}
    for _s in [VirtualSite]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, OutOfPlaneSite, name)
    __repr__ = _swig_repr

    def getWeight12(self):
        """
        getWeight12(self) -> double

        Get the weight factor for the vector from particle1 to particle2.
        """
        return _openmm.OutOfPlaneSite_getWeight12(self)


    def getWeight13(self):
        """
        getWeight13(self) -> double

        Get the weight factor for the vector from particle1 to particle3.
        """
        return _openmm.OutOfPlaneSite_getWeight13(self)


    def getWeightCross(self):
        """
        getWeightCross(self) -> double

        Get the weight factor for the cross product.
        """
        return _openmm.OutOfPlaneSite_getWeightCross(self)


    def __init__(self, *args):
        """
        __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
        """
        this = _openmm.new_OutOfPlaneSite(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_OutOfPlaneSite
    __del__ = lambda self: None
OutOfPlaneSite_swigregister = _openmm.OutOfPlaneSite_swigregister
OutOfPlaneSite_swigregister(OutOfPlaneSite)

class PeriodicTorsionForce(Force):
    """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()."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, PeriodicTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, PeriodicTorsionForce, name)
    __repr__ = _swig_repr

    def getNumTorsions(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __init__(self) -> PeriodicTorsionForce
        __init__(self, other) -> PeriodicTorsionForce

        Create a PeriodicTorsionForce.
        """
        this = _openmm.new_PeriodicTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_PeriodicTorsionForce
    __del__ = lambda self: None
PeriodicTorsionForce_swigregister = _openmm.PeriodicTorsionForce_swigregister
PeriodicTorsionForce_swigregister(PeriodicTorsionForce)

class Platform(_object):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Platform, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Platform, name)

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

    def registerPlatform(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

    if _newclass:
        registerPlatform = staticmethod(registerPlatform)
    __swig_getmethods__["registerPlatform"] = lambda x: registerPlatform

    def getNumPlatforms():
        """
        getNumPlatforms() -> int

        Get the number of Platforms that have been registered.
        """
        return _openmm.Platform_getNumPlatforms()

    if _newclass:
        getNumPlatforms = staticmethod(getNumPlatforms)
    __swig_getmethods__["getNumPlatforms"] = lambda x: getNumPlatforms

    def getPlatform(index):
        """
        getPlatform(index) -> Platform

        Get a registered Platform by index.
        """
        return _openmm.Platform_getPlatform(index)

    if _newclass:
        getPlatform = staticmethod(getPlatform)
    __swig_getmethods__["getPlatform"] = lambda x: getPlatform

    def getPluginLoadFailures():
        """
        getPluginLoadFailures() -> vectorstring

        Get any failures caused during the last call to loadPluginsFromDirectory
        """
        return _openmm.Platform_getPluginLoadFailures()

    if _newclass:
        getPluginLoadFailures = staticmethod(getPluginLoadFailures)
    __swig_getmethods__["getPluginLoadFailures"] = lambda x: getPluginLoadFailures

    def getPlatformByName(name):
        """
        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)

    if _newclass:
        getPlatformByName = staticmethod(getPlatformByName)
    __swig_getmethods__["getPlatformByName"] = lambda x: getPlatformByName

    def findPlatform(kernelNames):
        """
        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)

    if _newclass:
        findPlatform = staticmethod(findPlatform)
    __swig_getmethods__["findPlatform"] = lambda x: findPlatform

    def loadPluginLibrary(file):
        """
        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)

    if _newclass:
        loadPluginLibrary = staticmethod(loadPluginLibrary)
    __swig_getmethods__["loadPluginLibrary"] = lambda x: loadPluginLibrary

    def loadPluginsFromDirectory(directory):
        """
        loadPluginsFromDirectory(directory) -> vectorstring

        Load multiple dynamic libraries (DLLs) which contain OpenMM plugins from a single directory. This method loops over every file contained in the specified directory 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
            the path to the directory containing libraries to load

        Returns
        -------
        vector< std::string >
            the names of all files which were successfully loaded as libraries
        """
        return _openmm.Platform_loadPluginsFromDirectory(directory)

    if _newclass:
        loadPluginsFromDirectory = staticmethod(loadPluginsFromDirectory)
    __swig_getmethods__["loadPluginsFromDirectory"] = lambda x: loadPluginsFromDirectory

    def getDefaultPluginsDirectory():
        """
        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()

    if _newclass:
        getDefaultPluginsDirectory = staticmethod(getDefaultPluginsDirectory)
    __swig_getmethods__["getDefaultPluginsDirectory"] = lambda x: getDefaultPluginsDirectory

    def getOpenMMVersion():
        """
        getOpenMMVersion() -> std::string const &

        Get a string containing the version number of the OpenMM library.
        """
        return _openmm.Platform_getOpenMMVersion()

    if _newclass:
        getOpenMMVersion = staticmethod(getOpenMMVersion)
    __swig_getmethods__["getOpenMMVersion"] = lambda x: getOpenMMVersion

    def getName(self):
        """
        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):
        """
        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):
        """
        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.
        """
        return _openmm.Platform_supportsDoublePrecision(self)


    def getPropertyNames(self):
        """
        getPropertyNames(self) -> vectorstring

        Get the names of all Platform-specific properties this Platform supports.
        """
        return _openmm.Platform_getPropertyNames(self)


    def getPropertyValue(self, context, property):
        """
        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):
        """
        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):
        """
        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):
        """
        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 supportsKernels(self, kernelNames):
        """
        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)

Platform_swigregister = _openmm.Platform_swigregister
Platform_swigregister(Platform)

def Platform_registerPlatform(platform):
    """
    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():
    """
    Platform_getNumPlatforms() -> int

    Get the number of Platforms that have been registered.
    """
    return _openmm.Platform_getNumPlatforms()

def Platform_getPlatform(index):
    """
    Platform_getPlatform(index) -> Platform

    Get a registered Platform by index.
    """
    return _openmm.Platform_getPlatform(index)

def Platform_getPluginLoadFailures():
    """
    Platform_getPluginLoadFailures() -> vectorstring

    Get any failures caused during the last call to loadPluginsFromDirectory
    """
    return _openmm.Platform_getPluginLoadFailures()

def Platform_getPlatformByName(name):
    """
    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):
    """
    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):
    """
    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):
    """
    Platform_loadPluginsFromDirectory(directory) -> vectorstring

    Load multiple dynamic libraries (DLLs) which contain OpenMM plugins from a single directory. This method loops over every file contained in the specified directory 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
        the path to the directory 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():
    """
    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():
    """
    Platform_getOpenMMVersion() -> std::string const &

    Get a string containing the version number of the OpenMM library.
    """
    return _openmm.Platform_getOpenMMVersion()

class RBTorsionForce(Force):
    """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()."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, RBTorsionForce, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, RBTorsionForce, name)
    __repr__ = _swig_repr

    def getNumTorsions(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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 usesPeriodicBoundaryConditions(self):
        """
        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):
        """
        __init__(self) -> RBTorsionForce
        __init__(self, other) -> RBTorsionForce

        Create a RBTorsionForce.
        """
        this = _openmm.new_RBTorsionForce(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_RBTorsionForce
    __del__ = lambda self: None
RBTorsionForce_swigregister = _openmm.RBTorsionForce_swigregister
RBTorsionForce_swigregister(RBTorsionForce)

class RPMDIntegrator(Integrator):
    """
    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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, RPMDIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, RPMDIntegrator, name)
    __repr__ = _swig_repr

    def getNumCopies(self):
        """
        getNumCopies(self) -> int

        Get the number of copies of the system being simulated.
        """
        return _openmm.RPMDIntegrator_getNumCopies(self)


    def getTemperature(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        getApplyThermostat(self) -> bool

        Get whether a thermostat is applied to the system.
        """
        return _openmm.RPMDIntegrator_getApplyThermostat(self)


    def setApplyThermostat(self, apply):
        """
        setApplyThermostat(self, apply)

        Set whether a thermostat is applied to the system.
        """
        return _openmm.RPMDIntegrator_setApplyThermostat(self, apply)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.RPMDIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        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):
        """
        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 getTotalEnergy(self):
        """
        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):
        """
        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 _getStateAsLists(self, copy, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups):
        """_getStateAsLists(self, copy, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups) -> PyObject *"""
        return _openmm.RPMDIntegrator__getStateAsLists(self, copy, getPositions, getVelocities, getForces, getEnergy, getParameters, enforcePeriodic, groups)


    def getState(self,
                 copy,
                 getPositions=False,
                 getVelocities=False,
                 getForces=False,
                 getEnergy=False,
                 getParameters=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
        getParameter : bool=False
            whether to store context 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.
        """
        getP, getV, getF, getE, getPa, enforcePeriodic = map(bool,
            (getPositions, getVelocities, getForces, getEnergy, getParameters,
             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)

        (simTime, periodicBoxVectorsList, energy, coordList, velList,
          forceList, paramMap) = \
             self._getStateAsLists(copy, getP, getV, getF, getE, getPa, enforcePeriodic, groups_mask)

        state = State(simTime=simTime,
                      energy=energy,
                      coordList=coordList,
                      velList=velList,
                      forceList=forceList,
                      periodicBoxVectorsList=periodicBoxVectorsList,
                      paramMap=paramMap)
        return state


    def __init__(self, *args):
        """
        __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.
        """
        this = _openmm.new_RPMDIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_RPMDIntegrator
    __del__ = lambda self: None
RPMDIntegrator_swigregister = _openmm.RPMDIntegrator_swigregister
RPMDIntegrator_swigregister(RPMDIntegrator)

class RPMDMonteCarloBarostat(Force):
    """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)."""
    __swig_setmethods__ = {}
    for _s in [Force]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, RPMDMonteCarloBarostat, name, value)
    __swig_getmethods__ = {}
    for _s in [Force]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, RPMDMonteCarloBarostat, name)
    __repr__ = _swig_repr

    def Pressure():
        """
        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()

    if _newclass:
        Pressure = staticmethod(Pressure)
    __swig_getmethods__["Pressure"] = lambda x: Pressure

    def getDefaultPressure(self):
        """
        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):
        """
        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.
        """
        return _openmm.RPMDMonteCarloBarostat_setDefaultPressure(self, pressure)


    def getFrequency(self):
        """
        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):
        """
        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):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.RPMDMonteCarloBarostat_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        __init__(self, defaultPressure, frequency=25) -> RPMDMonteCarloBarostat
        __init__(self, defaultPressure) -> 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)
        """
        this = _openmm.new_RPMDMonteCarloBarostat(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_RPMDMonteCarloBarostat
    __del__ = lambda self: None
RPMDMonteCarloBarostat_swigregister = _openmm.RPMDMonteCarloBarostat_swigregister
RPMDMonteCarloBarostat_swigregister(RPMDMonteCarloBarostat)

def RPMDMonteCarloBarostat_Pressure():
    """
    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):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SerializationNode, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SerializationNode, name)

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

    def getName(self):
        """
        getName(self) -> std::string const &

        Get the name of this SerializationNode.
        """
        return _openmm.SerializationNode_getName(self)


    def setName(self, name):
        """
        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):
        """
        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):
        """
        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):
        """
        getProperties(self) -> mapstringstring

        Get a map containing all of this node's properties.
        """
        return _openmm.SerializationNode_getProperties(self)


    def hasProperty(self, name):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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
    __del__ = lambda self: None
SerializationNode_swigregister = _openmm.SerializationNode_swigregister
SerializationNode_swigregister(SerializationNode)

class SerializationProxy(_object):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SerializationProxy, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SerializationProxy, name)

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

    def registerProxy(type, proxy):
        """
        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)

    if _newclass:
        registerProxy = staticmethod(registerProxy)
    __swig_getmethods__["registerProxy"] = lambda x: registerProxy

    def getProxy(*args):
        """
        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)

    if _newclass:
        getProxy = staticmethod(getProxy)
    __swig_getmethods__["getProxy"] = lambda x: getProxy

    def getTypeName(self):
        """
        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):
        """
        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):
        """
        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)

SerializationProxy_swigregister = _openmm.SerializationProxy_swigregister
SerializationProxy_swigregister(SerializationProxy)

def SerializationProxy_registerProxy(type, proxy):
    """
    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):
    """
    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 System(_object):
    """
    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.
    """
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, System, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, System, name)
    __repr__ = _swig_repr
    __swig_destroy__ = _openmm.delete_System
    __del__ = lambda self: None

    def getNumParticles(self):
        """
        getNumParticles(self) -> int

        Get the number of particles in this System.
        """
        return _openmm.System_getNumParticles(self)


    def addParticle(self, mass):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        getNumConstraints(self) -> int

        Get the number of distance constraints in this System.
        """
        return _openmm.System_getNumConstraints(self)


    def addConstraint(self, particle1, particle2, distance):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """__copy__(self) -> System"""
        return _openmm.System___copy__(self)


    def __init__(self, *args):
        """
        __init__(self) -> System
        __init__(self, other) -> System

        Create a new System.
        """
        this = _openmm.new_System(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
System_swigregister = _openmm.System_swigregister
System_swigregister(System)

class ThreeParticleAverageSite(VirtualSite):
    """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."""
    __swig_setmethods__ = {}
    for _s in [VirtualSite]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, ThreeParticleAverageSite, name, value)
    __swig_getmethods__ = {}
    for _s in [VirtualSite]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, ThreeParticleAverageSite, name)
    __repr__ = _swig_repr

    def getWeight(self, particle):
        """
        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):
        """
        __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
        weight2 : double
            the weight factor (between 0 and 1) for the third particle
        """
        this = _openmm.new_ThreeParticleAverageSite(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_ThreeParticleAverageSite
    __del__ = lambda self: None
ThreeParticleAverageSite_swigregister = _openmm.ThreeParticleAverageSite_swigregister
ThreeParticleAverageSite_swigregister(ThreeParticleAverageSite)

class TwoParticleAverageSite(VirtualSite):
    """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."""
    __swig_setmethods__ = {}
    for _s in [VirtualSite]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, TwoParticleAverageSite, name, value)
    __swig_getmethods__ = {}
    for _s in [VirtualSite]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, TwoParticleAverageSite, name)
    __repr__ = _swig_repr

    def getWeight(self, particle):
        """
        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):
        """
        __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
        """
        this = _openmm.new_TwoParticleAverageSite(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_TwoParticleAverageSite
    __del__ = lambda self: None
TwoParticleAverageSite_swigregister = _openmm.TwoParticleAverageSite_swigregister
TwoParticleAverageSite_swigregister(TwoParticleAverageSite)

class VariableLangevinIntegrator(Integrator):
    """
    This is an error contolled, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, VariableLangevinIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, VariableLangevinIntegrator, name)
    __repr__ = _swig_repr

    def getTemperature(self):
        """
        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):
        """
        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):
        """
        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):
        """
        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):
        """
        getErrorTolerance(self) -> double

        Get the error tolerance.
        """
        return _openmm.VariableLangevinIntegrator_getErrorTolerance(self)


    def setErrorTolerance(self, tol):
        """
        setErrorTolerance(self, tol)

        Set the error tolerance.
        """
        return _openmm.VariableLangevinIntegrator_setErrorTolerance(self, tol)


    def getRandomNumberSeed(self):
        """
        getRandomNumberSeed(self) -> int

        Get the random number seed. See setRandomNumberSeed() for details.
        """
        return _openmm.VariableLangevinIntegrator_getRandomNumberSeed(self)


    def setRandomNumberSeed(self, seed):
        """
        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):
        """
        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):
        """
        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):
        """
        __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
        """
        this = _openmm.new_VariableLangevinIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_VariableLangevinIntegrator
    __del__ = lambda self: None
VariableLangevinIntegrator_swigregister = _openmm.VariableLangevinIntegrator_swigregister
VariableLangevinIntegrator_swigregister(VariableLangevinIntegrator)

class VariableVerletIntegrator(Integrator):
    """
    This is an error contolled, 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.
    """
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, VariableVerletIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, VariableVerletIntegrator, name)
    __repr__ = _swig_repr

    def getErrorTolerance(self):
        """
        getErrorTolerance(self) -> double

        Get the error tolerance.
        """
        return _openmm.VariableVerletIntegrator_getErrorTolerance(self)


    def setErrorTolerance(self, tol):
        """
        setErrorTolerance(self, tol)

        Set the error tolerance.
        """
        return _openmm.VariableVerletIntegrator_setErrorTolerance(self, tol)


    def step(self, steps):
        """
        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):
        """
        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):
        """
        __init__(self, errorTol) -> VariableVerletIntegrator
        __init__(self, other) -> VariableVerletIntegrator

        Create a VariableVerletIntegrator.

        Parameters
        ----------
        errorTol : double
            the error tolerance
        """
        this = _openmm.new_VariableVerletIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_VariableVerletIntegrator
    __del__ = lambda self: None
VariableVerletIntegrator_swigregister = _openmm.VariableVerletIntegrator_swigregister
VariableVerletIntegrator_swigregister(VariableVerletIntegrator)

class VerletIntegrator(Integrator):
    """This is an Integrator which simulates a System using the leap-frog Verlet algorithm."""
    __swig_setmethods__ = {}
    for _s in [Integrator]:
        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
    __setattr__ = lambda self, name, value: _swig_setattr(self, VerletIntegrator, name, value)
    __swig_getmethods__ = {}
    for _s in [Integrator]:
        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
    __getattr__ = lambda self, name: _swig_getattr(self, VerletIntegrator, name)
    __repr__ = _swig_repr

    def step(self, steps):
        """
        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):
        """
        __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)
        """
        this = _openmm.new_VerletIntegrator(*args)
        try:
            self.this.append(this)
        except:
            self.this = this
    __swig_destroy__ = _openmm.delete_VerletIntegrator
    __del__ = lambda self: None
VerletIntegrator_swigregister = _openmm.VerletIntegrator_swigregister
VerletIntegrator_swigregister(VerletIntegrator)

class XmlSerializer(_object):
    """XmlSerializer is used for serializing objects as XML, and for reconstructing them again."""
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, XmlSerializer, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, XmlSerializer, name)

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

    def serializeSystem(object):
        """
        serializeSystem(object) -> std::string

        This method exists only for backward compatibility. @deprecated Use serialize() instead.
        """
        return _openmm.XmlSerializer_serializeSystem(object)

    if _newclass:
        serializeSystem = staticmethod(serializeSystem)
    __swig_getmethods__["serializeSystem"] = lambda x: serializeSystem

    def deserializeSystem(inputString):
        """
        deserializeSystem(inputString) -> System

        This method exists only for backward compatibility. @deprecated Use deserialize() instead.
        """
        return _openmm.XmlSerializer_deserializeSystem(inputString)

    if _newclass:
        deserializeSystem = staticmethod(deserializeSystem)
    __swig_getmethods__["deserializeSystem"] = lambda x: deserializeSystem

    def _serializeForce(object):
        """_serializeForce(object) -> std::string"""
        return _openmm.XmlSerializer__serializeForce(object)

    if _newclass:
        _serializeForce = staticmethod(_serializeForce)
    __swig_getmethods__["_serializeForce"] = lambda x: _serializeForce

    def _deserializeForce(inputString):
        """_deserializeForce(inputString) -> Force"""
        return _openmm.XmlSerializer__deserializeForce(inputString)

    if _newclass:
        _deserializeForce = staticmethod(_deserializeForce)
    __swig_getmethods__["_deserializeForce"] = lambda x: _deserializeForce

    def _serializeIntegrator(object):
        """_serializeIntegrator(object) -> std::string"""
        return _openmm.XmlSerializer__serializeIntegrator(object)

    if _newclass:
        _serializeIntegrator = staticmethod(_serializeIntegrator)
    __swig_getmethods__["_serializeIntegrator"] = lambda x: _serializeIntegrator

    def _deserializeIntegrator(inputString):
        """_deserializeIntegrator(inputString) -> Integrator"""
        return _openmm.XmlSerializer__deserializeIntegrator(inputString)

    if _newclass:
        _deserializeIntegrator = staticmethod(_deserializeIntegrator)
    __swig_getmethods__["_deserializeIntegrator"] = lambda x: _deserializeIntegrator

    def _serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types):
        """_serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types) -> std::string"""
        return _openmm.XmlSerializer__serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types)

    if _newclass:
        _serializeStateAsLists = staticmethod(_serializeStateAsLists)
    __swig_getmethods__["_serializeStateAsLists"] = lambda x: _serializeStateAsLists

    def _deserializeStringIntoLists(stateAsString):
        """_deserializeStringIntoLists(stateAsString) -> PyObject *"""
        return _openmm.XmlSerializer__deserializeStringIntoLists(stateAsString)

    if _newclass:
        _deserializeStringIntoLists = staticmethod(_deserializeStringIntoLists)
    __swig_getmethods__["_deserializeStringIntoLists"] = lambda x: _deserializeStringIntoLists

    @staticmethod
    def _serializeState(pythonState):
      positions = []
      velocities = []
      forces = []
      kineticEnergy = 0.0
      potentialEnergy = 0.0
      params = {}
      types = 0
      try:
        positions = pythonState.getPositions().value_in_unit(unit.nanometers)
        types |= 1
      except:
        pass
      try:
        velocities = pythonState.getVelocities().value_in_unit(unit.nanometers/unit.picoseconds)
        types |= 2
      except:
        pass
      try:
        forces = pythonState.getForces().value_in_unit(unit.kilojoules_per_mole/unit.nanometers)
        types |= 4
      except:
        pass
      try:
        kineticEnergy = pythonState.getKineticEnergy().value_in_unit(unit.kilojoules_per_mole)
        potentialEnergy = pythonState.getPotentialEnergy().value_in_unit(unit.kilojoules_per_mole)
        types |= 8
      except:
        pass
      try:
        params = pythonState.getParameters()
        types |= 16
      except:
        pass
      time = pythonState.getTime().value_in_unit(unit.picoseconds)
      boxVectors = pythonState.getPeriodicBoxVectors().value_in_unit(unit.nanometers)
      string = XmlSerializer._serializeStateAsLists(positions, velocities, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types)
      return string

    @staticmethod
    def _deserializeState(pythonString):

      (simTime, periodicBoxVectorsList, energy, coordList, velList,
       forceList, paramMap) = XmlSerializer._deserializeStringIntoLists(pythonString)

      state = State(simTime=simTime,
                    energy=energy,
                    coordList=coordList,
                    velList=velList,
                    forceList=forceList,
                    periodicBoxVectorsList=periodicBoxVectorsList,
                    paramMap=paramMap)
      return state

    @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)
      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)
      raise ValueError("Unsupported object type")

    __swig_destroy__ = _openmm.delete_XmlSerializer
    __del__ = lambda self: None
XmlSerializer_swigregister = _openmm.XmlSerializer_swigregister
XmlSerializer_swigregister(XmlSerializer)

def XmlSerializer_serializeSystem(object):
    """
    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):
    """
    XmlSerializer_deserializeSystem(inputString) -> System

    This method exists only for backward compatibility. @deprecated Use deserialize() instead.
    """
    return _openmm.XmlSerializer_deserializeSystem(inputString)

def XmlSerializer__serializeForce(object):
    """XmlSerializer__serializeForce(object) -> std::string"""
    return _openmm.XmlSerializer__serializeForce(object)

def XmlSerializer__deserializeForce(inputString):
    """XmlSerializer__deserializeForce(inputString) -> Force"""
    return _openmm.XmlSerializer__deserializeForce(inputString)

def XmlSerializer__serializeIntegrator(object):
    """XmlSerializer__serializeIntegrator(object) -> std::string"""
    return _openmm.XmlSerializer__serializeIntegrator(object)

def XmlSerializer__deserializeIntegrator(inputString):
    """XmlSerializer__deserializeIntegrator(inputString) -> Integrator"""
    return _openmm.XmlSerializer__deserializeIntegrator(inputString)

def XmlSerializer__serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types):
    """XmlSerializer__serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types) -> std::string"""
    return _openmm.XmlSerializer__serializeStateAsLists(pos, vel, forces, kineticEnergy, potentialEnergy, time, boxVectors, params, types)

def XmlSerializer__deserializeStringIntoLists(stateAsString):
    """XmlSerializer__deserializeStringIntoLists(stateAsString) -> PyObject *"""
    return _openmm.XmlSerializer__deserializeStringIntoLists(stateAsString)


  # 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('_'))]

# This file is compatible with both classic and new-style classes.


