def log(self): rvecs = self.ff.system.cell.rvecs lengths, angles = self.ff.system.cell.parameters rvec_names = 'abc' angle_names = ['alpha', 'beta', 'gamma'] log(" ") log("Final Unit Cell:") log("----------------") log("- cell vectors:") for i in xrange(len(rvecs)): log(" %s = %s %s %s" %(rvec_names[i], log.length(rvecs[i,0]), log.length(rvecs[i,1]), log.length(rvecs[i,2]) )) log(" ") log("- lengths, angles and volume:") for i in xrange(len(rvecs)): log(" |%s| = %s" % (rvec_names[i], log.length(lengths[i]))) for i in xrange(len(angles)): log(" %5s = %s" % (angle_names[i], log.angle(angles[i]))) log(" volume = %s" % log.volume(self.ff.system.cell.volume) )
def _need_rebuild(self): '''Internal method that determines if a rebuild is needed.''' if self.skin <= 0 or self._pos_old is None or self.rebuild_next: return True else: # Compute an upper bound for the maximum relative displacement. disp = np.sqrt(((self.system.pos - self._pos_old)**2).sum(axis=1).max()) disp *= 2*(self.rmax.max()+1) if log.do_debug: log('Maximum relative displacement %s Skin %s' % (log.length(disp), log.length(self.skin))) # Compare with skin parameter return disp >= self.skin
def _init_log(self): if log.do_medium: log('Unit cell') log.hline() log('Number of periodic dimensions: %i' % self.cell.nvec) lengths, angles = self.cell.parameters names = 'abc' for i in xrange(len(lengths)): log('Cell parameter %5s: %10s' % (names[i], log.length(lengths[i]))) names = 'alpha', 'beta', 'gamma' for i in xrange(len(angles)): log('Cell parameter %5s: %10s' % (names[i], log.angle(angles[i]))) log.hline() log.blank()
def __call__(self, iterative): if log.do_medium: if self.time0 is None: self.time0 = time.time() if log.do_medium: log.hline() log('Cons.Err. =&the root of the ratio of the variance on the conserved quantity and the variance on the kinetic energy.') log('d-rmsd =&the root-mean-square displacement of the atoms.') log('g-rmsd =&the root-mean-square gradient of the energy.') log('counter Cons.Err. Temp d-RMSD g-RMSD Walltime') log.hline() log('%7i %10.5f %s %s %s %10.1f' % ( iterative.counter, iterative.cons_err, log.temperature(iterative.temp), log.length(iterative.rmsd_delta), log.force(iterative.rmsd_gpos), time.time() - self.time0, ))
def __init__(self, system, nlist, scalings, pair_pot): ''' **Arguments:** system The system to which this pairwise interaction applies. nlist A ``NeighborList`` object. This has to be the same as the one passed to the ForceField object that contains this part. scalings A ``Scalings`` object. This object contains all the information about the energy scaling of pairwise contributions that are involved in covalent interactions. See :class:`yaff.pes.scalings.Scalings` for more details. pair_pot An instance of the ``PairPot`` built-in class from :mod:`yaff.pes.ext`. ''' ForcePart.__init__(self, 'pair_%s' % pair_pot.name, system) self.nlist = nlist self.scalings = scalings self.pair_pot = pair_pot self.nlist.request_rcut(pair_pot.rcut) if log.do_medium: with log.section('FPINIT'): log('Force part: %s' % self.name) log.hline() log(' scalings: %5.3f %5.3f %5.3f' % (scalings.scale1, scalings.scale2, scalings.scale3)) log(' real space cutoff: %s' % log.length(pair_pot.rcut)) tr = pair_pot.get_truncation() if tr is None: log(' truncation: none') else: log(' truncation: %s' % tr.get_log()) self.pair_pot.log() log.hline()
def check(self): """Perform a slow internal consistency test. Use this for debugging only. It is assumed that self.rmax is set correctly. """ # 0) Some initial tests assert ( (self.neighs['a'][:self.nneigh] > self.neighs['b'][:self.nneigh]) | (self.neighs['r0'][:self.nneigh] != 0) | (self.neighs['r1'][:self.nneigh] != 0) | (self.neighs['r2'][:self.nneigh] != 0) ).all() # A) transform the current nlist into a set actual = self.to_dictionary() # B) Define loops of cell vectors if self.system.cell.nvec == 3: def rloops(): for r2 in xrange(0, self.rmax[2]+1): if r2 == 0: r1_start = 0 else: r1_start = -self.rmax[1] for r1 in xrange(r1_start, self.rmax[1]+1): if r2 == 0 and r1 == 0: r0_start = 0 else: r0_start = -self.rmax[0] for r0 in xrange(r0_start, self.rmax[0]+1): yield r0, r1, r2 elif self.system.cell.nvec == 2: def rloops(): for r1 in xrange(0, self.rmax[1]+1): if r1 == 0: r0_start = 0 else: r0_start = -self.rmax[0] for r0 in xrange(r0_start, self.rmax[0]+1): yield r0, r1, 0 elif self.system.cell.nvec == 1: def rloops(): for r0 in xrange(0, self.rmax[0]+1): yield r0, 0, 0 else: def rloops(): yield 0, 0, 0 # C) Compute the nlists the slow way validation = {} nvec = self.system.cell.nvec for r0, r1, r2 in rloops(): for a in xrange(self.system.natom): for b in xrange(a+1): if r0!=0 or r1!=0 or r2!=0: signs = [1, -1] elif a > b: signs = [1] else: continue for sign in signs: delta = self.system.pos[b] - self.system.pos[a] self.system.cell.mic(delta) delta *= sign if nvec > 0: self.system.cell.add_vec(delta, np.array([r0, r1, r2])[:nvec]) d = np.linalg.norm(delta) if d < self.rcut + self.skin: if sign == 1: key = a, b, r0, r1, r2 else: key = b, a, r0, r1, r2 value = np.array([d, delta[0], delta[1], delta[2]]) validation[key] = value # D) Compare wrong = False with log.section('NLIST'): for key0, value0 in validation.iteritems(): value1 = actual.pop(key0, None) if value1 is None: log('Missing: ', key0) log(' Validation %s %s %s %s' % ( log.length(value0[0]), log.length(value0[1]), log.length(value0[2]), log.length(value0[3]) )) wrong = True elif abs(value0 - value1).max() > 1e-10*log.length.conversion: log('Different:', key0) log(' Actual %s %s %s %s' % ( log.length(value1[0]), log.length(value1[1]), log.length(value1[2]), log.length(value1[3]) )) log(' Validation %s %s %s %s' % ( log.length(value0[0]), log.length(value0[1]), log.length(value0[2]), log.length(value0[3]) )) log(' Difference %10.3e %10.3e %10.3e %10.3e' % tuple((value0 - value1)/log.length.conversion) ) log(' AbsMaxDiff %10.3e' % (abs(value0 - value1).max()/log.length.conversion) ) wrong = True for key1, value1 in actual.iteritems(): log('Redundant:', key1) log(' Actual %s %s %s %s' % ( log.length(value1[0]), log.length(value1[1]), log.length(value1[2]), log.length(value1[3]) )) wrong = True assert not wrong
def check_mic(self, system): '''Check if each scale2 and scale3 are uniquely defined. **Arguments:** system An instance of the system class, i.e. the one that is used to create this scaling object. This check is done by constructing for each scaled pair, all possible bond paths between the two atoms. For each path, the bond vectors (after applying the minimum image convention) are added. If for a given pair, these sums of bond vectors differ between all possible paths, the differences are expanded in cell vectors which can be used to construct a proper supercell in which scale2 and scale3 pairs are all uniquely defined. ''' if system.cell.nvec == 0: return troubles = False with log.section('SCALING'): for i0, i1, scale, nbond in self.stab: if nbond == 1: continue all_deltas = [] paths = [] for path in iter_paths(system, i0, i1, nbond): delta_total = 0 for j0 in xrange(nbond): j1 = j0 + 1 delta = system.pos[path[j0]] - system.pos[path[j1]] system.cell.mic(delta) delta_total += delta all_deltas.append(delta_total) paths.append(path) all_deltas = np.array(all_deltas) if abs(all_deltas.mean(axis=0) - all_deltas).max() > 1e-10: troubles = True if log.do_warning: log.warn('Troublesome pair scaling detected.') log('The following bond paths connect the same pair of ' 'atoms, yet the relative vectors are different.') for ipath in xrange(len(paths)): log('%2i %27s %10s %10s %10s' % ( ipath, ','.join(str(index) for index in paths[ipath]), log.length(all_deltas[ipath,0]), log.length(all_deltas[ipath,1]), log.length(all_deltas[ipath,2]), )) log('Differences between relative vectors in fractional ' 'coordinates:') for ipath0 in xrange(1, len(paths)): for ipath1 in xrange(ipath0): diff = all_deltas[ipath0] - all_deltas[ipath1] diff_frac = np.dot(system.cell.gvecs, diff) log('%2i %2i %10.4f %10.4f %10.4f' % ( ipath0, ipath1, diff_frac[0], diff_frac[1], diff_frac[2] )) log.blank() if troubles: raise AssertionError('Due to the small spacing between some crystal planes, the scaling of non-bonding interactions will not work properly. Use a supercell to avoid this problem.')
def check(self): """Perform a slow internal consistency test. Use this for debugging only. It is assumed that self.rmax is set correctly. """ # 0) Some initial tests assert ( (self.neighs['a'][:self.nneigh] > self.neighs['b'][:self.nneigh]) | (self.neighs['r0'][:self.nneigh] != 0) | (self.neighs['r1'][:self.nneigh] != 0) | (self.neighs['r2'][:self.nneigh] != 0)).all() # A) transform the current nlist into a set actual = self.to_dictionary() # B) Define loops of cell vectors if self.system.cell.nvec == 3: def rloops(): for r2 in range(0, self.rmax[2] + 1): if r2 == 0: r1_start = 0 else: r1_start = -self.rmax[1] for r1 in range(r1_start, self.rmax[1] + 1): if r2 == 0 and r1 == 0: r0_start = 0 else: r0_start = -self.rmax[0] for r0 in range(r0_start, self.rmax[0] + 1): yield r0, r1, r2 elif self.system.cell.nvec == 2: def rloops(): for r1 in range(0, self.rmax[1] + 1): if r1 == 0: r0_start = 0 else: r0_start = -self.rmax[0] for r0 in range(r0_start, self.rmax[0] + 1): yield r0, r1, 0 elif self.system.cell.nvec == 1: def rloops(): for r0 in range(0, self.rmax[0] + 1): yield r0, 0, 0 else: def rloops(): yield 0, 0, 0 # C) Compute the nlists the slow way validation = {} nvec = self.system.cell.nvec for r0, r1, r2 in rloops(): for a in range(self.system.natom): for b in range(a + 1): if r0 != 0 or r1 != 0 or r2 != 0: signs = [1, -1] elif a > b: signs = [1] else: continue for sign in signs: delta = self.system.pos[b] - self.system.pos[a] self.system.cell.mic(delta) delta *= sign if nvec > 0: self.system.cell.add_vec( delta, np.array([r0, r1, r2])[:nvec]) d = np.linalg.norm(delta) if d < self.rcut + self.skin: if sign == 1: key = a, b, r0, r1, r2 else: key = b, a, r0, r1, r2 value = np.array([d, delta[0], delta[1], delta[2]]) validation[key] = value # D) Compare wrong = False with log.section('NLIST'): for key0, value0 in validation.items(): value1 = actual.pop(key0, None) if value1 is None: log('Missing: ', key0) log(' Validation %s %s %s %s' % (log.length(value0[0]), log.length(value0[1]), log.length(value0[2]), log.length(value0[3]))) wrong = True elif abs(value0 - value1).max() > 1e-10 * log.length.conversion: log('Different:', key0) log(' Actual %s %s %s %s' % (log.length(value1[0]), log.length(value1[1]), log.length(value1[2]), log.length(value1[3]))) log(' Validation %s %s %s %s' % (log.length(value0[0]), log.length(value0[1]), log.length(value0[2]), log.length(value0[3]))) log(' Difference %10.3e %10.3e %10.3e %10.3e' % tuple( (value0 - value1) / log.length.conversion)) log(' AbsMaxDiff %10.3e' % (abs(value0 - value1).max() / log.length.conversion)) wrong = True for key1, value1 in actual.items(): log('Redundant:', key1) log(' Actual %s %s %s %s' % (log.length(value1[0]), log.length(value1[1]), log.length(value1[2]), log.length(value1[3]))) wrong = True assert not wrong