示例#1
0
    def set_kernel(self, func, kmin, kmax, width, coeff=dict()):
        """Set the table to be used for the convolution kernel.

        :param func:
            The function the returns the convolution kernel and its derivative
        :param kmin:
            Minimum k
        :param kmax:
            Maximum k
        :param width:
            Number of interpolation points
        :param coeff:
            Additional parameters to the function, as a dict (optional)
        """
        # allocate arrays to store kernel and derivative
        Ktable = _hoomd.std_vector_scalar()
        dKtable = _hoomd.std_vector_scalar()

        # calculate dr
        dk = (kmax - kmin) / float(width - 1)

        # evaluate the function
        for i in range(0, width):
            k = kmin + dk * i
            (K, dK) = func(k, kmin, kmax, **coeff)

            Ktable.append(K)
            dKtable.append(dK)

        # pass table to C++ collective variable
        self.cpp_force.setTable(Ktable, dKtable, kmin, kmax)
示例#2
0
    def set_kernel(self, func, kmin, kmax, width, coeff=dict()):
        """Set the table to be used for the convolution kernel.

        :param func:
            The function the returns the convolution kernel and its derivative
        :param kmin:
            Minimum k
        :param kmax:
            Maximum k
        :param width:
            Number of interpolation points
        :param coeff:
            Additional parameters to the function, as a dict (optional)
        """
        # allocate arrays to store kernel and derivative
        Ktable = _hoomd.std_vector_scalar()
        dKtable = _hoomd.std_vector_scalar()

        # calculate dr
        dk = (kmax - kmin) / float(width - 1)

        # evaluate the function
        for i in range(0, width):
            k = kmin + dk * i
            (K, dK) = func(k, kmin, kmax, **coeff)

            Ktable.append(K)
            dKtable.append(dK)

        # pass table to C++ collective variable
        self.cpp_force.setTable(Ktable, dKtable, kmin, kmax)
示例#3
0
    def _make_cpp_decomposition(self, box):
        # if the box is uniform in all directions, just use these values
        if self.uniform_x and self.uniform_y and self.uniform_z:
            self.cpp_dd = _hoomd.DomainDecomposition(hoomd.context.current.device.cpp_exec_conf, box.getL(), self.nx, self.ny, self.nz, not self._onelevel)
            return self.cpp_dd

        # otherwise, make the fractional decomposition
        try:
            fxs = _hoomd.std_vector_scalar()
            fys = _hoomd.std_vector_scalar()
            fzs = _hoomd.std_vector_scalar()

            # if uniform, correct the fractions to be uniform as well
            if self.uniform_x and self.nx > 0:
                self.x = [1.0/self.nx]*(self.nx-1)
            if self.uniform_y and self.ny > 0:
                self.y = [1.0/self.ny]*(self.ny-1)
            if self.uniform_z and self.nz > 0:
                self.z = [1.0/self.nz]*(self.nz-1)

            sum_x = sum_y = sum_z = 0.0
            tol = 1.0e-5
            for i in self.x:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fxs.append(i)
                sum_x += i
            if sum_x >= 1.0 - tol or sum_x <= -tol:
                hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in x must lie between 0.0 and 1.0")

            for i in self.y:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fys.append(i)
                sum_y += i
            if sum_y >= 1.0 - tol or sum_y <= -tol:
                hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in y must lie between 0.0 and 1.0")

            for i in self.z:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fzs.append(i)
                sum_z += i
            if sum_z >= 1.0 - tol or sum_z <= -tol:
                hoomd.context.current.device.cpp_msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in z must lie between 0.0 and 1.0")

            self.cpp_dd = _hoomd.DomainDecomposition(hoomd.context.current.device.cpp_exec_conf, box.getL(), fxs, fys, fzs)
            return self.cpp_dd

        except TypeError as te:
            hoomd.context.current.device.cpp_msg.error("Fractional cuts must be iterable (list, tuple, etc.)\n")
            raise te
