def addljtype(root, amber_prmtop, messages): """ Turns given mask into a new LJ atom type """ # We need a mask, new radius, new epsilon, and for chamber topologies, # a new radius-1-4 and epsilon-1-4. Don't add the latter ones until we # know if we have a chamber prmtop or not. widget_list = [('MaskEntry', 'Atoms to make new LJ Type'), ('Entry', 'New Radius (default old radius)'), ('Entry', 'New Depth (default old depth)')] # We need 5 string variables, then get the description. var_list = [StringVar(), StringVar(), StringVar(), StringVar(), StringVar()] description=('Turns given mask into a new LJ atom type. Uses the radius\n' 'and well depth from the first atom type in <mask> if none\n' 'are provided.') if amber_prmtop.parm.chamber: widget_list += [('Entry', 'New Radius for 1-4 Terms'), ('Entry', 'New Depth for 1-4 Terms')] # Create the window, open it, then wait for it to close cmd_window = _guiwidgets.ActionWindow('addLJType', amber_prmtop, widget_list, var_list, description) cmd_window.wait_window() # See if we got any variables back vars_found = True in [bool(v.get()) for v in var_list] if not vars_found: return # addljtype expects any _non_specified variables to be None var_list = [v.get().strip() for v in var_list] kw_var_list = [var_list[0]] if var_list[1]: kw_var_list.extend(['radius', var_list[1]]) if var_list[2]: kw_var_list.extend(['epsilon', var_list[2]]) if amber_prmtop.parm.chamber and var_list[3]: kw_var_list.extend(['radius_14', var_list[3]]) if amber_prmtop.parm.chamber and var_list[4]: kw_var_list.extend(['epsilon_14', var_list[4]]) try: action = actions.addLJType(amber_prmtop,ArgumentList(kw_var_list)) except Exception as err: showerror('Unexpected Error!', '%s: %s' % (type(err).__name__, err)) return action.execute() messages.write('%s\n' % action)
def _set_nonbonded_tables(self, nbfixes=None): """ Sets the tables of Lennard-Jones nonbonded interaction pairs """ from parmed.tools.actions import addLJType data = self.parm_data ntypes = data['POINTERS'][NTYPES] ntypes2 = ntypes * ntypes # Set up the index lookup tables (not a unique solution) data['NONBONDED_PARM_INDEX'] = [0 for i in range(ntypes2)] holder = [0 for i in range(ntypes2)] idx = 0 for i in range(ntypes): for j in range(i+1): idx += 1 holder[ntypes*i+j] = holder[ntypes*j+i] = idx idx = 0 for i in range(ntypes): for j in range(ntypes): data['NONBONDED_PARM_INDEX'][idx] = holder[ntypes*i+j] idx += 1 nttyp = ntypes * (ntypes + 1) // 2 # Now build the Lennard-Jones arrays data['LENNARD_JONES_14_ACOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_14_BCOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_ACOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_BCOEF'] = [0 for i in range(nttyp)] self.recalculate_LJ() # Now make any NBFIX modifications we had if nbfixes is not None: for i, fix in enumerate(nbfixes): for terms in fix: j, rmin, eps, rmin14, eps14 = terms i, j = min(i, j-1), max(i, j-1) eps = abs(eps) eps14 = abs(eps14) idx = data['NONBONDED_PARM_INDEX'][ntypes*i+j] - 1 data['LENNARD_JONES_ACOEF'][idx] = eps * rmin**12 data['LENNARD_JONES_BCOEF'][idx] = 2 * eps * rmin**6 data['LENNARD_JONES_14_ACOEF'][idx] = eps14 * rmin14**12 data['LENNARD_JONES_14_BCOEF'][idx] = 2 * eps14 * rmin14**6 # If we had an explicit set of exceptions, we need to implement all of # those exclusions. The electrostatic component of that exception is # already handled (since a scaling factor *can* represent the full # flexibility of electrostatic exceptions). The vdW component must be # handled as 1-4 A- and B-coefficients. If vdW types are too compressed # for this to be handled correctly, use "addLJType" to expand the types # by 1 (so the tables only get as big as they *need* to get, to make # sure they continue to fit in CUDA shared memory). # # The way we do this is to fill all of the elements with None, then fill # them in as we walk through the 1-4 exceptions. If we hit a case where # the target element is not None and *doesn't* equal the computed A- and # B-coefficients, we have to expand our type list (assume all type # names will have the same L-J parameters, which has been a fair # assumption in my experience). if not self.adjusts: return for i in range(len(data['LENNARD_JONES_14_ACOEF'])): data['LENNARD_JONES_14_ACOEF'][i] = None data['LENNARD_JONES_14_BCOEF'][i] = None ii = 0 replaced_atoms = set() while True: needed_split = False for pair in self.adjusts: a1, a2 = pair.atom1, pair.atom2 i, j = sorted([a1.nb_idx - 1, a2.nb_idx - 1]) idx = data['NONBONDED_PARM_INDEX'][ntypes*i+j] - 1 eps = pair.type.epsilon rmin = pair.type.rmin rmin6 = rmin * rmin * rmin * rmin * rmin * rmin acoef = eps * rmin6*rmin6 bcoef = 2 * eps * rmin6 if data['LENNARD_JONES_14_ACOEF'][idx] is not None: if abs(data['LENNARD_JONES_14_ACOEF'][idx] - acoef) > SMALL: # Need to split out another type needed_split = True assert a1 not in replaced_atoms or a2 not in replaced_atoms # Only add each atom as a new type ONCE if a1 in replaced_atoms: mask = '@%d' % (a2.idx+1) replaced_atoms.add(a2) else: mask = '@%d' % (a1.idx+1) replaced_atoms.add(a1) addLJType(self, mask, radius_14=0, epsilon_14=0).execute() ntypes += 1 # None-out all of the added terms j = ntypes - 1 for i in range(j): idx2 = data['NONBONDED_PARM_INDEX'][ntypes*i+j] - 1 data['LENNARD_JONES_14_ACOEF'][idx2] = None data['LENNARD_JONES_14_BCOEF'][idx2] = None # We can stop here, since the next loop through the # explicit exclusions will fill this in else: data['LENNARD_JONES_14_ACOEF'][idx] = acoef data['LENNARD_JONES_14_BCOEF'][idx] = bcoef ii += 1 if not needed_split: break # The following should never happen assert ii <= len(self.atoms)+1, 'Could not resolve all exceptions. ' \ 'Some unexpected problem with the algorithm' # Now go through and change all None's to 0s, as these terms won't be # used for any exceptions, anyway for i, item in enumerate(data['LENNARD_JONES_14_ACOEF']): if item is None: assert data['LENNARD_JONES_14_BCOEF'][i] is None, \ 'A- and B- coefficients must be in lock-step!' data['LENNARD_JONES_14_ACOEF'][i] = 0.0 data['LENNARD_JONES_14_BCOEF'][i] = 0.0
def _set_nonbonded_tables(self, nbfixes=None): """ Sets the tables of Lennard-Jones nonbonded interaction pairs """ from parmed.tools.actions import addLJType data = self.parm_data ntypes = data['POINTERS'][NTYPES] ntypes2 = ntypes * ntypes # Set up the index lookup tables (not a unique solution) data['NONBONDED_PARM_INDEX'] = [0 for i in range(ntypes2)] holder = [0 for i in range(ntypes2)] idx = 0 for i in range(ntypes): for j in range(i + 1): idx += 1 holder[ntypes * i + j] = holder[ntypes * j + i] = idx idx = 0 for i in range(ntypes): for j in range(ntypes): data['NONBONDED_PARM_INDEX'][idx] = \ holder[ntypes*i+j] idx += 1 nttyp = ntypes * (ntypes + 1) // 2 # Now build the Lennard-Jones arrays data['LENNARD_JONES_14_ACOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_14_BCOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_ACOEF'] = [0 for i in range(nttyp)] data['LENNARD_JONES_BCOEF'] = [0 for i in range(nttyp)] self.recalculate_LJ() # Now make any NBFIX modifications we had if nbfixes is not None: for i, fix in enumerate(nbfixes): for terms in fix: j, rmin, eps, rmin14, eps14 = terms i, j = min(i, j - 1), max(i, j - 1) eps = abs(eps) eps14 = abs(eps14) idx = data['NONBONDED_PARM_INDEX'][ntypes * i + j] - 1 data['LENNARD_JONES_ACOEF'][idx] = eps * rmin**12 data['LENNARD_JONES_BCOEF'][idx] = 2 * eps * rmin**6 data['LENNARD_JONES_14_ACOEF'][idx] = eps14 * rmin14**12 data['LENNARD_JONES_14_BCOEF'][idx] = 2 * eps14 * rmin14**6 # If we had an explicit set of exceptions, we need to implement all of # those exclusions. The electrostatic component of that exception is # already handled (since a scaling factor *can* represent the full # flexibility of electrostatic exceptions). The vdW component must be # handled as 1-4 A- and B-coefficients. If vdW types are too compressed # for this to be handled correctly, use "addLJType" to expand the types # by 1 (so the tables only get as big as they *need* to get, to make # sure they continue to fit in CUDA shared memory). # # The way we do this is to fill all of the elements with None, then fill # them in as we walk through the 1-4 exceptions. If we hit a case where # the target element is not None and *doesn't* equal the computed A- and # B-coefficients, we have to expand our type list (assume all type # names will have the same L-J parameters, which has been a fair # assumption in my experience). if not self.adjusts: return for i in range(len(data['LENNARD_JONES_14_ACOEF'])): data['LENNARD_JONES_14_ACOEF'][i] = None data['LENNARD_JONES_14_BCOEF'][i] = None ii = 0 replaced_atoms = set() while True: needed_split = False for pair in self.adjusts: a1, a2 = pair.atom1, pair.atom2 i, j = sorted([a1.nb_idx - 1, a2.nb_idx - 1]) idx = data['NONBONDED_PARM_INDEX'][ntypes * i + j] - 1 eps = pair.type.epsilon rmin = pair.type.rmin rmin6 = rmin * rmin * rmin * rmin * rmin * rmin acoef = eps * rmin6 * rmin6 bcoef = 2 * eps * rmin6 if data['LENNARD_JONES_14_ACOEF'][idx] is not None: if abs(data['LENNARD_JONES_14_ACOEF'][idx] - acoef) > SMALL: # Need to split out another type needed_split = True assert (a1 not in replaced_atoms or a2 not in replaced_atoms) # Only add each atom as a new type ONCE if a1 in replaced_atoms: mask = '@%d' % (a2.idx + 1) replaced_atoms.add(a2) else: mask = '@%d' % (a1.idx + 1) replaced_atoms.add(a1) addLJType(self, mask, radius_14=0, epsilon_14=0).execute() ntypes += 1 # None-out all of the added terms j = ntypes - 1 for i in range(j): _ = data['NONBONDED_PARM_INDEX'][ntypes * i + j] - 1 data['LENNARD_JONES_14_ACOEF'][_] = None data['LENNARD_JONES_14_BCOEF'][_] = None # We can stop here, since the next loop through the # explicit exclusions will fill this in else: data['LENNARD_JONES_14_ACOEF'][idx] = acoef data['LENNARD_JONES_14_BCOEF'][idx] = bcoef ii += 1 if not needed_split: break # The following should never happen assert ii <= len(self.atoms)+1, 'Could not resolve all exceptions. ' \ 'Some unexpected problem with the algorithm' # Now go through and change all None's to 0s, as these terms won't be # used for any exceptions, anyway for i, item in enumerate(data['LENNARD_JONES_14_ACOEF']): if item is None: assert data['LENNARD_JONES_14_BCOEF'][i] is None, \ 'A- and B- coefficients must be in lock-step!' data['LENNARD_JONES_14_ACOEF'][i] = 0.0 data['LENNARD_JONES_14_BCOEF'][i] = 0.0