def init_oop_terms(self, thresshold_zero=5e-2*angstrom): ''' Initialize all out-of-plane terms in the system based on the oops attribute of the system instance. All oops are given harmonic potentials. ''' with log.section('VAL', 3, 'Initializing'): #get all dihedrals from molmod.ic import opbend_dist, _opdist_low ffatypes = [self.system.ffatypes[fid] for fid in self.system.ffatype_ids] opdists = {} for opdist in self.system.iter_oops(): opdist, types = term_sort_atypes(ffatypes, opdist, 'opdist') if types in opdists.keys(): opdists[types].append(opdist) else: opdists[types] = [opdist] #loop over all distinct opdist types nharm = 0 nsq = 0 for types, oops in opdists.iteritems(): d0s = np.zeros(len(oops), float) for i, oop in enumerate(oops): if self.system.cell.nvec>0: d01 = self.system.pos[oop[1]]-self.system.pos[oop[0]] d02 = self.system.pos[oop[2]]-self.system.pos[oop[0]] d03 = self.system.pos[oop[3]]-self.system.pos[oop[0]] self.system.cell.mic(d01) self.system.cell.mic(d02) self.system.cell.mic(d03) d0s[i] = abs(_opdist_low(d01, d02, d03, 0)[0]) else: rs = np.array([#mind the order, is(or was) wrongly documented in molmod self.system.pos[oop[0]], self.system.pos[oop[1]], self.system.pos[oop[2]], self.system.pos[oop[3]], ]) d0s[i] = abs(opbend_dist(rs)[0]) if d0s.mean()<thresshold_zero: #TODO: check this thresshold #add regular term harmonic in oopdist for oop in oops: term = self.add_term(Harmonic, [OopDist(*oop)], types, ['HC_FC_DIAG'], ['kjmol/A**2', 'A']) self.set_params(term.index, rv0=0.0) nharm += 1 else: #add term harmonic in square of oopdist log.dump('Mean absolute value of OopDist %s is %.3e A, used SQOOPDIST' %('.'.join(types), d0s.mean()/angstrom)) for oop in oops: self.add_term(Harmonic, [SqOopDist(*oop)], types, ['PT_ALL', 'HC_FC_DIAG'], ['kjmol/A**4', 'A**2']) nsq += 1 log.dump('Added %i Harmonic and %i SquareHarmonic out-of-plane distance terms' %(nharm, nsq))
def test_opbend_ethene(): mol = Molecule.from_file(context.get_fn("test/ethene.xyz")) c = mol.coordinates.copy() assert abs(ic.opbend_cos([c[0], c[5], c[4], c[3]])[0] - 1.0) < 1e-5 assert abs(ic.opbend_angle([c[0], c[5], c[4], c[3]])[0]) < 1e-5 assert abs(ic.opbend_mcos([c[0], c[5], c[4], c[3]])[0] - 1.0) < 1e-5 assert abs(ic.opbend_mangle([c[0], c[5], c[4], c[3]])[0]) < 1e-5 assert abs(ic.opbend_dist([c[0], c[5], c[4], c[3]])[0]) < 1e-5 for i in xrange(1000): angle = np.random.uniform(-np.pi/2, np.pi/2) radius = np.random.uniform(0, 5*angstrom) #offset = np.random.uniform(0, 5*angstrom) c[3] = [ radius*np.cos(angle), 0.0, radius*np.sin(angle), ] assert abs(ic.opbend_cos([c[0], c[5], c[4], c[3]])[0] - np.cos(angle)) < 1e-5 assert abs(ic.opbend_angle([c[0], c[5], c[4], c[3]])[0] - angle) < 1e-5
def test_opbend_ethene(): mol = Molecule.from_file(context.get_fn("test/ethene.xyz")) c = mol.coordinates.copy() assert abs(ic.opbend_cos([c[0], c[5], c[4], c[3]])[0] - 1.0) < 1e-5 assert abs(ic.opbend_angle([c[0], c[5], c[4], c[3]])[0]) < 1e-5 assert abs(ic.opbend_mcos([c[0], c[5], c[4], c[3]])[0] - 1.0) < 1e-5 assert abs(ic.opbend_mangle([c[0], c[5], c[4], c[3]])[0]) < 1e-5 assert abs(ic.opbend_dist([c[0], c[5], c[4], c[3]])[0]) < 1e-5 for i in xrange(1000): angle = np.random.uniform(-np.pi / 2, np.pi / 2) radius = np.random.uniform(0, 5 * angstrom) #offset = np.random.uniform(0, 5*angstrom) c[3] = [ radius * np.cos(angle), 0.0, radius * np.sin(angle), ] assert abs(ic.opbend_cos([c[0], c[5], c[4], c[3]])[0] - np.cos(angle)) < 1e-5 assert abs(ic.opbend_angle([c[0], c[5], c[4], c[3]])[0] - angle) < 1e-5
def opbend_dist(self, *atoms): ''' distance plane 012 and vector 03''' return ic.opbend_dist([self.coordinates[i] for i in atoms])[0] / units.angstrom