示例#4
0
文件: comm.py 项目: kolbt/hoomd-blue
    def _make_cpp_decomposition(self, box):
        # if the box is uniform in all directions, just use these values
        if self.uniform_x and self.uniform_y and self.uniform_z:
            self.cpp_dd = _hoomd.DomainDecomposition(hoomd.context.exec_conf, box.getL(), self.nx, self.ny, self.nz, not hoomd.context.options.onelevel)
            return self.cpp_dd

        # otherwise, make the fractional decomposition
        try:
            fxs = _hoomd.std_vector_scalar()
            fys = _hoomd.std_vector_scalar()
            fzs = _hoomd.std_vector_scalar()

            # if uniform, correct the fractions to be uniform as well
            if self.uniform_x and self.nx > 0:
                self.x = [1.0/self.nx]*(self.nx-1)
            if self.uniform_y and self.ny > 0:
                self.y = [1.0/self.ny]*(self.ny-1)
            if self.uniform_z and self.nz > 0:
                self.z = [1.0/self.nz]*(self.nz-1)

            sum_x = sum_y = sum_z = 0.0
            tol = 1.0e-5
            for i in self.x:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fxs.append(i)
                sum_x += i
            if sum_x >= 1.0 - tol or sum_x <= -tol:
                hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in x must lie between 0.0 and 1.0")

            for i in self.y:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fys.append(i)
                sum_y += i
            if sum_y >= 1.0 - tol or sum_y <= -tol:
                hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in y must lie between 0.0 and 1.0")

            for i in self.z:
                if i <= -tol or i >= 1.0 - tol:
                    hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                    raise RuntimeError("Fractional decomposition must be between 0.0 and 1.0")
                fzs.append(i)
                sum_z += i
            if sum_z >= 1.0 - tol or sum_z <= -tol:
                hoomd.context.msg.error("comm.decomposition: fraction must be between 0.0 and 1.0\n")
                raise RuntimeError("Sum of decomposition in z must lie between 0.0 and 1.0")

            self.cpp_dd = _hoomd.DomainDecomposition(hoomd.context.exec_conf, box.getL(), fxs, fys, fzs)
            return self.cpp_dd

        except TypeError as te:
            hoomd.context.msg.error("Fractional cuts must be iterable (list, tuple, etc.)\n")
            raise te
示例#5
0
    def __init__(self, r_cut, r_on, lmax, Ql_ref, nlist, type, name=None, sigma=1.0):
        hoomd.util.print_status_line()

        suffix = ""
        if name is not None:
            suffix = "_" + name

        _collective_variable.__init__(self, sigma, name)

        self.type = type

        # subscribe to neighbor list rcut
        self.nlist = nlist
        self.r_cut = r_cut
        self.nlist.subscribe(lambda: self.get_rcut())
        self.nlist.update_rcut()

        if hoomd.context.exec_conf.isCUDAEnabled():
            self.nlist.cpp_nlist.setStorageMode(_md.NeighborList.storageMode.full)

        type_list = []
        for i in range(0, hoomd.context.current.system_definition.getParticleData().getNTypes()):
            type_list.append(hoomd.context.current.system_definition.getParticleData().getNameByType(i))

        if type not in type_list:
            hoomd.context.msg.error("cv.steinhardt: Invalid particle type.")
            raise RuntimeError('Error creating collective variable.')

        cpp_Ql_ref = _hoomd.std_vector_scalar()
        for Ql in list(Ql_ref):
            cpp_Ql_ref.append(Ql)

        self.cpp_force = _metadynamics.SteinhardtQl(hoomd.context.current.system_definition, float(
            r_cut), float(r_on), int(lmax), nlist.cpp_nlist, type_list.index(type), cpp_Ql_ref, suffix)
        hoomd.context.current.system.addCompute(self.cpp_force, self.force_name)
示例#6
0
    def __init__(self, mode, lattice_vectors, name=None, sigma=1.0):
        hoomd.util.print_status_line()

        if name is not None:
            name = "_" + name
            suffix = name
        else:
            suffix = ""

        _collective_variable.__init__(self, sigma, name)

        if len(lattice_vectors) == 0:
            hoomd.context.msg.error(
                "cv.lamellar: List of supplied latice vectors is empty.\n")
            raise RuntimeEror('Error creating collective variable.')

        if type(mode) != type(dict()):
            hoomd.context.msg.error(
                "cv.lamellar: Mode amplitudes specified incorrectly.\n")
            raise RuntimeEror('Error creating collective variable.')

        cpp_mode = _hoomd.std_vector_scalar()
        for i in range(
                0,
                hoomd.context.current.system_definition.getParticleData().
                getNTypes()):
            t = hoomd.context.current.system_definition.getParticleData(
            ).getNameByType(i)

            if t not in mode.keys():
                hoomd.context.msg.error(
                    "cv.lamellar: Missing mode amplitude for particle type " +
                    t + ".\n")
                raise RuntimeEror('Error creating collective variable.')
            cpp_mode.append(mode[t])

        cpp_lattice_vectors = _metadynamics.std_vector_int3()
        for l in lattice_vectors:
            if len(l) != 3:
                hoomd.context.msg.error(
                    "cv.lamellar: List of input lattice vectors not a list of triples.\n"
                )
                raise RuntimeError('Error creating collective variable.')
            cpp_lattice_vectors.append(hoomd.make_int3(l[0], l[1], l[2]))

        if not hoomd.context.exec_conf.isCUDAEnabled():
            self.cpp_force = _metadynamics.LamellarOrderParameter(
                hoomd.context.current.system_definition, cpp_mode,
                cpp_lattice_vectors, suffix)
        else:
            self.cpp_force = _metadynamics.LamellarOrderParameterGPU(
                hoomd.context.current.system_definition, cpp_mode,
                cpp_lattice_vectors, suffix)

        hoomd.context.current.system.addCompute(self.cpp_force,
                                                self.force_name)
