def __init__(self, min1, min2, pot, mindist, database, verbosity=1, merge_minima=False, max_dist_merge=0.1, local_connect_params=None, fresh_connect=False, longest_first=True, niter=200, conf_checks=None ): self.minstart = min1 assert min1.id() == min1, "minima must compare equal with their id %d %s %s" % ( min1.id(), str(min1), str(min1.__hash__())) self.minend = min2 self.pot = pot self.mindist = mindist self.pairsNEB = dict() self.longest_first = longest_first self.niter = niter if conf_checks is None: self.conf_checks = [] else: self.conf_checks = conf_checks self.verbosity = int(verbosity) if local_connect_params is None: local_connect_params = dict() self.local_connect_params = dict([("verbosity", verbosity)] + list(local_connect_params.items())) self.database = database self.fresh_connect = fresh_connect if self.fresh_connect: self.graph = TSGraph(self.database, minima=[self.minstart, self.minend], no_edges=True) else: self.graph = TSGraph(self.database) self.merge_minima = merge_minima self.max_dist_merge = float(max_dist_merge) self.dist_graph = _DistanceGraph(self.database, self.graph, self.mindist, self.verbosity) # check if a connection exists before initializing distance graph if self.graph.areConnected(self.minstart, self.minend): logger.info("minima are already connected. not initializing distance graph") return self.dist_graph.initialize(self.minstart, self.minend) if self.verbosity > 0: logger.info("************************************************************") logger.info("starting a double ended connect run between") logger.info(" minimum 1: id %d energy %f" % (self.minstart.id(), self.minstart.energy)) logger.info(" minimum 2: id %d energy %f" % (self.minend.id(), self.minend.energy)) logger.info(" dist %f" % self.getDist(self.minstart, self.minend)) logger.info("************************************************************")
def test_merge_minima(self): graph = TSGraph(self.db) # select two minima with at least one edge minima = [] for n in graph.graph.nodes(): if graph.graph.degree(n) > 0: minima.append(n) if len(minima) == 2: break nedges = [graph.graph.degree(n) for n in minima] min1, min2 = minima neighbors = graph.graph.neighbors(min2) graph.mergeMinima(min1, min2) self.db.mergeMinima(min1, min2) self.assertNotIn(min2, graph.graph.nodes()) # make sure the edges were copied for n in neighbors: if n == min1: continue edge_exists = (graph.graph.has_edge(min1, n) or graph.graph.has_edge(n, min1)) self.assert_(edge_exists) # make sure the new edges have transition state data attached for v in graph.graph.neighbors(min1): data = graph.graph.get_edge_data(v, min1) self.assertIn("ts", list(data.keys())) # make sure min2 is not in database self.assertNotIn(min2, self.db.minima())
def test_minima_keyword(self): nmin = 3 minima = list(self.db.minima()) minima = minima[:nmin] graph = TSGraph(self.db, minima=minima, no_edges=True) ng = graph.graph.number_of_nodes() self.assertEqual(ng, nmin) self.assertEqual(graph.graph.number_of_edges(), 0)
def test_hi(self): graph = TSGraph(self.db) ng = graph.graph.number_of_nodes() nd = len(self.db.minima()) self.assertEqual(ng, nd, "all nodes not imported") ntsg = graph.graph.number_of_edges() ntsd = len(self.db.transition_states()) self.assertEqual(ntsg, ntsd, "all transition states not imported")
def test_disconn_graph(self, database): from pele.utils.disconnectivity_graph import DisconnectivityGraph from pele.landscape import TSGraph import matplotlib.pyplot as plt graph = TSGraph(database).graph dg = DisconnectivityGraph(graph, nlevels=3, center_gmin=True) dg.calculate() dg.plot() plt.show()
def test_connected_components(self): tsgraph = TSGraph(self.db) cc = list(nx.connected_components(tsgraph.graph)) for nodes in cc: for u, v in izip(nodes[:-1], nodes[1:]): self.assertTrue(tsgraph.areConnected(u, v)) for nodes1, nodes2 in izip(cc[:-1], cc[1:]): for u in nodes1: for v in nodes2: self.assertFalse(tsgraph.areConnected(u, v))
def test_connected_components(self): tsgraph = TSGraph(self.db) cc = nx.connected_components(tsgraph.graph) # networkx changed the function so now cc is an iterator over sets cc = [list(c) for c in cc] for nodes in cc: for u, v in zip(nodes[:-1], nodes[1:]): self.assertTrue(tsgraph.areConnected(u, v)) for nodes1, nodes2 in zip(cc[:-1], cc[1:]): for u in nodes1: for v in nodes2: self.assertFalse(tsgraph.areConnected(u, v))
def _build_list(self): if self.verbosity > 0: print "populating list of minima not connected to the global minimum" self.minpairs = deque() gmin = self.database.minima()[0] graph = TSGraph(self.database) for m in self.database.minima()[1:]: if not graph.areConnected(gmin, m): if self.is_good_pair(gmin, m): self.minpairs.append((gmin, m))
def _build_list(self): """make a list of minima pairs to try to connect""" print("analyzing the database to find minima to connect") self.minpairs = deque() graph = TSGraph(self.database).graph cclist = list(nx.connected_components(graph)) # remove clusters with fewer than clust_min cclist = [cc for cc in cclist if len(cc) >= self.clust_min] if len(cclist) == 0: print("all minima are connected") return self.minpairs # get the group that all other groups will be connected to group1 = cclist[0] min1 = sorted(group1, key=lambda m: m.energy)[0] if True: # make sure that the global minimum is in group1 global_min = self.database.minima()[0] if global_min not in group1: print( "warning, the global minimum is not the in the largest cluster. Will try to connect them" ) self.minpairs.append((min1, global_min)) # remove group1 from cclist cclist.remove(group1) # get a minimum from each of the other groups for group2 in cclist: if len(self.minpairs) > self.list_len: break print("adding groups of size", len(group1), "and", len(group2), "to the connect list") # sort the groups by energy group2 = sorted(group2, key=lambda m: m.energy) # select the lowest energy minima in the groups # (this can probably be done in a more intelligent way) min2 = group2[0] if self.is_good_pair(min1, min2): self.minpairs.append((min1, min2)) return self.minpairs
def on_btn_connect_in_optim_clicked(self, clicked=None): """spawn an OPTIM job and retrieve the minima and transition states it finds""" if clicked is None: return min1, min2 = self.get_selected_minima() # existing_minima = set(self.system.database.minima()) spawner = self.system.get_optim_spawner(min1.coords, min2.coords) spawner.run() db = self.system.database newminima, newts = spawner.load_results(self.system.database) # for m in newminima: # if m not in existing_minima: # self.NewMinimum(m) # now use DoubleEndedConnect to test if they are connected graph = TSGraph(db) if graph.areConnected(min1, min2): # use double ended connect to draw the interpolated path # this is ugly self._doubleEndedConnect(reconnect=False, min1min2=(min1, min2))
def _build_list(self): print("using disconnectivity analysis to find minima to untrap") self.minpairs = deque() graph = TSGraph(self.database).graph cclist = list(nx.connected_components(graph)) # get the largest cluster group1 = cclist[0] min1 = sorted(group1, key=lambda m: m.energy)[0] if not min1 == self.database.minima()[0]: # make sure that the global minimum is in group1 print( "warning, the global minimum is not the in the largest cluster." ) # compute the energy barriers for all minima in the cluster subgraph = nx.subgraph(graph, group1) energy_barriers = self._compute_barriers(subgraph, min1) # sort the minima by the barrier height divided by the energy difference weights = [(m, old_div(np.abs(barrier), np.abs(m.energy - min1.energy))) for (m, barrier) in energy_barriers.items()] weights.sort(key=lambda v: 1. / v[1]) self.minpairs = deque() for min2, w in weights: if len(self.minpairs) > self.list_len: break if not self.is_good_pair(min1, min2): continue self.minpairs.append((min1, min2)) if True: # print some stuff print(" untrap analysis: minimum", min2.id(), "with energy", min2.energy, "barrier", energy_barriers[min2], "untrap weight", w)
from __future__ import print_function from pele.utils.disconnectivity_graph import DisconnectivityGraph from pele.storage import Database from pele.landscape import TSGraph import pylab as pl import numpy as np kbT = 0.75 db = Database(db="tip4p_8.sqlite", createdb=False) graph = TSGraph(db) dg = DisconnectivityGraph(graph.graph, db.minima(), subgraph_size=20) dg.calculate() dg.plot() for m in db.minima(): if m.pgorder != 2: print(m.pgorder) m.free_energy = m.energy + kbT * 0.5*m.fvib + kbT*np.log(m.pgorder) for ts in db.transition_states(): # if ts.pgorder != 2: print(ts.pgorder) #assert ts.pgorder == 2 ts.free_energy = ts.energy + kbT * 0.5*ts.fvib + kbT*np.log(ts.pgorder) + kbT*np.log(kbT) if ts.free_energy > ts.minimum1.free_energy or ts.free_energy > ts.minimum2.free_energy: print("warning, free energy of transition state lower than minimum")
if min1 is min2: print( "Warning in single ended search: downhill search from transistion state ended in same minimum" ) ts = graph.addTransitionState(energy_ts, x_ts, min1, min2) print("found transition state: ", min1.id(), min2.id(), min1.energy, ts.energy, min2.energy) search.findNextTS() if __name__ == "__main__": from pele.landscape import TSGraph from .connect_min import getSetOfMinLJ natoms = 8 pot, saveit = getSetOfMinLJ(natoms) graph = TSGraph(saveit) minima = saveit.minima() find_escape_paths(minima[0], pot, graph, ntries=20) # print graph # for node in graph.graph.nodes(): # print node, node.energy for ts in graph.storage.transition_states(): print(ts.minimum1.id(), ts.minimum2.id(), "E", ts.minimum1.energy, ts.minimum2.energy, ts.minimum2.energy)