def tag_list(name, tags): R""" Groups particles by tag list. Args: tags (list): List of particle tags to include in the group name (str): User-assigned name for this group. Creates a particle group from particles with the given tags. Can be used to implement advanced grouping not available with existing group commands. Examples:: a = group.tag_list(name="a", tags = [0, 12, 18, 205]) b = group.tag_list(name="b", tags = range(20,400)) """ # check if initialization has occurred if not hoomd.init.is_initialized(): raise RuntimeError('Cannot create a group before initialization\n'); # build a vector of the tags cpp_list = _hoomd.std_vector_uint(); for t in tags: cpp_list.append(t); # create the group cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, cpp_list); # notify the user of the created group hoomd.context.current.device.cpp_msg.notice(2, 'Group "' + name + '" created containing ' + str(cpp_group.getNumMembersGlobal()) + ' particles\n'); # return it in the wrapper class return group(name, cpp_group);
def type(type, name=None, update=False): R""" Groups particles by type. Args: type (str): Name of the particle type to add to the group. name (str): User-assigned name for this group. If a name is not specified, a default one will be generated. update (bool): When true, update list of group members when particles are added to or removed from the simulation. Creates a particle group from particles that match the given type. The group can then be used by other hoomd_script commands (such as analyze.msd) to specify which particles should be operated on. Note: Membership in :py:func:`hoomd.group.type()` is defined at time of group creation. Once created, any particles added to the system will be added to the group if *update* is set to *True*. However, if you change a particle type it will not be added to or removed from this group. Between runs, you can force a group to update its membership with the particles currently in the originally specified type using :py:meth:`hoomd.group.group.force_update()`. Examples:: groupA = group.type(name='a-particles', type='A') groupB = group.type(name='b-particles', type='B') groupB = group.type(name='b-particles', type='B',update=True) """ hoomd.util.print_status_line(); type = str(type); # check if initialization has occurred if not hoomd.init.is_initialized(): hoomd.context.msg.error("Cannot create a group before initialization\n"); raise RuntimeError('Error creating group'); if name is None: name = 'type ' + type; # 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 not in type_list: hoomd.context.msg.warning(str(type) + " does not exist in the system, creating an empty group\n"); cpp_list = _hoomd.std_vector_uint(); cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, cpp_list); else: type_id = hoomd.context.current.system_definition.getParticleData().getTypeByName(type); selector = _hoomd.ParticleSelectorType(hoomd.context.current.system_definition, type_id, type_id); cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, selector, update); # notify the user of the created group hoomd.context.msg.notice(2, 'Group "' + name + '" created containing ' + str(cpp_group.getNumMembersGlobal()) + ' particles\n'); # return it in the wrapper class return group(name, cpp_group);
def type(type, name=None, update=False): R""" Groups particles by type. Args: type (str): Name of the particle type to add to the group. name (str): User-assigned name for this group. If a name is not specified, a default one will be generated. update (bool): When true, update list of group members when particles are added to or removed from the simulation. Creates a particle group from particles that match the given type. The group can then be used by other hoomd commands (such as analyze.msd) to specify which particles should be operated on. Note: Membership in :py:func:`hoomd.group.type()` is defined at time of group creation. Once created, any particles added to the system will be added to the group if *update* is set to *True*. However, if you change a particle type it will not be added to or removed from this group. Between runs, you can force a group to update its membership with the particles currently in the originally specified type using :py:meth:`hoomd.group.group.force_update()`. Examples:: groupA = group.type(name='a-particles', type='A') groupB = group.type(name='b-particles', type='B') groupB = group.type(name='b-particles', type='B',update=True) """ type = str(type); # check if initialization has occurred if not hoomd.init.is_initialized(): raise RuntimeError('Cannot create a group before initialization\n'); if name is None: name = 'type ' + type; # 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 not in type_list: hoomd.context.current.device.cpp_msg.warning(str(type) + " does not exist in the system, creating an empty group\n"); cpp_list = _hoomd.std_vector_uint(); cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, cpp_list); else: type_id = hoomd.context.current.system_definition.getParticleData().getTypeByName(type); selector = _hoomd.ParticleSelectorType(hoomd.context.current.system_definition, type_id, type_id); cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, selector, update); # notify the user of the created group hoomd.context.current.device.cpp_msg.notice(2, 'Group "' + name + '" created containing ' + str(cpp_group.getNumMembersGlobal()) + ' particles\n'); # return it in the wrapper class return group(name, cpp_group);
def tag_list(name, tags): R""" Groups particles by tag list. Args: tags (list): List of particle tags to include in the group name (str): User-assigned name for this group. Creates a particle group from particles with the given tags. Can be used to implement advanced grouping not available with existing group commands. Examples:: a = group.tag_list(name="a", tags = [0, 12, 18, 205]) b = group.tag_list(name="b", tags = range(20,400)) """ hoomd.util.print_status_line(); # check if initialization has occurred if not hoomd.init.is_initialized(): hoomd.context.msg.error("Cannot create a group before initialization\n"); raise RuntimeError('Error creating group'); # build a vector of the tags cpp_list = _hoomd.std_vector_uint(); for t in tags: cpp_list.append(t); # create the group cpp_group = _hoomd.ParticleGroup(hoomd.context.current.system_definition, cpp_list); # notify the user of the created group hoomd.context.msg.notice(2, 'Group "' + name + '" created containing ' + str(cpp_group.getNumMembersGlobal()) + ' particles\n'); # return it in the wrapper class return group(name, cpp_group);
def __init__(self, mc, seed, period=1, transfer_types=None, ngibbs=1): hoomd.util.print_status_line() if not isinstance(mc, integrate.mode_hpmc): hoomd.context.msg.warning( "update.muvt: Must have a handle to an HPMC integrator.\n") return self.mc = mc # initialize base class _updater.__init__(self) if ngibbs > 1: self.gibbs = True else: self.gibbs = False # 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)) # by default, transfer all types if transfer_types is None: transfer_types = type_list cls = None if self.mc.implicit is True: if isinstance(mc, integrate.sphere): cls = _hpmc.UpdaterMuVTImplicitSphere elif isinstance(mc, integrate.convex_polygon): cls = _hpmc.UpdaterMuVTImplicitConvexPolygon elif isinstance(mc, integrate.simple_polygon): cls = _hpmc.UpdaterMuVTImplicitSimplePolygon elif isinstance(mc, integrate.convex_polyhedron): cls = integrate._get_sized_entry( 'UpdaterMuVTImplicitConvexPolyhedron', mc.max_verts) elif isinstance(mc, integrate.convex_spheropolyhedron): cls = integrate._get_sized_entry( 'UpdaterMuVTImplicitSpheropolyhedron', mc.max_verts) elif isinstance(mc, integrate.ellipsoid): cls = _hpmc.UpdaterMuVTImplicitEllipsoid elif isinstance(mc, integrate.convex_spheropolygon): cls = _hpmc.UpdaterMuVTImplicitSpheropolygon elif isinstance(mc, integrate.faceted_sphere): cls = _hpmc.UpdaterMuVTImplicitFacetedSphere elif isinstance(mc, integrate.sphere_union): cls = integrate._get_sized_entry( 'UpdaterMuVTImplicitSphereUnion', mc.max_members) elif isinstance(mc, integrate.polyhedron): cls = _hpmc.UpdaterMuVTImplicitPolyhedron else: hoomd.context.msg.error( "update.muvt: Unsupported integrator.\n") raise RuntimeError("Error initializing update.muvt") else: if isinstance(mc, integrate.sphere): cls = _hpmc.UpdaterMuVTSphere elif isinstance(mc, integrate.convex_polygon): cls = _hpmc.UpdaterMuVTConvexPolygon elif isinstance(mc, integrate.simple_polygon): cls = _hpmc.UpdaterMuVTSimplePolygon elif isinstance(mc, integrate.convex_polyhedron): cls = integrate._get_sized_entry('UpdaterMuVTConvexPolyhedron', mc.max_verts) elif isinstance(mc, integrate.convex_spheropolyhedron): cls = integrate._get_sized_entry('UpdaterMuVTSpheropolyhedron', mc.max_verts) elif isinstance(mc, integrate.ellipsoid): cls = _hpmc.UpdaterMuVTEllipsoid elif isinstance(mc, integrate.convex_spheropolygon): cls = _hpmc.UpdaterMuVTSpheropolygon elif isinstance(mc, integrate.faceted_sphere): cls = _hpmc.UpdaterMuVTFacetedSphere elif isinstance(mc, integrate.sphere_union): cls = integrate._get_sized_entry('UpdaterMuVTSphereUnion', mc.max_members) elif isinstance(mc, integrate.polyhedron): cls = _hpmc.UpdaterMuVTPolyhedron else: hoomd.context.msg.error( "update.muvt: Unsupported integrator.\n") raise RuntimeError("Error initializing update.muvt") if self.mc.implicit: self.cpp_updater = cls(hoomd.context.current.system_definition, mc.cpp_integrator, int(seed), ngibbs) else: self.cpp_updater = cls(hoomd.context.current.system_definition, mc.cpp_integrator, int(seed), ngibbs) # register the muvt updater self.setupUpdater(period) # set the list of transfered types if not isinstance(transfer_types, list): hoomd.context.msg.error( "update.muvt: Need list of types to transfer.\n") raise RuntimeError("Error initializing update.muvt") cpp_transfer_types = _hoomd.std_vector_uint() for t in transfer_types: if t not in type_list: hoomd.context.msg.error("Trying to transfer unknown type " + str(t) + "\n") raise RuntimeError("Error setting muVT parameters") else: type_id = hoomd.context.current.system_definition.getParticleData( ).getTypeByName(t) cpp_transfer_types.append(type_id) self.cpp_updater.setTransferTypes(cpp_transfer_types)
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, mc, seed, period=1, transfer_types=None,ngibbs=1): hoomd.util.print_status_line(); if not isinstance(mc, integrate.mode_hpmc): hoomd.context.msg.warning("update.muvt: Must have a handle to an HPMC integrator.\n"); return; self.mc = mc # initialize base class _updater.__init__(self); if ngibbs > 1: self.gibbs = True; else: self.gibbs = False; # 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)); # by default, transfer all types if transfer_types is None: transfer_types = type_list cls = None; if self.mc.implicit is True: if isinstance(mc, integrate.sphere): cls = _hpmc.UpdaterMuVTImplicitSphere; elif isinstance(mc, integrate.convex_polygon): cls = _hpmc.UpdaterMuVTImplicitConvexPolygon; elif isinstance(mc, integrate.simple_polygon): cls = _hpmc.UpdaterMuVTImplicitSimplePolygon; elif isinstance(mc, integrate.convex_polyhedron): cls = _hpmc.UpdaterMuVTImplicitConvexPolyhedron; elif isinstance(mc, integrate.convex_spheropolyhedron): cls = _hpmc.UpdaterMuVTImplicitSpheropolyhedron; elif isinstance(mc, integrate.ellipsoid): cls = _hpmc.UpdaterMuVTImplicitEllipsoid; elif isinstance(mc, integrate.convex_spheropolygon): cls =_hpmc.UpdaterMuVTImplicitSpheropolygon; elif isinstance(mc, integrate.faceted_sphere): cls =_hpmc.UpdaterMuVTImplicitFacetedSphere; elif isinstance(mc, integrate.sphere_union): cls = integrate._get_sized_entry('UpdaterMuVTImplicitSphereUnion', mc.capacity); elif isinstance(mc, integrate.polyhedron): cls =_hpmc.UpdaterMuVTImplicitPolyhedron; else: hoomd.context.msg.error("update.muvt: Unsupported integrator.\n"); raise RuntimeError("Error initializing update.muvt"); else: if isinstance(mc, integrate.sphere): cls = _hpmc.UpdaterMuVTSphere; elif isinstance(mc, integrate.convex_polygon): cls = _hpmc.UpdaterMuVTConvexPolygon; elif isinstance(mc, integrate.simple_polygon): cls = _hpmc.UpdaterMuVTSimplePolygon; elif isinstance(mc, integrate.convex_polyhedron): cls = _hpmc.UpdaterMuVTConvexPolyhedron; elif isinstance(mc, integrate.convex_spheropolyhedron): cls = _hpmc.UpdaterMuVTSpheropolyhedron; elif isinstance(mc, integrate.ellipsoid): cls = _hpmc.UpdaterMuVTEllipsoid; elif isinstance(mc, integrate.convex_spheropolygon): cls =_hpmc.UpdaterMuVTSpheropolygon; elif isinstance(mc, integrate.faceted_sphere): cls =_hpmc.UpdaterMuVTFacetedSphere; elif isinstance(mc, integrate.sphere_union): cls = integrate._get_sized_entry('UpdaterMuVTSphereUnion', mc.capacity); elif isinstance(mc, integrate.polyhedron): cls =_hpmc.UpdaterMuVTPolyhedron; else: hoomd.context.msg.error("update.muvt: Unsupported integrator.\n"); raise RuntimeError("Error initializing update.muvt"); if self.mc.implicit: self.cpp_updater = cls(hoomd.context.current.system_definition, mc.cpp_integrator, int(seed), ngibbs); else: self.cpp_updater = cls(hoomd.context.current.system_definition, mc.cpp_integrator, int(seed), ngibbs); # register the muvt updater self.setupUpdater(period); # set the list of transfered types if not isinstance(transfer_types,list): hoomd.context.msg.error("update.muvt: Need list of types to transfer.\n"); raise RuntimeError("Error initializing update.muvt"); cpp_transfer_types = _hoomd.std_vector_uint(); for t in transfer_types: if t not in type_list: hoomd.context.msg.error("Trying to transfer unknown type " + str(t) + "\n"); raise RuntimeError("Error setting muVT parameters"); else: type_id = hoomd.context.current.system_definition.getParticleData().getTypeByName(t); cpp_transfer_types.append(type_id) self.cpp_updater.setTransferTypes(cpp_transfer_types)
def create_random(N, phi_p=None, name="A", min_dist=0.7, box=None, seed=1, dimensions=3): R""" Generates N randomly positioned particles of the same type. Args: N (int): Number of particles to create. phi_p (float): Packing fraction of particles in the simulation box (unitless). name (str): Name of the particle type to create. min_dist (float): Minimum distance particles will be separated by (in distance units). box (:py:class:`hoomd.data.boxdim`): Simulation box dimensions. seed (int): Random seed. dimensions (int): The number of dimensions in the simulation. .. deprecated:: 2.0 Random initialization is best left to specific methods tailored by the user for their work. Either *phi_p* or *box* must be specified. If *phi_p* is provided, it overrides the value of *box*. Examples:: init.create_random(N=2400, phi_p=0.20) init.create_random(N=2400, phi_p=0.40, min_dist=0.5) system = init.create_random(N=2400, box=data.boxdim(L=20)) When *phi_p* is set, the dimensions of the created box are such that the packing fraction of particles in the box is *phi_p*. The number density \e n is related to the packing fraction by :math:`n = 2d/\pi \cdot \phi_P`, where *d* is the dimension, and assumes the particles have a radius of 0.5. All particles are created with the same type, given by *name*. The result of :py:func:`hoomd.deprecated.init.create_random` can be saved in a variable and later used to read and/or change particle properties later in the script. See :py:mod:`hoomd.data` for more information. """ hoomd.util.print_status_line(); hoomd.context._verify_init(); # check if initialization has already occurred if hoomd.init.is_initialized(): hoomd.context.msg.error("Cannot initialize more than once\n"); raise RuntimeError("Error initializing"); # check that dimensions are appropriate if dimensions not in (2,3): raise ValueError('dimensions must be 2 or 3') # abuse the polymer generator to generate single particles if phi_p is not None: # calculate the box size L = math.pow(math.pi/(2.0*dimensions)*N / phi_p, 1.0/dimensions); box = hoomd.data.boxdim(L=L, dimensions=dimensions); if box is None: raise RuntimeError('box or phi_p must be specified'); if not isinstance(box, hoomd.data.boxdim): hoomd.context.msg.error('box must be a data.boxdim object'); raise TypeError('box must be a data.boxdim object'); # create the generator generator = _deprecated.RandomGenerator(hoomd.context.exec_conf, box._getBoxDim(), seed, box.dimensions); # build type list type_vector = _hoomd.std_vector_string(); type_vector.append(name); # empty bond lists for single particles bond_ab = _hoomd.std_vector_uint(); bond_type = _hoomd.std_vector_string(); # create the generator generator.addGenerator(int(N), _deprecated.PolymerParticleGenerator(hoomd.context.exec_conf, 1.0, type_vector, bond_ab, bond_ab, bond_type, 100, box.dimensions)); # set the separation radius generator.setSeparationRadius(name, min_dist/2.0); # generate the particles generator.generate(); # initialize snapshot snapshot = generator.getSnapshot() my_domain_decomposition = hoomd.init._create_domain_decomposition(snapshot._global_box); if my_domain_decomposition is not None: hoomd.context.current.system_definition = _hoomd.SystemDefinition(snapshot, hoomd.context.exec_conf, my_domain_decomposition); else: hoomd.context.current.system_definition = _hoomd.SystemDefinition(snapshot, hoomd.context.exec_conf); # initialize the system hoomd.context.current.system = _hoomd.System(hoomd.context.current.system_definition, 0); hoomd.init._perform_common_init_tasks(); return hoomd.data.system_data(hoomd.context.current.system_definition);
def create_random_polymers(box, polymers, separation, seed=1): R""" Generates any number of randomly positioned polymers of configurable types. Args: box (:py:class:`hoomd.data.boxdim`): Simulation box dimensions polymers (list): Specification for the different polymers to create (see below) separation (dict): Separation radii for different particle types (see below) seed (int): Random seed to use .. deprecated:: 2.0 Random initialization is best left to specific methods tailored by the user for their work. Any number of polymers can be generated, of the same or different types, as specified in the argument *polymers*. Parameters for each polymer include bond length, particle type list, bond list, and count. The syntax is best shown by example. The below line specifies that 600 block copolymers A6B7A6 with a bond length of 1.2 be generated:: polymer1 = dict(bond_len=1.2, type=['A']*6 + ['B']*7 + ['A']*6, bond="linear", count=600) Here is an example for a second polymer, specifying just 100 polymers made of 5 B beads bonded in a branched pattern:: polymer2 = dict(bond_len=1.2, type=['B']*5, bond=[(0, 1), (1,2), (1,3), (3,4)] , count=100) The *polymers* argument can be given a list of any number of polymer types specified as above. *count* randomly generated polymers of each type in the list will be generated in the system. In detail: - bond_len defines the bond length of the generated polymers. This should not necessarily be set to the equilibrium bond length! The generator is dumb and doesn't know that bonded particles can be placed closer together than the separation (see below). Thus bond_len must be at a minimum set at twice the value of the largest separation radius. An error will be generated if this is not the case. - type is a python list of strings. Each string names a particle type in the order that they will be created in generating the polymer. - bond can be specified as "linear" in which case the generator connects all particles together with bonds to form a linear chain. bond can also be given a list if python tuples (see example above). - Each tuple in the form of \c (a,b) specifies that particle \c a of the polymer be bonded to particle \c b. These bonds are given the default type name of 'polymer' to be used when specifying parameters to bond forces such as bond.harmonic. - A tuple with three elements (a,b,type) can be used as above, but with a custom name for the bond. For example, a simple branched polymer with different bond types on each branch could be defined like so:: bond=[(0,1), (1,2), (2,3,'branchA'), (3,4,'branchA), (2,5,'branchB'), (5,6,'branchB')] separation must contain one entry for each particle type specified in polymers ('A' and 'B' in the examples above). The value given is the separation radius of each particle of that type. The generated polymer system will have no two overlapping particles. Examples:: init.create_random_polymers(box=data.boxdim(L=35), polymers=[polymer1, polymer2], separation=dict(A=0.35, B=0.35)); init.create_random_polymers(box=data.boxdim(L=31), polymers=[polymer1], separation=dict(A=0.35, B=0.35), seed=52); # create polymers in an orthorhombic box init.create_random_polymers(box=data.boxdim(Lx=18,Ly=10,Lz=25), polymers=[polymer2], separation=dict(A=0.35, B=0.35), seed=12345); # create a triclinic box with tilt factors xy=0.1 xz=0.2 yz=0.3 init.create_random_polymers(box=data.boxdim(L=18, xy=0.1, xz=0.2, yz=0.3), polymers=[polymer2], separation=dict(A=0.35, B=0.35)); With all other parameters the same, create_random_polymers will always create the same system if seed is the same. Set a different seed (any integer) to create a different random system with the same parameters. Note that different versions of HOOMD \e may generate different systems even with the same seed due to programming changes. Note: For relatively dense systems (packing fraction 0.4 and higher) the simple random generation algorithm may fail to find room for all the particles and print an error message. There are two methods to solve this. First, you can lower the separation radii allowing particles to be placed closer together. Then setup integrate.nve with the limit option set to a relatively small value. A few thousand time steps should relax the system so that the simulation can be continued without the limit or with a different integrator. For extremely troublesome systems, generate it at a very low density and shrink the box with the command update.box_resize to the desired final size. Note: The polymer generator always generates polymers as if there were linear chains. If you provide a non-linear bond topology, the bonds in the initial configuration will be stretched significantly. This normally doesn't pose a problem for harmonic bonds (bond.harmonic) as the system will simply relax over a few time steps, but can cause the system to blow up with FENE bonds (bond.fene). """ hoomd.util.print_status_line(); hoomd.context._verify_init(); # check if initialization has already occurred if hoomd.init.is_initialized(): hoomd.context.msg.error("Cannot initialize more than once\n"); raise RuntimeError("Error creating random polymers"); if len(polymers) == 0: hoomd.context.msg.error("Polymers list cannot be empty.\n"); raise RuntimeError("Error creating random polymers"); if len(separation) == 0: hoomd.context.msg.error("Separation dict cannot be empty.\n"); raise RuntimeError("Error creating random polymers"); if not isinstance(box, hoomd.data.boxdim): hoomd.context.msg.error('Box must be a data.boxdim object\n'); raise TypeError('box must be a data.boxdim object'); # create the generator generator = _deprecated.RandomGenerator(hoomd.context.exec_conf,box._getBoxDim(), seed, box.dimensions); # make a list of types used for an eventual check vs the types in separation for completeness types_used = []; # track the minimum bond length min_bond_len = None; # build the polymer generators for poly in polymers: type_list = []; # check that all fields are specified if not 'bond_len' in poly: hoomd.context.msg.error('Polymer specification missing bond_len\n'); raise RuntimeError("Error creating random polymers"); if min_bond_len is None: min_bond_len = poly['bond_len']; else: min_bond_len = min(min_bond_len, poly['bond_len']); if not 'type' in poly: hoomd.context.msg.error('Polymer specification missing type\n'); raise RuntimeError("Error creating random polymers"); if not 'count' in poly: hoomd.context.msg.error('Polymer specification missing count\n'); raise RuntimeError("Error creating random polymers"); if not 'bond' in poly: hoomd.context.msg.error('Polymer specification missing bond\n'); raise RuntimeError("Error creating random polymers"); # build type list type_vector = _hoomd.std_vector_string(); for t in poly['type']: type_vector.append(t); if not t in types_used: types_used.append(t); # build bond list bond_a = _hoomd.std_vector_uint(); bond_b = _hoomd.std_vector_uint(); bond_name = _hoomd.std_vector_string(); # if the bond setting is 'linear' create a default set of bonds if poly['bond'] == 'linear': for i in range(0,len(poly['type'])-1): bond_a.append(i); bond_b.append(i+1); bond_name.append('polymer') #if it is a list, parse the user custom bonds elif type(poly['bond']) == type([]): for t in poly['bond']: # a 2-tuple gets the default 'polymer' name for the bond if len(t) == 2: a,b = t; name = 'polymer'; # and a 3-tuple specifies the name directly elif len(t) == 3: a,b,name = t; else: hoomd.context.msg.error('Custom bond ' + str(t) + ' must have either two or three elements\n'); raise RuntimeError("Error creating random polymers"); bond_a.append(a); bond_b.append(b); bond_name.append(name); else: hoomd.context.msg.error('Unexpected argument value for polymer bond\n'); raise RuntimeError("Error creating random polymers"); # create the generator generator.addGenerator(int(poly['count']), _deprecated.PolymerParticleGenerator(hoomd.context.exec_conf, poly['bond_len'], type_vector, bond_a, bond_b, bond_name, 100, box.dimensions)); # check that all used types are in the separation list for t in types_used: if not t in separation: hoomd.context.msg.error("No separation radius specified for type " + str(t) + "\n"); raise RuntimeError("Error creating random polymers"); # set the separation radii, checking that it is within the minimum bond length for t,r in separation.items(): generator.setSeparationRadius(t, r); if 2*r >= min_bond_len: hoomd.context.msg.error("Separation radius " + str(r) + " is too big for the minimum bond length of " + str(min_bond_len) + " specified\n"); raise RuntimeError("Error creating random polymers"); # generate the particles generator.generate(); # copy over data to snapshot snapshot = generator.getSnapshot() my_domain_decomposition = hoomd.init._create_domain_decomposition(snapshot._global_box); if my_domain_decomposition is not None: hoomd.context.current.system_definition = _hoomd.SystemDefinition(snapshot, hoomd.context.exec_conf, my_domain_decomposition); else: hoomd.context.current.system_definition = _hoomd.SystemDefinition(snapshot, hoomd.context.exec_conf); # initialize the system hoomd.context.current.system = _hoomd.System(hoomd.context.current.system_definition, 0); hoomd.init._perform_common_init_tasks(); return hoomd.data.system_data(hoomd.context.current.system_definition);
def __init__(self, mc, seed, period=1, transfer_types=None,ngibbs=1): if not isinstance(mc, integrate.mode_hpmc): hoomd.context.current.device.cpp_msg.warning("update.muvt: Must have a handle to an HPMC integrator.\n"); return; self.mc = mc # initialize base class _updater.__init__(self); if ngibbs > 1: self.gibbs = True; else: self.gibbs = False; # 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)); # by default, transfer all types if transfer_types is None: transfer_types = type_list cls = None; if isinstance(mc, integrate.sphere): cls = _hpmc.UpdaterMuVTSphere; elif isinstance(mc, integrate.convex_polygon): cls = _hpmc.UpdaterMuVTConvexPolygon; elif isinstance(mc, integrate.simple_polygon): cls = _hpmc.UpdaterMuVTSimplePolygon; elif isinstance(mc, integrate.convex_polyhedron): cls = _hpmc.UpdaterMuVTConvexPolyhedron; elif isinstance(mc, integrate.convex_spheropolyhedron): cls = _hpmc.UpdaterMuVTSpheropolyhedron; elif isinstance(mc, integrate.ellipsoid): cls = _hpmc.UpdaterMuVTEllipsoid; elif isinstance(mc, integrate.convex_spheropolygon): cls =_hpmc.UpdaterMuVTSpheropolygon; elif isinstance(mc, integrate.faceted_sphere): cls =_hpmc.UpdaterMuVTFacetedEllipsoid; elif isinstance(mc, integrate.sphere_union): cls = _hpmc.UpdaterMuVTSphereUnion; elif isinstance(mc, integrate.convex_spheropolyhedron_union): cls = _hpmc.UpdaterMuVTConvexPolyhedronUnion; elif isinstance(mc, integrate.faceted_ellipsoid_union): cls = _hpmc.UpdaterMuVTFacetedEllipsoidUnion; elif isinstance(mc, integrate.polyhedron): cls =_hpmc.UpdaterMuVTPolyhedron; else: hoomd.context.current.device.cpp_msg.error("update.muvt: Unsupported integrator.\n"); raise RuntimeError("Error initializing update.muvt"); self.cpp_updater = cls(hoomd.context.current.system_definition, mc.cpp_integrator, int(seed), ngibbs); # register the muvt updater self.setupUpdater(period); # set the list of transferred types if not isinstance(transfer_types,list): hoomd.context.current.device.cpp_msg.error("update.muvt: Need list of types to transfer.\n"); raise RuntimeError("Error initializing update.muvt"); cpp_transfer_types = _hoomd.std_vector_uint(); for t in transfer_types: if t not in type_list: hoomd.context.current.device.cpp_msg.error("Trying to transfer unknown type " + str(t) + "\n"); raise RuntimeError("Error setting muVT parameters"); else: type_id = hoomd.context.current.system_definition.getParticleData().getTypeByName(t); cpp_transfer_types.append(type_id) self.cpp_updater.setTransferTypes(cpp_transfer_types)
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, mc, r_cut, array_size=1, code=None, llvm_ir_file=None, r_cut_iso=None, code_iso=None, llvm_ir_file_iso=None, array_size_iso=1, clang_exec=None): # check if initialization has occurred hoomd.context._verify_init() if clang_exec is not None: clang = clang_exec else: clang = 'clang' if code is not None: llvm_ir = self.compile_user(array_size_iso, array_size, code, clang) else: # IR is a text file with open(llvm_ir_file, 'r') as f: llvm_ir = f.read() if code_iso is not None: llvm_ir_iso = self.compile_user(array_size_iso, array_size, code_iso, clang) else: if llvm_ir_file_iso is not None: # IR is a text file with open(llvm_ir_file_iso, 'r') as f: llvm_ir_iso = f.read() else: # provide a dummy function llvm_ir_iso = self.compile_user(array_size_iso, array_size, 'return 0;', clang) if r_cut_iso is None: r_cut_iso = -1.0 self.compute_name = "patch_union" if hoomd.context.current.device.cpp_exec_conf.isCUDAEnabled(): include_path_hoomd = os.path.dirname(hoomd.__file__) + '/include' include_path_source = hoomd._hoomd.__hoomd_source_dir__ include_path_cuda = _jit.__cuda_include_path__ options = [ "-I" + include_path_hoomd, "-I" + include_path_source, "-I" + include_path_cuda ] # use union evaluator options += ["-DUNION_EVAL"] cuda_devrt_library_path = _jit.__cuda_devrt_library_path__ # select maximum supported compute capability out of those we compile for compute_archs = _jit.__cuda_compute_archs__ compute_archs_vec = _hoomd.std_vector_uint() compute_capability = hoomd.context.current.device.cpp_exec_conf.getComputeCapability( 0) # GPU 0 compute_major, compute_minor = compute_capability.split('.') max_arch = 0 for a in compute_archs.split('_'): if int(a) < int(compute_major) * 10 + int(compute_major): max_arch = int(a) gpu_code = self.wrap_gpu_code(code) self.cpp_evaluator = _jit.PatchEnergyJITUnionGPU( hoomd.context.current.system_definition, hoomd.context.current.device.cpp_exec_conf, llvm_ir_iso, r_cut_iso, array_size_iso, llvm_ir, r_cut, array_size, gpu_code, "hpmc::gpu::kernel::hpmc_narrow_phase_patch", options, cuda_devrt_library_path, max_arch) else: self.cpp_evaluator = _jit.PatchEnergyJITUnion( hoomd.context.current.system_definition, hoomd.context.current.device.cpp_exec_conf, llvm_ir_iso, r_cut_iso, array_size_iso, llvm_ir, r_cut, array_size) mc.set_PatchEnergyEvaluator(self) self.mc = mc self.enabled = True self.log = False self.cpp_evaluator.alpha_iso[:] = [0] * array_size_iso self.cpp_evaluator.alpha_union[:] = [0] * array_size self.alpha_iso = self.cpp_evaluator.alpha_iso[:] self.alpha_union = self.cpp_evaluator.alpha_union[:]
def __init__(self, mc, r_cut, array_size=1, code=None, llvm_ir_file=None, clang_exec=None): # check if initialization has occurred hoomd.context._verify_init() self.compute_name = "patch" # Find a clang executable if none is provided (we need the CPU version even when running on GPU) if clang_exec is not None: clang = clang_exec else: clang = 'clang' if code is not None: llvm_ir = self.compile_user(array_size, 1, code, clang) else: # IR is a text file with open(llvm_ir_file, 'r') as f: llvm_ir = f.read() if hoomd.context.current.device.cpp_exec_conf.isCUDAEnabled(): include_path_hoomd = os.path.dirname(hoomd.__file__) + '/include' include_path_source = hoomd._hoomd.__hoomd_source_dir__ include_path_cuda = _jit.__cuda_include_path__ options = [ "-I" + include_path_hoomd, "-I" + include_path_source, "-I" + include_path_cuda ] cuda_devrt_library_path = _jit.__cuda_devrt_library_path__ # select maximum supported compute capability out of those we compile for compute_archs = _jit.__cuda_compute_archs__ compute_archs_vec = _hoomd.std_vector_uint() compute_capability = hoomd.context.current.device.cpp_exec_conf.getComputeCapability( 0) # GPU 0 compute_major, compute_minor = compute_capability.split('.') max_arch = 0 for a in compute_archs.split('_'): if int(a) < int(compute_major) * 10 + int(compute_major): max_arch = int(a) gpu_code = self.wrap_gpu_code(code) self.cpp_evaluator = _jit.PatchEnergyJITGPU( hoomd.context.current.device.cpp_exec_conf, llvm_ir, r_cut, array_size, gpu_code, "hpmc::gpu::kernel::hpmc_narrow_phase_patch", options, cuda_devrt_library_path, max_arch) else: self.cpp_evaluator = _jit.PatchEnergyJIT( hoomd.context.current.device.cpp_exec_conf, llvm_ir, r_cut, array_size) mc.set_PatchEnergyEvaluator(self) self.mc = mc self.enabled = True self.log = False self.cpp_evaluator.alpha_iso[:] = [0] * array_size self.alpha_iso = self.cpp_evaluator.alpha_iso