示例#7
0
    def update_dihedral_table(self, atype, func, coeff):
        # allocate arrays to store V and F
        Vtable = _hoomd.std_vector_scalar()
        Ttable = _hoomd.std_vector_scalar()

        # calculate dth
        dth = 2.0 * math.pi / float(self.width - 1)

        # evaluate each point of the function
        for i in range(0, self.width):
            theta = -math.pi + dth * i
            (V, T) = func(theta, **coeff)

            # fill out the tables
            Vtable.append(V)
            Ttable.append(T)

        # pass the tables on to the underlying cpp compute
        self.cpp_force.setTable(atype, Vtable, Ttable)
示例#8
0
文件: angle.py 项目: kolbt/hoomd-blue
    def update_angle_table(self, atype, func, coeff):
        # allocate arrays to store V and F
        Vtable = _hoomd.std_vector_scalar();
        Ttable = _hoomd.std_vector_scalar();

        # calculate dth
        dth = math.pi / float(self.width-1);

        # evaluate each point of the function
        for i in range(0, self.width):
            theta = dth * i;
            (V,T) = func(theta, **coeff);

            # fill out the tables
            Vtable.append(V);
            Ttable.append(T);

        # pass the tables on to the underlying cpp compute
        self.cpp_force.setTable(atype, Vtable, Ttable);
示例#9
0
    def update_bond_table(self, btype, func, rmin, rmax, coeff):
        # allocate arrays to store V and F
        Vtable = _hoomd.std_vector_scalar();
        Ftable = _hoomd.std_vector_scalar();

        # calculate dr
        dr = (rmax - rmin) / float(self.width-1);

        # evaluate each point of the function
        for i in range(0, self.width):
            r = rmin + dr * i;
            (V,F) = func(r, rmin, rmax, **coeff);

            # fill out the tables
            Vtable.append(V);
            Ftable.append(F);

        # pass the tables on to the underlying cpp compute
        self.cpp_force.setTable(btype, Vtable, Ftable, rmin, rmax);
示例#10
0
    def __init__(self,
                 r_cut,
                 r_on,
                 lmax,
                 Ql_ref,
                 nlist,
                 type,
                 name=None,
                 sigma=1.0):
        hoomd.util.print_status_line()

        suffix = ""
        if name is not None:
            suffix = "_" + name

        _collective_variable.__init__(self, sigma, name)

        self.type = type

        # subscribe to neighbor list rcut
        self.nlist = nlist
        self.r_cut = r_cut
        self.nlist.subscribe(lambda: self.get_rcut())
        self.nlist.update_rcut()

        if hoomd.context.exec_conf.isCUDAEnabled():
            self.nlist.cpp_nlist.setStorageMode(
                _md.NeighborList.storageMode.full)

        type_list = []
        for i in range(
                0,
                hoomd.context.current.system_definition.getParticleData().
                getNTypes()):
            type_list.append(hoomd.context.current.system_definition.
                             getParticleData().getNameByType(i))

        if type not in type_list:
            hoomd.context.msg.error("cv.steinhardt: Invalid particle type.")
            raise RuntimeError('Error creating collective variable.')

        cpp_Ql_ref = _hoomd.std_vector_scalar()
        for Ql in list(Ql_ref):
            cpp_Ql_ref.append(Ql)

        self.cpp_force = _metadynamics.SteinhardtQl(
            hoomd.context.current.system_definition, float(r_cut), float(r_on),
            int(lmax), nlist.cpp_nlist, type_list.index(type), cpp_Ql_ref,
            suffix)
        hoomd.context.current.system.addCompute(self.cpp_force,
                                                self.force_name)
