def __call__(self, parameters): # prepare force field ff = ForceField.generate(self.system, parameters, **self.kwargs) # run actual simulation return self.run(ff)
def ff_generator(system, guest): return ForceField.generate(system, parameters, nlow=max(0,system.natom-guest.natom), nhigh=max(0,system.natom-guest.natom), **kwargs)
def write_raspa_input(guests, parameters, host=None, workdir='.', guestdata=None, hostname='host'): """ Prepare input files that can be used to run RASPA simulations. Only a small subset of the full capabilities of RASPA can be explored. **Arguments:** guests A list specifying the guest molecules. Each entry can be one of two types: (i) the filename of a system file describing one guest molecule, (ii) a System instance of one guest molecule parameters Force-field parameters describing guest-guest and optionally host-guest interaction. Three types are accepted: (i) the filename of the parameter file, which is a text file that adheres to YAFF parameter format, (ii) a list of such filenames, or (iii) an instance of the Parameters class. **Optional arguments:** host Two types are accepted: (i) the filename of a system file describing the host system, (ii) a System instance of the host workdir The directory where output files will be placed. guestdata List with the same length as guests. Each entry contains a tuple either looking as (name, Tc, Pc, omega) or (name). In the latter case, the parameters Tc, Pc, and omega will be loaded from a data file based on the name. Otherwise, these will be left blank in the input file. """ # Load the guest Systems guests = [ System.from_file(guest) if isinstance(guest, str) else guest for guest in guests ] for guest in guests: assert isinstance(guest, System) if guestdata is None: guestdata = [("guest%03d" % iguest, ) for iguest in range(len(guests))] assert len(guests) == len(guestdata) # Load the host System if host is not None: if isinstance(host, str): host = System.from_file(host) assert isinstance(host, System) complex = host # Merge all systems for guest in guests: complex = complex.merge(guest) # Generate the ForceField, we don't really care about settings such as # cutoffs etc. We only need the parameters in the end ff = ForceField.generate(complex, parameters) # Write the force-field parameters write_raspa_forcefield(ff, workdir) # Write masses and charges of all atoms ffatypes, ffatype_ids = write_pseudo_atoms(ff, workdir) # Write the guest information if host == None: counter = 0 else: counter = host.natom for iguest, (guest, data) in enumerate(zip(guests, guestdata)): write_guest(guest, data, workdir, [ ffatypes[iffa] for iffa in ffatype_ids[counter:counter + guest.natom] ]) counter += guest.natom # Write the host coordinates to a cif file if host is not None: dump_cif( host, os.path.join(workdir, '%s.cif' % hostname), ffatypes=[ffatypes[iffa] for iffa in ffatype_ids[:host.natom]]) # A fairly standard input file for GCMC simulations dump_input(workdir, hostname, [data[0] for data in guestdata])
def from_files(cls, guest, parameters, **kwargs): """Automated setup of GCMC simulation **Arguments:** guest Two types are accepted: (i) the filename of a system file describing one guest molecule, (ii) a System instance of one guest molecule parameters Force-field parameters describing guest-guest and optionally host-guest interaction. Three types are accepted: (i) the filename of the parameter file, which is a text file that adheres to YAFF parameter format, (ii) a list of such filenames, or (iii) an instance of the Parameters class. **Optional arguments:** hooks A list of MCHooks host Two types are accepted: (i) the filename of a system file describing the host system, (ii) a System instance of the host All other keyword arguments are passed to the ForceField constructor See the constructor of the :class:`yaff.pes.generator.FFArgs` class for the available optional arguments. """ # Load the guest System if isinstance(guest, str): guest = System.from_file(guest) assert isinstance(guest, System) # We want to control nlow and nhigh here ourselves, so remove it from the # optional arguments if the user provided it. kwargs.pop('nlow', None) kwargs.pop('nhigh', None) # Rough guess for number of adsorbed guests nguests = kwargs.pop('nguests', 10) # Load the host if it is present as a keyword host = kwargs.pop('host', None) # Extract the hooks hooks = kwargs.pop('hooks', []) # Efficient treatment of reciprocal ewald contribution if not 'reci_ei' in kwargs.keys(): kwargs['reci_ei'] = 'ewald_interaction' if host is not None: if isinstance(host, str): host = System.from_file(host) assert isinstance(host, System) # If the guest molecule is currently an isolated molecule, than put # it in the same periodic box as the host if guest.cell is None or guest.cell.nvec==0: guest.cell = Cell(host.cell.rvecs) # Construct a complex of host and one guest and the corresponding # force field excluding host-host interactions hostguest = host.merge(guest) external_potential = ForceField.generate(hostguest, parameters, nlow=host.natom, nhigh=host.natom, **kwargs) else: external_potential = None # # Compare the energy of the guest, once isolated, once in a periodic box # guest_isolated = guest.subsystem(np.arange(guest.natom)) # guest_isolated.cell = Cell(np.zeros((0,3))) # optional_arguments = {} # for key in kwargs.keys(): # if key=='reci_ei': continue # optional_arguments[key] = kwargs[key] # ff_guest_isolated = ForceField.generate(guest_isolated, parameters, **optional_arguments) # e_isolated = ff_guest_isolated.compute() # guest_periodic = guest.subsystem(np.arange(guest.natom)) # ff_guest_periodic = ForceField.generate(guest_periodic, parameters, **optional_arguments) # e_periodic = ff_guest_periodic.compute() # if np.abs(e_isolated-e_periodic)>1e-4: # if log.do_warning: # log.warn("An interaction energy of %s of the guest with its periodic " # "images was detected. The interaction of a guest with its periodic " # "images will however NOT be taken into account in this simulation. " # "If the energy difference is large compared to k_bT, you should " # "consider using a supercell." % (log.energy(e_isolated-e_periodic))) # By making use of nlow=nhigh, we automatically discard intramolecular energies eguest = 0.0 # Generator of guest-guest force fields, excluding interactions # between the first N-1 guests def ff_generator(system, guest): return ForceField.generate(system, parameters, nlow=max(0,system.natom-guest.natom), nhigh=max(0,system.natom-guest.natom), **kwargs) return cls(guest, ff_generator, external_potential=external_potential, eguest=eguest, hooks=hooks, nguests=nguests)