def read_frag(self, fname): """ file-mode: read a fragment and convert to a graph """ m = molsys.mol() m.read(self.frag_path + "/" + fname + ".mfpx", ftype="mfpx") m.addon("graph") m.graph.make_graph() self.fragments[fname] = m return
def set_FFfrag(self, name, path, comment=""): """ Method to create a new entry in the FFfrags table. :Parameters: - name (str): name of the entry in the db - path (str): path to the mfpx file of the fragment - comment (str): comment """ assert type(name) == type(path) == type(comment) == str with open(path, "r") as handle: lines = handle.read() m = molsys.mol() m.fromString(lines, ftype="mfpx") prio = m.natoms - m.elems.count("x") self.mfp.set_FFfrag(name, lines, prio, comment) return
def extend_cell_with_fragments(mol, fragments, boxtol=[0.1, 0.1, 0.1]): m = mol addmol = molsys.mol() offset = np.zeros([3], "d") boxtol = np.array(boxtol) for ix in range(-1, 2): for iy in range(-1, 2): for iz in range(-1, 2): cell_disp = np.sum(m.cell * np.array([ix, iy, iz], "d")[:, np.newaxis], axis=0) xyz = m.xyz + cell_disp inflags, frag_com, frag_flag = check_fragcom_in_cell( mol, xyz, boxtol, fragments) for i in range(m.natoms): if inflags[i]: addmol.add_atom(m.elems[i], m.atypes[i], xyz[i]) return addmol
def inner(*args, **kwargs): try: lines = func(*args, **kwargs) if "mol" in kwargs.keys(): if kwargs["mol"] == True: if dtype == "topology": m = molsys.topo() else: m = molsys.mol() m.fromString(lines) return m if binary == False: f = open(str(args[1]) + '.mfpx', 'w') f.write(lines) f.close() else: with open("%s.hdf5" % str(args[1]), "wb") as handle: handle.write(lines) logger.info('%s %s downloaded from mofplus' % (dtype, args[1])) except xmlrpclib.Fault: logger.error('Requested %s %s not available on mofplus' % (dtype, args[1]))
def get_primitive_cell(self): """ get the primitve cell as a new mol object """ assert self.spgcell != None new_spgcell = spglib.find_primitive(self.spgcell) if new_spgcell == None: logger.error("Search for primitive cell failed with symprec %f" % self.symprec) return print(new_spgcell[0]) print(new_spgcell[2]) new_mol = molsys.mol() new_mol.set_natoms(len(new_spgcell[2])) new_mol.set_cell(new_spgcell[0]) new_mol.set_xyz(new_mol.get_real_from_frac(new_spgcell[1])) new_mol.set_elems_number(new_spgcell[2]) # now add the connectivity new_mol.detect_conn() # RS: we could do atomtyping ... but this would have to be a method of mol ... new_mol.set_atypes(["0"] * new_mol.get_natoms()) new_mol.set_nofrags() return new_mol
def init_objective(self, objname, sysname, tag, coord=None, fpar=None, reffile=None, weight=1.0, offline=False, refsys=None, mm='lammps', bcond=3, stdout=False, objargs=[], objkwargs={}, mmkwargs={}): """ Method to initialize an objective class :Parameters: - objname (str): name of the objective class - sysname (str): Name of the molecular system, if coord or fpar or reffile are None, the sysname is also used for this files - tag (str): Name of the subgroup in the hdf5 file holding the actual reference information - coord (str, optional): Name of the mfpx file, if None sysname.mfpx will be used, default: None - fpar (str, optional): Name of the fpar/ric file, if None sysname.fpar will be used, default: None - reffile (str, optional): Name of the hdf5 reference file, if None sysname.hdf5 will be used, default: None - weight (float, optional): Weight of the objective in the total objective function, default: 1.0 - offline (bool, optional): Flag to specify if molsys offline assignment should be used, default: False - refsys (str, optional): Name of the reference system in case of offline assignment, default: None - mm (str, optional): Name of the molecular mechanics engine to use, only pydlpoly or lammps possible, default: lammps - bcond (int, optional): Bconds used in MM engine, default: 3 - stdout (bool, optional): Flag to toggle if objective should use stdout or an seperate outfile, default: False - objargs (list, optional): List of arguments passed to the objective class at init, default: [] - objkwargs (dict, optional): List of keyword arguments passed to the objective class at init, default: {} - mmkwargs (dict, optional): List of keyword arguments passed to mm machine at setup, default: {}, in this case the defaults in defmmkwargs are used """ # in this dictionary the implemeted objectives has to be given objclasses = { 'ric_fit': ric_fit.ric_fit, 'force_ric_fit': force_ric_fit.force_ric_fit } defmmkwargs = { 'lammps': { 'screen': False, 'logfile': 'none' }, 'pydlpoly': {} } assert self.bsetup == False, "FFgen already set up. Not possible to add more objectives" assert objname in objclasses.keys( ), "Objective %s not available" % objname assert mm in mmclasses, 'Requested MM backend %s not available' % mm if objname == 'force_ric_fit' and self.mpi_size > 1: raise NotImplementedError('No MPI fitting with force_ric_fit') dir_prefix = {'ric_fit': 'rf', 'force_ric_fit': 'frf'} # do MPI_stuff if self.local_size > 1: obj_comm = self.local_comm.Split(self.local_rank, 0) else: obj_comm = self.local_comm obj_size = obj_comm.Get_size() obj_rank = obj_comm.Get_rank() # pass input if coord == None: coord = '%s.mfpx' % sysname if fpar == None: fpar = sysname if reffile == None: reffile = '%s.hdf5' % sysname # handle filenames if self.mpi_rank != 0: name = '%s_%s-r%i' % (dir_prefix[objname], sysname, self.mpi_rank) else: name = '%s_%s' % (dir_prefix[objname], sysname) if stdout: outfile = sys.stdout else: outfile = open('%s.out' % name, 'w') # init molsys m = molsys.mol(mpi_comm=obj_comm, out=outfile) m.read(os.path.join(self.start_dir, coord)) # add ff and distribute params m.addon('ff', par=self.par) if offline: assert refsys is not None m.ff.load_params_from_parfile(os.path.join(self.start_dir, fpar), fit=True) m.ff.assign_params_offline(refsys) else: m.ff.read(os.path.join(self.start_dir, fpar), fit=True) # if the current local rank is not responsible for the current obj, add # add None to the list of objs if self.local_size > 1 and self.local_rank != len(self.objs): self.add_objective(None, weight) return # add calculator # introduce global rank specific, objective and system dependent name for creating subdirs if len(mmkwargs) == 0: mmkwargs = defmmkwargs[mm] calc = mmclasses[mm](name, mpi_comm=obj_comm, out=outfile) calc.setup(mol=m, local=False, bcond=bcond, **mmkwargs) # init objective obj = objclasses[objname](calc, os.path.join(self.start_dir, reffile), tag, self.start_dir, out=outfile, mpi_comm=obj_comm, *objargs, **objkwargs) # add objective self.add_objective(obj, weight) return
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import pydlpoly import molsys # initialize a pydlpoly instance m = molsys.mol() m.read("bdc_0opt.mfpx") m.addon("ff") m.ff.read("bdc_0") pd = pydlpoly.pydlpoly("test") pd.control["shift"] = "" pd.control["spme"] = "precision 1.0d-6" pd.setup(mol=m, local=False) # set field pd.set_efield([0.00, 0.0, 0.0], use_ref=False, const_D=False) pd.set_atoms_moved() pd.calc_energy_force() # equilibrate temperature pd.MD_init("equil", T=150, ensemble="nvt", thermo="ber", relax=[0.2]) pd.MD_run(100000, printout=100) # sampling pd.MD_init("cons", T=150, ensemble="nvt",
def setup(self, mfpx=None, local=True, mol=None, par=None, ff="MOF-FF", logfile='none', screen=True, bcond=2): cmdargs = ['-log', logfile] if screen == False: cmdargs += ['-screen', 'none'] self.lmps = lammps(cmdargs=cmdargs, comm=self.mpi_comm) # depending on what type of input is given a setup will be done # the default is to load an mfpx file and assign from MOF+ (using force field MOF-FF) # if par is given or ff="file" we use mfpx/ric/par # if mol is given then this is expected to be an already assigned mol object # (in the latter case everything else is ignored!) self.start_dir = os.getcwd() if mol != None: self.mol = mol else: # we need to make a molsys and read it in self.mol = molsys.mol() if mfpx == None: mfpx = self.name + ".mfpx" self.mol.read(mfpx) self.mol.addon("ff") if par or ff == "file": if par == None: par = self.name self.mol.ff.read(par) else: self.mol.ff.assign_params(ff) # now generate the converter self.ff2lmp = ff2lammps.ff2lammps(self.mol) # adjust the settings if self.control["oop_umbrella"]: self.pprint("using umbrella_harmonic for OOP terms") self.ff2lmp.setting("use_improper_umbrella_harmonic", True) self.data_file = self.name + ".data" self.inp_file = self.name + ".in" if local: # self.data_file = self.name+".data" # self.inp_file = self.name+".in" self.rundir = self.start_dir else: self.rundir = self.start_dir + '/' + self.name if self.mpi_comm.Get_rank() == 0: if os.path.isdir(self.rundir): i = 1 temprundir = self.rundir + ('_%d' % i) while os.path.isdir(temprundir): i += 1 temprundir = self.rundir + ('_%d' % i) self.rundir = temprundir os.mkdir(self.rundir) self.rundir = self.mpi_comm.bcast(self.rundir) self.mpi_comm.Barrier() self.pprint(self.rundir) self.pprint(self.name) os.chdir(self.rundir) #further settings in order to be compatible to pydlpoly self.QMMM = False self.bcond = bcond # before writing output we can adjust the settings in ff2lmp # TBI self.ff2lmp.write_data(filename=self.data_file) self.ff2lmp.write_input(filename=self.inp_file, kspace=self.control["kspace"]) self.lmps.file(self.inp_file) os.chdir(self.start_dir) # connect variables for extracting for e in evars: self.lmps.command("variable %s equal %s" % (e, evars[e])) for p in pressure: self.lmps.command("variable %s equal %s" % (p, p)) self.lmps.command("variable vol equal vol") # stole this from ASE lammpslib ... needed to recompute the stress ?? should affect only the ouptut ... compute is automatically generated self.lmps.command('thermo_style custom pe temp pxx pyy pzz') self.natoms = self.lmps.get_natoms() # compute energy of initial config self.calc_energy() self.report_energies() self.md_fixes = [] return
def frags2atypes(db,row): import molsys m = molsys.mol() m.read()