示例#11
0
    def __init__(self, mode, nx, ny=None, nz=None, name=None, sigma=1.0, zero_modes=None):
        hoomd.util.print_status_line()

        if name is not None:
            name = "_" + name
            suffix = name
        else:
            suffix = ""

        if ny is None:
            ny = nx

        if nz is None:
            nz = nx

        _collective_variable.__init__(self, sigma, name)

        if type(mode) != type(dict()):
            hoomd.context.msg.error("cv.mesh: Mode amplitudes specified incorrectly.\n")
            raise RuntimeEror('Error creating collective variable.')

        cpp_mode = _hoomd.std_vector_scalar()
        for i in range(0, hoomd.context.current.system_definition.getParticleData().getNTypes()):
            t = hoomd.context.current.system_definition.getParticleData().getNameByType(i)

            if t not in mode.keys():
                hoomd.context.msg.error("cv.mesh: Missing mode amplitude for particle type " + t + ".\n")
                raise RuntimeEror('Error creating collective variable.')
            cpp_mode.append(mode[t])

        cpp_zero_modes = _metadynamics.std_vector_int3()
        if zero_modes is not None:
            for l in zero_modes:
                if len(l) != 3:
                    hoomd.context.msg.error("cv.lamellar: List of modes to zero not a list of triples.\n")
                    raise RuntimeError('Error creating collective variable.')
                cpp_zero_modes.append(hoomd.make_int3(l[0], l[1], l[2]))

        if not hoomd.context.exec_conf.isCUDAEnabled():
            self.cpp_force = _metadynamics.OrderParameterMesh(
                hoomd.context.current.system_definition, nx, ny, nz, cpp_mode, cpp_zero_modes)
        else:
            self.cpp_force = _metadynamics.OrderParameterMeshGPU(
                hoomd.context.current.system_definition, nx, ny, nz, cpp_mode, cpp_zero_modes)

        hoomd.context.current.system.addCompute(self.cpp_force, self.force_name)
示例#12
0
    def __init__(self, mode, lattice_vectors, name=None, sigma=1.0):
        hoomd.util.print_status_line()

        if name is not None:
            name = "_" + name
            suffix = name
        else:
            suffix = ""

        _collective_variable.__init__(self, sigma, name)

        if len(lattice_vectors) == 0:
            hoomd.context.msg.error("cv.lamellar: List of supplied latice vectors is empty.\n")
            raise RuntimeEror('Error creating collective variable.')

        if type(mode) != type(dict()):
            hoomd.context.msg.error("cv.lamellar: Mode amplitudes specified incorrectly.\n")
            raise RuntimeEror('Error creating collective variable.')

        cpp_mode = _hoomd.std_vector_scalar()
        for i in range(0, hoomd.context.current.system_definition.getParticleData().getNTypes()):
            t = hoomd.context.current.system_definition.getParticleData().getNameByType(i)

            if t not in mode.keys():
                hoomd.context.msg.error("cv.lamellar: Missing mode amplitude for particle type " + t + ".\n")
                raise RuntimeEror('Error creating collective variable.')
            cpp_mode.append(mode[t])

        cpp_lattice_vectors = _metadynamics.std_vector_int3()
        for l in lattice_vectors:
            if len(l) != 3:
                hoomd.context.msg.error("cv.lamellar: List of input lattice vectors not a list of triples.\n")
                raise RuntimeError('Error creating collective variable.')
            cpp_lattice_vectors.append(hoomd.make_int3(l[0], l[1], l[2]))

        if not hoomd.context.exec_conf.isCUDAEnabled():
            self.cpp_force = _metadynamics.LamellarOrderParameter(
                hoomd.context.current.system_definition, cpp_mode, cpp_lattice_vectors, suffix)
        else:
            self.cpp_force = _metadynamics.LamellarOrderParameterGPU(
                hoomd.context.current.system_definition, cpp_mode, cpp_lattice_vectors, suffix)

        hoomd.context.current.system.addCompute(self.cpp_force, self.force_name)
