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)
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
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
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)
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)
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)
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);
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);
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)
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)
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)
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)
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)
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)