-run_args.num_cells / 2, run_args.num_cells / 2, -run_args.num_cells / 2, run_args.num_cells / 2) simulation.setup("box") simulation.create_rods(box=None) # DYNAMICS py_lmp.fix("thermostat", "all", "langevin", run_args.temp, run_args.temp, run_args.damp, seed) #, "zero yes") simulation.set_rod_dynamics("nve") py_lmp.neigh_modify("every 1 delay 1") py_lmp.timestep(run_args.dt) # RANDOMISE INITIAL CONFIGURATION simulation.deactivate_state(0, vx_eps=5.0) py_lmp.command('run 10000') simulation.activate_state(0) py_lmp.reset_timestep(0) # GROUPS & COMPUTES if hasattr(run_args, 'label_fibrils'): fibril_group = 'beta_patches' beta_active_patch_types = sorted(filter(lambda t: (t in model.active_bead_types) and\ (t not in model.body_bead_types), model.state_bead_types[1])) py_lmp.variable( fibril_group, 'atom', '"' + '||'.join( ['(type == {:d})'.format(t) for t in beta_active_patch_types]) + '"') py_lmp.group(fibril_group, 'dynamic', simulation.rods_group, 'var', fibril_group, 'every', out_freq)
#py_lmp.fix_modify(simulation.rod_dyn_fix, 'dynamic/dof yes') #only for nvt&npt (small) py_lmp.compute_modify("thermo_temp", "dynamic/dof yes") # TEST DUMP... # py_lmp.thermo_style('custom', 'step atoms', 'pe temp') # py_lmp.variable('thermo_var', 'equal', '"stagger({:d}, 1)"'.format(out_freq)) # py_lmp.thermo('v_thermo_var') # py_lmp.dump('test_dump', 'all', 'custom', out_freq, dump_path+'_init', # 'id x y z type mol c_'+cluster_compute) # py_lmp.dump_modify('test_dump', 'sort id') # GENERATING INITIAL CONFIGURATION py_lmp.neigh_modify('every', 1, 'delay', 1) py_lmp.timestep(run_args.dt) py_lmp.command('run 2000') py_lmp.unfix(rod_gcmc_fix) py_lmp.unfix(zwalls_fix) py_lmp.reset_timestep(0) # ===== MEMBRANE ======================================================================== # create membrane (box update, create membrane & groups, ...) membrane.create_membrane(py_lmp, seed, append=True) py_lmp.fix(zwalls_fix, 'all', 'wall/lj126', 'zlo EDGE', 1.0, model.rod_radius, model.rod_radius*pow(2,1./6), 'zhi EDGE', 1.0, model.rod_radius, model.rod_radius*pow(2,1./6)) # GROUPS & COMPUTES adsorbed_group = 'mem_and_tips'
-run_args.num_cells / 2, run_args.num_cells / 2, -run_args.num_cells / 2, run_args.num_cells / 2) simulation.setup("box") simulation.create_rods(box = None) # DYNAMICS py_lmp.fix("thermostat", "all", "langevin", run_args.temp, run_args.temp, run_args.damp, seed)#, "zero yes") simulation.set_rod_dynamics("nve") py_lmp.neigh_modify("every 1 delay 1") py_lmp.timestep(run_args.dt) # RANDOMISE INITIAL CONFIGURATION simulation.deactivate_state(0, vx_eps=5.0) py_lmp.command('run 10000') simulation.activate_state(0) py_lmp.reset_timestep(0) # GROUPS & COMPUTES if hasattr(run_args, 'label_micelles'): micelle_group = 'sol_tips' sol_tip_bead_type = model.state_structures[0][0][-1] py_lmp.variable(micelle_group, 'atom', '"type == {:d}"'.format(sol_tip_bead_type)) py_lmp.group(micelle_group, 'dynamic', simulation.rods_group, 'var', micelle_group, 'every', out_freq) micelle_compute = "micelle_ID" if hasattr(run_args, 'micelle_cutoff'): micelle_cutoff = run_args.micelle_cutoff else: SS_tip_int_key = model.eps[(sol_tip_bead_type, sol_tip_bead_type)][1]
class LammpsCalc(object): def __init__(self, initfilepath, potfilepath, poscar): # self.lmp = lammps() self.initpath = initfilepath self.potentialpath = potfilepath self.poscar = poscar # self.scel = tokens[0] # self.id = tokens[1] self.pylmp = PyLammps() self.configurename = None # self.clex = clex self.labels_dict = {} self.num_types_cell = None self.atoms_num = {} self.total_atoms = 0 self.atoms = None self.atom_types = None self.cart_coors = None self.lattice = None self.basis_vec = None self.basis_sites = None self.cos_alpha = None self.cos_beta = None self.cos_gamma = None self.xlo = None self.xhi = None self.ylo = None self.yhi = None self.zlo = None self.zhi = None self.xy = None self.yz = None self.xz = None self.properties = {} self.json_props = None self.relaxed_energy = None # def load_files(self): # self.lmp.file("init.mod") # self.lmp.file("potential.mod") def read_prim(self): prim_path = "./prim.json" prim_file = open(prim_path).read() prim = json.JSONDecoder().decode(prim_file) print("prim:\n\n\n\n", prim) if prim['coordinate_mode'] == "Fractional": self.basis_vec = np.array(prim['lattice_vectors']) self.basis_sites = [] # for basis in prim[''] def read_structure(self): # Dir is defined at CASMcode/python/casm/casm/project/project.py # dir.__setattr__("POS", open(self.configurename + "/POS")) # pos_file = dir.POS(self.configname) pos_file = open(self.poscar) # assert \ self.configurename == pos_file.readline().strip() a0 = float(pos_file.readline().strip()) print(a0) a1str = pos_file.readline().strip() a1 = a1str.split() a2str = pos_file.readline().strip() a2 = a2str.split() a3str = pos_file.readline().strip() a3 = a3str.split() self.lattice = np.array([a1, a2, a3], float) * a0 print("lattice") print(self.lattice) labels = pos_file.readline().strip().split() nums = pos_file.readline().strip().split() for i in range(len(labels)): self.atoms_num[labels[i]] = nums[i] self.total_atoms = np.sum(np.array(nums, int)) self.num_types_cell = len(labels) self.atoms = np.zeros((self.total_atoms, 3)) self.atom_types = np.zeros(self.total_atoms) assert 'Direct' == pos_file.readline().strip() i = 0 line = pos_file.readline() while line: line = line.strip() tokens = line.split() line = pos_file.readline() if len(tokens) <= 0: continue frac_coor = np.array(tokens[:3], float) # cart_coor = frac_coor @ lattice.T # convert fractional coordinates to cartesian # print(self.lmp.atoms) # self.lmp.atoms[i].position = tuple(cart_coor.reshape(1, -1)[0]) self.atoms[i] = frac_coor # self.lmp.atoms[i].type = int(labels_dict[tokens[3].strip()]) self.atom_types[i] = int(self.labels_dict[tokens[3].strip()]) # print(atoms[i], atom_types[i]) i += 1 def create_structure(self): # Might not need this function anymore self.read_structure() # self.xlo = round(np.amin(cart_coors[:, 0]), 8) # # self.xhi = round(np.amax(cart_coors[:, 0]), 8) # self.ylo = round(np.amin(cart_coors[:, 1]), 8) # # self.yhi = round(np.amax(cart_coors[:, 1]), 8) # self.zlo = round(np.amin(cart_coors[:, 2]), 8) # # self.zhi = round(np.amax(cart_coors[:, 2]), 8) self.create_region() self.read_prim() self.create_atoms() def create_atoms(self): self.cart_coors = self.atoms @ self.lattice print('\nAtoms:\n', self.cart_coors[:10], "\n", self.atom_types[:10]) print("test", self.cart_coors[0][0]) print("atom types", self.atom_types) print("coors: ") print(self.cart_coors) print(self.pylmp.atoms.natoms) # Could optionally use lammps_create_atoms(void *, int, tagint *, int *, double *, double *, # imageint *, int) # But would still need to iterate through list and this method aides debugging. for i in range(self.cart_coors.shape[0]): # maybe should iterate through possible rounding values ### rounding must be consistent across all structure values print( 'create_atoms ' + str(int(self.atom_types[i])) + ' single ' + str(round(self.cart_coors[i][0], 16)) + ' ' + str(round(self.cart_coors[i][1], 16)) + ' ' + str(round(self.cart_coors[i][2], 16))) # self.pylmp.command( # 'create_atoms ' + str(int(self.atom_types[i])) + ' single ' + str(round(self.cart_coors[i][0], 16)) + ' ' # + str(round(self.cart_coors[i][1], 16)) + ' ' + str(round(self.cart_coors[i][2], 16))) self.pylmp.command( 'create_atoms ' + str(int(self.atom_types[i])) + ' single ' + str( self.cart_coors[i][0]) + ' ' + str(self.cart_coors[i][1]) + ' ' + str(self.cart_coors[i][2])) print(self.cart_coors.shape[0]) print(self.pylmp.atoms.natoms) def get_labels(self): raise NotImplementedError() def run_calc(self): raise NotImplementedError() def create_properties(self): self.properties['atom_type'] = list(self.labels_dict.keys()) self.properties['atoms_per_type'] = [self.atoms_num[atom] for atom in self.atoms_num.keys()] # enforces same order as atom_type self.properties['coord_mode'] = 'cartesian' self.properties['is_complete'] = True if self.relaxed_energy is not None else False relaxed_basis = [] relaxed_forces = [] for i in range(self.total_atoms): relaxed_basis.append(list(self.pylmp.atoms[i].position)) relaxed_forces.append(list(self.pylmp.atoms[i].force)) self.properties['relaxed_basis'] = relaxed_basis self.properties['relaxed_energy'] = self.relaxed_energy self.properties['relaxed_forces'] = relaxed_forces self.properties['relaxed_lattice'] = [[self.pylmp.system.xhi-self.pylmp.system.xlo, 0, 0], [self.pylmp.eval('xy'), self.pylmp.system.yhi-self.pylmp.system.ylo, 0], [self.pylmp.eval('xz'), self.pylmp.eval('yz'), self.pylmp.system.zhi-self.pylmp.system.zlo]] j_encoder = json.JSONEncoder() self.json_props = j_encoder.encode(self.properties) return self.properties # self.properties['relaxed_lattice'] = self.lattice # def report_results(self): # # try: # os.mkdir(self.configurename + '/calctype.lammps') # except: # pass # # outputfile = self.configurename + '/calctype.lammps/properties.calc.json' # # with open(outputfile, 'wb') as file: # # cls=noindent.NoIndentEncoder, # file.write(six.u(json.dumps(self.properties, indent=4, sort_keys=True)).encode('utf-8')) # print("Wrote " + outputfile) # sys.stdout.flush() # self.report_status() # def report_status(self): # output = {'status': 'complete'} # outputfile = self.configurename + '/calctype.lammps/status.json' # # with open(outputfile, 'wb') as file: # # cls=noindent.NoIndentEncoder, # file.write(six.u(json.dumps(output, indent=4, sort_keys=True)).encode('utf-8')) # print("Wrote " + outputfile) # sys.stdout.flush() def create_region(self): # In the future will have to read prim and take max or min vector for each dimension # Need to add space for next position b/c otherwise periodicity will make atoms at border overlap # basis_vec = np.array([0.666666666667, 0.333333333334, 0.500000000000]) # lat_vec = np.array([[3.184000000000, 0.000000000000, 0.000000000000], # [-1.592000000000, 2.757424885650, 0.000000000000], # [0.000000000000, 0.000000000000, 5.249000000000]]) # dist = basis_vec @ lat_vec # self.xhi += dist[0] # self.yhi += dist[1] # self.zhi += dist[2] # a = 3.2094 # self.lmp.lattice("hcp ", a) # self.xy = self.lattice[1, 0] # self.yz = self.lattice[2, 1] # self.xz = self.lattice[2, 0] self.xlo = 0 self.ylo = 0 self.zlo = 0 self.cos_alpha = self.cos_angle(self.lattice[1], self.lattice[2]) self.cos_beta = self.cos_angle(self.lattice[0], self.lattice[2]) self.cos_gamma = self.cos_angle(self.lattice[0], self.lattice[1]) self.xy = self.norm(self.lattice[1]) * self.cos_gamma self.xz = self.norm(self.lattice[2]) * self.cos_beta self.xhi = self.norm(self.lattice[0]) self.yhi = np.sqrt(self.norm(self.lattice[1])**2 - self.xy**2) self.yz = ((self.norm(self.lattice[1]) * self.norm(self.lattice[2]) * self.cos_alpha) - (self.xy * self.xz)) / self.yhi self.zhi = np.sqrt((self.norm(self.lattice[2])**2) - (self.xz**2) - (self.yz**2)) # self.xhi = self.lattice[0, 0] - self.lattice[1, 0] - self.lattice[2, 0] # self.yhi = self.lattice[1, 1] - self.lattice[0, 1] - self.lattice[2, 1] # self.zhi = self.lattice[2, 2] - self.lattice[0, 2] - self.lattice[1, 2] self.pylmp.atom_style('atomic') print('prism ', self.xlo, ' ', self.xhi, ' ', self.ylo, ' ', self.yhi, ' ', self.zlo, ' ', self.zhi, ' ', self.xy, ' ', self.xz, ' ', self.yz) self.pylmp.region('box prism ', self.xlo, ' ', self.xhi, ' ', self.ylo, ' ', self.yhi, ' ', self.zlo, ' ', self.zhi, ' ', self.xy, ' ', self.xz, ' ', self.yz) self.pylmp.command("boundary p p p") # self.lmp.region("box block", self.xlo, self.xhi, self.ylo, self.yhi, self.zlo, self.zhi) # self.lmp.command("create_box {0:d} box".format(num_types)) self.pylmp.command("create_box {0:d} box".format(len(self.labels_dict.keys()))) print("bounding box", self.pylmp.system.xlo, self.pylmp.system.xhi, self.pylmp.system.ylo, self.pylmp.system.yhi, self.pylmp.system.zlo, self.pylmp.system.zhi) # self.lmp.create_atoms("1 box") for i in self.labels_dict.values(): self.pylmp.command("mass {0:d} 1.0e-20".format(i)) # self.pylmp.command("mass 2 1.0e-20") def norm(self, vec): return np.sqrt(np.sum(vec**2)) def dot_prod(self, vec1, vec2): return np.sum(vec1 * vec2) def cos_angle(self, vec1, vec2): cos_theta = self.dot_prod(vec1, vec2) / (self.norm(vec1) * self.norm(vec2)) assert cos_theta >= -1 and cos_theta <= 1 if cos_theta < -1: cos_theta = -1 elif cos_theta > 1: cos_theta = 1 return cos_theta def visualize(self): try: print("creating", "./dumpfiles/" + self.scel) os.mkdir("./dumpfiles/" + self.scel) except: pass try: print("creating", "./dumpfiles/" + self.configurename) os.mkdir("./dumpfiles/" + self.configurename) except: pass self.pylmp.dump("dump1", "all", "atom", 1, "./dumpfiles/" + self.configurename + "/dump.atom") # , "zoom 2.0"
# OUTPUT py_lmp.thermo_style("custom", "step atoms", "pe temp") dump_elems = "id x y z type mol" py_lmp.dump("dump_cmd", "all", "custom", out_freq, dump_path, dump_elems) py_lmp.dump_modify("dump_cmd", "sort id") py_lmp.thermo(out_freq) # RUN... mc_moves_per_run = 0 if model.num_states > 1: mc_moves_per_run = int(run_args.mc_moves * simulation.rods_count()) py_lmp.timestep(run_args.dt) if mc_moves_per_run == 0: py_lmp.command('run {:d}'.format(args.simlen)) else: py_lmp.command( 'run {:d} post no'.format(run_args.run_length - 1)) #so output happens after state changes remaining = args.simlen - run_args.run_length + 1 for i in range(args.simlen / run_args.run_length): success = simulation.state_change_MC(mc_moves_per_run) if not args.silent: base_count = simulation.state_count(0) beta_count = simulation.state_count(1) print 'step {:d} / {:d} : beta-to-soluble ratio = {:d}/{:d} = {:.5f} (accept rate = {:.5f})'.format( (i + 1) * run_args.run_length, args.simlen, beta_count, base_count, float(beta_count) / base_count, float(success) / mc_moves_per_run)
class LammpsKernel(IGMKernel): def __init__(self, model, cfg, runid): self.cfg = cfg self.model = model self.runid = runid self.tmp_dir = self.cfg.tmpdir('optimization') self.randseed = int(self.cfg["optimization/kernel_opts/lammps/seed"]) self.initLammps() self.setupSimulationBox() self.setupParticles() self.setCoordinates() self.setRadii() self.setupNeighbor() def initLammps(self): """ setup lammps python interface, log file """ if self.cfg["optimization/kernel_opts/lammps/keep_logs"]: self.Lmp = PyLammps(cmdargs=["-log",os.path.join(self.tmp_dir, self.runid+".log")]) else: self.Lmp = PyLammps(cmdargs=["-log","none"]) self.Lmp.atom_style("bond") self.Lmp.boundary('s','s','s') def setupSimulationBox(self): """ setup lammps simulation box """ atom_types = 1 bond_types = 0 bond_per_atom = 0 for Res in self.model.restraints: atom_types += Res.extra_atom_types bond_types += Res.extra_bond_types bond_per_atom += Res.extra_bond_per_atom if res.type == "Envelope": xx , yy, zz = Res.a*1.2, Res.b*1.2, Res.c*1.2 self.Lmp.region("IGMBOX", "block", -xx, xx, -yy, yy, -zz, zz) self.Lmp.create_box(1, "IGMBOX", "bond/types", bond_types, "extra/bond/per/atom", bond_per_atom) def setupParticles(self): """ initialize particles with random position """ #add user define per-atom property: radius(double) self.Lmp.fix("UserProperty","all","property/atom","d_radius") #number of particles self.nbead = len(self.model.particles) self.atom_style_index = 1 self.Lmp.create_atoms(1, "random", self.nbead, self.randseed, "IGMBOX") #set particle mass 1.0 self.Lmp.mass('*', 1.0) #group particle NORMAL self.lmp_group_NORMAL = "NORMAL" self.Lmp.group(self.lmp_group_NORMAL, "type", 1) #get numpy view of per atom array self.particle_id = self.Lmp.lmp.numpy.extract_atom_iarray('id', n, 1) self._coordinates = self.Lmp.lmp.numpy.extract_atom_darray('x', n, 3) self._radii = self.lmp.lmp.numpy.extract_atom_darray('d_radius', n, 1) def indexMapping(self): """ particle mapping from lammps index to original index """ return np.argsort( self.particle_id[:, 0] ) def setCoordinates(self, crd = None): """ assign xyz values to lammps """ if crd: self.coordinates[self.indexMapping(), :] = crd[:] else: self.coordinates[self.indexMapping(), :] = self.model.particles.coordinates[:] def setRadii(self, radii = None): """ assign radius values to lammps """ if radii: self.radii[self.indexMapping(), :] = radii[:] else: self.radii[self.indexMapping(), :] = self.model.particles.radii[:] self.maxrad = max(self.radii) def setupNeighbor(self): """ setup neighbor list rules """ if hasattr(self, "maxrad"): self.Lmp.neighbor(self.maxrad, 'bin') else: raise RuntimeError("Radii not set before setupNeighbor()") max_neighbor = int(self.cfg["optimization/kernel_opts/lammps/max_neigh"]) self.Lmp.neigh_modify('every',1,'check','yes') self.Lmp.neigh_modify("one", max_neighbor, 'page', 20*max_neighbor) def addRestraints(self): """ add restraints to lammps one by one """ #lammps bond style definition bond_styles = set() n = 1 for Res in self.model.restraints: if hasattr(Res, "bond_style"): bond_styles.add(Res.bond_style) #give_bond_id Res.setBondId(n) n += 1 if len(bond_styles) == 1: self.Lmp.bond_style(bond_styles.pop()) elif len(bond_styles) > 1: cmd = ["bond_style", "hybrid"] while bond_styles: cmd.append(bond_styles.pop()) self.Lmp.command(" ".join(cmd)) #define variable for fast communication/avoid input string parsing self.Lmp.variable("batoms","string","EMPTY") bond_variable = "batoms" #loop all restraints and apply lammps code for Res in self.model.restraints: Res.Lammps(self.Lmp, runid = self.runid, tmp_dir = self.tmp_dir, randseed = self.randseed, normal_group = self.lmp_group_NORMAL, bond_variable = bond_variable)