示例#13
0
    def set_param(self,
                  type_name,
                  types,
                  positions,
                  orientations=None,
                  charges=None,
                  diameters=None):
        R""" Set constituent particle types and coordinates for a rigid body.

        Args:
            type_name (str): The type of the central particle
            types (list): List of types of constituent particles
            positions (list): List of relative positions of constituent particles
            orientations (list): List of orientations of constituent particles (**optional**)
            charge (list): List of charges of constituent particles (**optional**)
            diameters (list): List of diameters of constituent particles (**optional**)

        .. caution::
            The constituent particle type must be exist.
            If it does not exist, it can be created on the fly using
            ``system.particles.types.add('A_const')`` (see :py:mod:`hoomd.data`).

        Example::

            rigid = constrain.rigd()
            rigid.set_param('A', types = ['A_const', 'A_const'], positions = [(0,0,1),(0,0,-1)])
            rigid.set_param('B', types = ['B_const', 'B_const'], positions = [(0,0,.5),(0,0,-.5)])

        """
        # get a list of types from the particle data
        ntypes = hoomd.context.current.system_definition.getParticleData(
        ).getNTypes()
        type_list = []
        for i in range(0, ntypes):
            type_list.append(hoomd.context.current.system_definition.
                             getParticleData().getNameByType(i))

        if type_name not in type_list:
            hoomd.context.msg.error('Type '
                                    '{}'
                                    ' not found.\n'.format(type_name))
            raise RuntimeError(
                'Error setting up parameters for constrain.rigid()')

        type_id = type_list.index(type_name)

        if not isinstance(types, list):
            hoomd.context.msg.error('Expecting list of particle types.\n')
            raise RuntimeError(
                'Error setting up parameters for constrain.rigid()')

        type_vec = _hoomd.std_vector_uint()
        for t in types:
            if t not in type_list:
                hoomd.context.msg.error('Type ' '{}' ' not found.\n'.format(t))
                raise RuntimeError(
                    'Error setting up parameters for constrain.rigid()')
            constituent_type_id = type_list.index(t)

            type_vec.append(constituent_type_id)

        pos_vec = _hoomd.std_vector_scalar3()
        positions_list = list(positions)
        for p in positions_list:
            p = tuple(p)
            if len(p) != 3:
                hoomd.context.msg.error(
                    'Particle position is not a coordinate triple.\n')
                raise RuntimeError(
                    'Error setting up parameters for constrain.rigid()')
            pos_vec.append(_hoomd.make_scalar3(p[0], p[1], p[2]))

        orientation_vec = _hoomd.std_vector_scalar4()
        if orientations is not None:
            orientations_list = list(orientations)
            for o in orientations_list:
                o = tuple(o)
                if len(o) != 4:
                    hoomd.context.msg.error(
                        'Particle orientation is not a 4-tuple.\n')
                    raise RuntimeError(
                        'Error setting up parameters for constrain.rigid()')
                orientation_vec.append(
                    _hoomd.make_scalar4(o[0], o[1], o[2], o[3]))
        else:
            for p in positions:
                orientation_vec.append(_hoomd.make_scalar4(1, 0, 0, 0))

        charge_vec = _hoomd.std_vector_scalar()
        if charges is not None:
            charges_list = list(charges)
            for c in charges_list:
                charge_vec.append(float(c))
        else:
            for p in positions:
                charge_vec.append(0.0)

        diameter_vec = _hoomd.std_vector_scalar()
        if diameters is not None:
            diameters_list = list(diameters)
            for d in diameters_list:
                diameter_vec.append(float(d))
        else:
            for p in positions:
                diameter_vec.append(1.0)

        # set parameters in C++ force
        self.cpp_force.setParam(type_id, type_vec, pos_vec, orientation_vec,
                                charge_vec, diameter_vec)
示例#14
0
    def __init__(self,
                 mode,
                 nx,
                 ny=None,
                 nz=None,
                 name=None,
                 sigma=1.0,
                 zero_modes=None):
        hoomd.util.print_status_line()

        if name is not None:
            name = "_" + name
            suffix = name
        else:
            suffix = ""

        if ny is None:
            ny = nx

        if nz is None:
            nz = nx

        _collective_variable.__init__(self, sigma, name)

        if type(mode) != type(dict()):
            hoomd.context.msg.error(
                "cv.mesh: Mode amplitudes specified incorrectly.\n")
            raise RuntimeEror('Error creating collective variable.')

        cpp_mode = _hoomd.std_vector_scalar()
        for i in range(
                0,
                hoomd.context.current.system_definition.getParticleData().
                getNTypes()):
            t = hoomd.context.current.system_definition.getParticleData(
            ).getNameByType(i)

            if t not in mode.keys():
                hoomd.context.msg.error(
                    "cv.mesh: Missing mode amplitude for particle type " + t +
                    ".\n")
                raise RuntimeEror('Error creating collective variable.')
            cpp_mode.append(mode[t])

        cpp_zero_modes = _metadynamics.std_vector_int3()
        if zero_modes is not None:
            for l in zero_modes:
                if len(l) != 3:
                    hoomd.context.msg.error(
                        "cv.lamellar: List of modes to zero not a list of triples.\n"
                    )
                    raise RuntimeError('Error creating collective variable.')
                cpp_zero_modes.append(hoomd.make_int3(l[0], l[1], l[2]))

        if not hoomd.context.exec_conf.isCUDAEnabled():
            self.cpp_force = _metadynamics.OrderParameterMesh(
                hoomd.context.current.system_definition, nx, ny, nz, cpp_mode,
                cpp_zero_modes)
        else:
            self.cpp_force = _metadynamics.OrderParameterMeshGPU(
                hoomd.context.current.system_definition, nx, ny, nz, cpp_mode,
                cpp_zero_modes)

        hoomd.context.current.system.addCompute(self.cpp_force,
                                                self.force_name)
示例#15
0
    def set_param(self,type_name, types, positions, orientations=None, charges=None, diameters=None):
        R""" Set constituent particle types and coordinates for a rigid body.

        Args:
            type_name (str): The type of the central particle
            types (list): List of types of constituent particles
            positions (list): List of relative positions of constituent particles
            orientations (list): List of orientations of constituent particles (**optional**)
            charge (list): List of charges of constituent particles (**optional**)
            diameters (list): List of diameters of constituent particles (**optional**)

        .. caution::
            The constituent particle type must be exist.
            If it does not exist, it can be created on the fly using
            ``system.particles.types.add('A_const')`` (see :py:mod:`hoomd.data`).

        Example::

            rigid = constrain.rigd()
            rigid.set_param('A', types = ['A_const', 'A_const'], positions = [(0,0,1),(0,0,-1)])
            rigid.set_param('B', types = ['B_const', 'B_const'], positions = [(0,0,.5),(0,0,-.5)])

        """
        # get a list of types from the particle data
        ntypes = hoomd.context.current.system_definition.getParticleData().getNTypes();
        type_list = [];
        for i in range(0,ntypes):
            type_list.append(hoomd.context.current.system_definition.getParticleData().getNameByType(i));

        if type_name not in type_list:
            hoomd.context.msg.error('Type ''{}'' not found.\n'.format(type_name))
            raise RuntimeError('Error setting up parameters for constrain.rigid()')

        type_id = type_list.index(type_name)

        if not isinstance(types, list):
            hoomd.context.msg.error('Expecting list of particle types.\n')
            raise RuntimeError('Error setting up parameters for constrain.rigid()')

        type_vec = _hoomd.std_vector_uint()
        for t in types:
            if t not in type_list:
                hoomd.context.msg.error('Type ''{}'' not found.\n'.format(t))
                raise RuntimeError('Error setting up parameters for constrain.rigid()')
            constituent_type_id = type_list.index(t)

            type_vec.append(constituent_type_id)

        pos_vec = _hoomd.std_vector_scalar3()
        positions_list = list(positions)
        for p in positions_list:
            p = tuple(p)
            if len(p) != 3:
                hoomd.context.msg.error('Particle position is not a coordinate triple.\n')
                raise RuntimeError('Error setting up parameters for constrain.rigid()')
            pos_vec.append(_hoomd.make_scalar3(p[0],p[1],p[2]))

        orientation_vec = _hoomd.std_vector_scalar4()
        if orientations is not None:
            orientations_list = list(orientations)
            for o in orientations_list:
                o = tuple(o)
                if len(o) != 4:
                    hoomd.context.msg.error('Particle orientation is not a 4-tuple.\n')
                    raise RuntimeError('Error setting up parameters for constrain.rigid()')
                orientation_vec.append(_hoomd.make_scalar4(o[0], o[1], o[2], o[3]))
        else:
            for p in positions:
                orientation_vec.append(_hoomd.make_scalar4(1,0,0,0))

        charge_vec = _hoomd.std_vector_scalar()
        if charges is not None:
            charges_list = list(charges)
            for c in charges_list:
                charge_vec.append(float(c))
        else:
            for p in positions:
                charge_vec.append(0.0)

        diameter_vec = _hoomd.std_vector_scalar()
        if diameters is not None:
            diameters_list = list(diameters)
            for d in diameters_list:
                diameter_vec.append(float(d))
        else:
            for p in positions:
                diameter_vec.append(1.0)

        # set parameters in C++ force
        self.cpp_force.setParam(type_id, type_vec, pos_vec, orientation_vec, charge_vec, diameter_vec)