def qDist(x, y): d1 = 0.43 d2 = 0.85 if state(x, y) == -1: return 0.0 elif state(x, y) == 1: return 1.0 elif (x - 1.15)**2 + y**2 >= (2.0 * 1.15 - d1)**2: return 0.0 elif (x - 1.15)**2 + y**2 <= d2**2: return 1.0 else: return 1.0 - (np.sqrt( (x - 1.15)**2 + y**2) - d2) / (2 * 1.15 - d1 - d2)
def dqDist(x, y): d1 = 0.43 d2 = 0.85 if state(x, y) == -1: return 0.0, 0.0 elif state(x, y) == 1: return 0.0, 0.0 elif (x - 1.15)**2 + y**2 >= (2.0 * 1.15 - d1)**2: return 0.0, 0.0 elif (x - 1.15)**2 + y**2 <= d2**2: return 0.0, 0.0 else: return -(x - 1.15) / ( (2 * 1.15 - d1 - d2) * np.sqrt((x - 1.15)**2 + y**2)), -y / ( (2 * 1.15 - d1 - d2) * np.sqrt((x - 1.15)**2 + y**2))
def Lang(ncomm, q0, tstep, temperature, isteps): # Define preliminary variables q = np.empty((isteps, 2), dtype=np.float64) q_trans = np.empty((isteps, 2), dtype=np.float64) # Initial conditions q[0, 0] = q0[0] q[0, 1] = q0[1] # Diffusion coefficient Dt = np.sqrt(2.0 * temperature * tstep) # Index for the transition trajectory j = 0 for i in range(isteps - 1): # Evaluate evolution of the system fx, fy = force(q[i, 0], q[i, 1]) q[i + 1, 0] = q[i, 0] + fx * tstep + Dt * np.random.normal(0, 1) q[i + 1, 1] = q[i, 1] + fy * tstep + Dt * np.random.normal(0, 1) if state(q[i + 1, 0], q[i + 1, 1]) == 0: q_trans[j, :] = q[i + 1, :] j += 1 if j == 0: out = np.empty((1, 2), dtype=np.float64) out[0, 0] = 0.0 out[0, 1] = 0.0 return out else: return q_trans[:j, :]
def LangM(ncomm, q0, tstep, temperature, isteps): # Define preliminary variables q = np.empty((isteps, 2), dtype=np.float64) q_trans = np.empty((isteps, 2), dtype=np.float64) M = np.empty((isteps, ncomm, ncomm), dtype=np.float64) dGx = np.empty(ncomm, dtype=np.float64) dGy = np.empty(ncomm, dtype=np.float64) # Initial conditions q[0, 0] = q0[0] q[0, 1] = q0[1] # Diffusion coefficient Dt = np.sqrt(2.0 * temperature * tstep) # Index for the transition trajectory j = 0 for i in range(isteps - 1): # Evaluate evolution of the system fx, fy = force(q[i, 0], q[i, 1]) q[i + 1, 0] = q[i, 0] + fx * tstep + Dt * np.random.normal(0, 1) q[i + 1, 1] = q[i, 1] + fy * tstep + Dt * np.random.normal(0, 1) if state(q[i + 1, 0], q[i + 1, 1]) == 0: # Gradient components of the committors for k in range(ncomm): dGx[k], dGy[k] = ListdGuess(k, q[i + 1, 0], q[i + 1, 1]) # Evaluating M Matrix for k in range(ncomm): for l in range(ncomm): M[j, k, l] = dGx[k] * dGx[l] + dGy[k] * dGy[l] q_trans[j, :] = q[i + 1, :] j += 1 if j == 0: out = np.empty((1, 2), dtype=np.float64) out[0, 0] = 0.0 out[0, 1] = 0.0 outM = np.empty((1, ncomm, ncomm), dtype=np.float64) for k in range(ncomm): for l in range(ncomm): outM[i, k, l] = 0.0 return out, outM else: return q_trans[:j, :], M[:j, :, :]
def main(): print("Algorithm has started") ## Parameters of the run ncomm = 0 # Number of guess committors temperature = 1.0 # Temperature tstep = 0.01 # time interval for MD simulations kratchet = 150 # Force constant of the ratchet MDsteps = 10000 # Maximum number of steps fo MD simulations biassim = 1000 # Number of bias simulations used to sample transition region selfsteps = 5 # Number of self consistent iterations alpha = 0.5 # Percentage of previous iteration in self consistent step threshold = 0.001 # Threshold for the end of the self consistent part relax = 5 # How often do we pick a point of a biased trajectory as starting point of a MD trajectory relaxation = False # If true, we do a relaxation after we estimate the transition probability with the biased simulations ## Limits of the plots xlimleft = -2.0 xlimright = 2.0 ylimdown = -2.5 ylimup = 1.5 delta = 0.025 ## Name of file if we want to save the evolution of the coefficients of the committor during the self consistent savecoeff = False namecoeff = "" ## Parameters of plots axisticslabelfontsize = 9 axisticslabelfontsizeinset = 7 axislabelfontsize = 11 axislabelfontsizeinset = 9 legendfontsize = 7 lineswidth = 2 ncontour = 25 cmap = plt.get_cmap('RdBu') ## Name of file if we want to save the trajectories of the last run savetraj = False savetraj = "" ## Name of file if we want to save transition probability distribution plot saveprob = False nameprob = "" with open("input", "r") as f: for line in f: line = re.sub("#.*$", "", line) line = re.sub(" *$", "", line) words = line.split() if len(words) == 0: continue key = words[0] if key == "ncomm": ncomm = int(words[1]) elif key == "temperature": temperature = float(words[1]) elif key == "tstep": tstep = float(words[1]) elif key == "kratchet": kratchet = float(words[1]) elif key == "MDsteps": MDsteps = int(words[1]) elif key == "biassim": biassim = int(words[1]) elif key == "selfsteps": selfsteps = int(words[1]) elif key == "alpha": alpha = float(words[1]) elif key == "threshold": threshold = float(words[1]) elif key == "relaxation": if re.match("[Tt].*", words[1]): relaxation = True elif key == "relax": relax = int(words[1]) elif key == "xlimleft": xlimleft = float(words[1]) elif key == "xlimright": xlimright = float(words[1]) elif key == "ylimdown": ylimdown = float(words[1]) elif key == "ylimup": ylimup = float(words[1]) elif key == "delta": delta = float(words[1]) elif key == "namecoeff": savecoeff = True namecoeff = words[1] elif key == "nametraj": savetraj = True nametraj = words[1] elif key == "nameprob": saveprob = True nameprob = words[1] elif key == "axisticslabelfontsize": axisticslabelfontsize = int(words[1]) elif key == "axisticslabelfontsizeinset": axisticslabelfontsizeinset = int(words[1]) elif key == "axislabelfontsize": axislabelfontsize = int(words[1]) elif key == "axislabelfontsizeinset": axislabelfontsizeinset = int(words[1]) elif key == "legendfontsize": legendfontsize = int(words[1]) elif key == "lineswidth": lineswidth = float(words[1]) elif key == "ncontour": ncontour = int(words[1]) else: raise Exception("Unknown keyword: " + key) if ncomm == 0: raise Exception("Specify the number of guess committors") print("Parameters loaded correctly") ## Prepare the contour lines for the potential and the basins xcontour = np.arange(xlimleft, xlimright, 0.025) ycontour = np.arange(ylimdown, ylimup, 0.025) X, Y = np.meshgrid(xcontour, ycontour) # Potential CONT = X * 0 for i in range(X.shape[0]): for j in range(X.shape[1]): CONT[i, j] = potential(X[i, j], Y[i, j]) # Basins BASINS = X * 0 for i in range(X.shape[0]): for j in range(X.shape[1]): BASINS[i, j] = state(X[i, j], Y[i, j]) levelsb = [-1.0, 0.0, 1.0] ## Prepare the grid for the plots yplot, xplot = np.mgrid[slice(ylimdown, ylimup + delta, delta), slice(xlimleft, xlimright + delta, delta)] ## I do the self consistent operation print("Cycle = ", 1) co = np.array([1.0 / ncomm for i in range(ncomm)]) print(co) if savecoeff == True: cprint = [] cprint.append(co) print("Cycle = ", 2) M = BiasRuns(ncomm, co, tstep, temperature, kratchet, MDsteps, biassim, relaxation, relax) print(M) c = minimization(co, M, ncomm) print(c) if savecoeff == True: cprint.append(c) # I iterate the previous procedure many times k = 0 while k < selfsteps - 2 and np.any(c - co > threshold): print("Cycle = ", k + 3) M = BiasRuns(ncomm, alpha * c + (1.0 - alpha) * co, tstep, temperature, kratchet, MDsteps, biassim, relaxation, relax) print(M) cn = minimization(alpha * c + (1.0 - alpha) * co, M, ncomm) co = np.copy(c) c = np.copy(cn) print(c) k += 1 if savecoeff == True: cprint.append(c) ## I save the coefficients of the linear combination if savecoeff == True: cprint = np.array(cprint) with open(namecoeff, "w") as f: np.savetxt(f, cprint, fmt="%10.10f") print("Coefficients saved correctly") ## Relaxation of the last iteration if savetraj == True or saveprob == True: tmp = 0 for j in range(biassim): q0 = start_pos() biastraj = RatchetLang(c, q0, tstep, temperature, kratchet, MDsteps) if biastraj[0, 0] != 0.0 and biastraj[0, 1] != 0.0: q0Lang = biastraj[1::5, :] for i in range(q0Lang.shape[0]): traj, M = LangM(ncomm, q0Lang[i, :], tstep, temperature, relax) # I run the integrator if traj[0, 0] != 0 and traj[0, 1] != 0: if tmp == 0: trajall = np.copy(traj) Mall = np.copy(M) tmp = 1 if tmp == 1: trajall = np.concatenate((trajall, traj), axis=0) Mall = np.concatenate((Mall, M), axis=0) del traj, M del biastraj M = np.zeros((ncomm, ncomm), dtype=np.float64) # Average all the values of M for k in range(Mall.shape[0]): for i in range(ncomm): for j in range(ncomm): M[i, j] += Mall[k, i, j] # Average M over all the values obtained with the sampling M /= Mall.shape[0] ## Evaluate the rate rate = 0.0 for i in range(ncomm): for j in range(ncomm): rate += M[i, j] * c[i] * c[j] rate *= np.sqrt(2.0 * temperature) print("Rate of optimal linear combination: ", rate) ## I do the plot of the Langevin trajectories if savetraj == True: with PdfPages(nametraj) as pdf: fmt1 = '%r %%' fig = plt.figure(figsize=(4., 2.8)) plt.rc('text') panel = fig.add_axes([ 0.15, 0.15, 0.72, 0.75 ]) # dimensions and location of the panel within the figure # Potential pcm = panel.plot(trajall[:, 0], trajall[:, 1], linewidth=0.5, zorder=10) panel.set_xlabel( r'$x$', fontsize=axislabelfontsize, labelpad=2 ) # labels and ticklabels along x with their fontsize and location, x limits and same for y below for tick in panel.xaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_xlim(xlimleft - delta, xlimright + delta) panel.xaxis.set_major_locator(MultipleLocator(1)) panel.xaxis.set_minor_locator(MultipleLocator(0.2)) panel.set_ylabel(r'$y$', fontsize=axislabelfontsize, labelpad=2) for tick in panel.yaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_ylim(ylimdown - delta, ylimup + delta) panel.yaxis.set_major_locator(MultipleLocator(1)) panel.yaxis.set_minor_locator(MultipleLocator(0.2)) CS = panel.contour(X, Y, CONT, ncontour, colors='k', linewidths=0.5, zorder=0) plt.clabel(CS, fontsize=4, inline=1) contour = panel.contour(X, Y, BASINS, levels=levelsb, colors="orange", linewidths=0.5, linestyles='dashed', zorder=5) plt.title("Trajectories") # title pdf.savefig(fig) print("Trajectories plotted successfully") ## I do the plot of the probability distribution in the transition region if saveprob == True: with PdfPages(nameprob) as pdf: fmt1 = '%r %%' fig = plt.figure(figsize=(4., 2.8)) plt.rc('text') panel = fig.add_axes([ 0.15, 0.15, 0.72, 0.75 ]) # dimensions and location of the panel within the figure # Borders of the plot xedges = np.arange(xlimleft, xlimright, delta).tolist() yedges = np.arange(ylimdown, ylimup, delta).tolist() # Create the histogram H, xedges, yedges = np.histogram2d(trajall[:, 0], trajall[:, 1], bins=(xedges, yedges), density=True) H = H.T # Let each row list bins with common y range. pcm = panel.imshow( H, interpolation='nearest', origin='low', extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]]) cbar = plt.colorbar(pcm, format=ticker.FuncFormatter( fmt)) # plot colorbar and select format cbar.ax.tick_params(labelsize=axisticslabelfontsize - 2) # dimension of the labels of the colorbar pcm.set_cmap('RdBu') panel.set_xlabel( r'$x$', fontsize=axislabelfontsize, labelpad=2 ) # labels and ticklabels along x with their fontsize and location, x limits and same for y below for tick in panel.xaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_xlim(xlimleft - delta, xlimright + delta) panel.xaxis.set_major_locator(MultipleLocator(1)) panel.xaxis.set_minor_locator(MultipleLocator(0.2)) panel.set_ylabel(r'$y$', fontsize=axislabelfontsize, labelpad=2) for tick in panel.yaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_ylim(ylimdown - delta, ylimup + delta) panel.yaxis.set_major_locator(MultipleLocator(1)) panel.yaxis.set_minor_locator(MultipleLocator(0.2)) # Potential CS = panel.contour(X, Y, CONT, ncontour, colors='k', linewidths=0.5) plt.clabel(CS, fontsize=4, inline=1) contour = panel.contour(X, Y, BASINS, levels=levelsb, colors="white", linewidths=0.5, linestyles='dashed') plt.title("Transition probability distribution") # title pdf.savefig(fig) print("Transition probability distribution plotted successfully")
def RatchetLangM(c, q0, tstep, temperature, kr, isteps): ## Number of committor functions given as input ncomm = len(c) # Define preliminary variables q = np.empty((isteps, 2), dtype=np.float64) M = np.empty((isteps, ncomm, ncomm), dtype=np.float64) dGx = np.empty(ncomm, dtype=np.float64) dGy = np.empty(ncomm, dtype=np.float64) # Assign initial position to the border of the reactant state q[0, 0] = q0[0] q[0, 1] = q0[1] # Incremental variables in the loop i = 0 j = 0 tmp = 0 # State of the point. If in reactant = -1, if in product = 1, otherwise = 0 s = state(q[0, 0], q[1, 1]) zmax = 0.0 # Diffusion coefficient Dt = np.sqrt(2.0 * temperature * tstep) while i < isteps - 1 and tmp == 0: if s == -1: # Restart trajectory j = i elif s == 1: #Exit from loop tmp = 1 # Evaluate evolution of the system fx, fy = force(q[i, 0], q[i, 1]) # Evaluate z z = 0.0 for k in range(ncomm): z += c[k] * ListGuess(k, q[i, 0], q[i, 1]) # Gradient components of the committors for k in range(ncomm): dGx[k], dGy[k] = ListdGuess(k, q[i, 0], q[i, 1]) # Evaluating M Matrix for k in range(ncomm): for l in range(ncomm): M[i, k, l] = dGx[k] * dGx[l] + dGy[k] * dGy[l] # Dynamics if z > zmax: q[i + 1, 0] = q[i, 0] + fx * tstep + Dt * np.random.normal(0, 1) q[i + 1, 1] = q[i, 1] + fy * tstep + Dt * np.random.normal(0, 1) zmax = z else: ratchetx = 0.0 ratchety = 0.0 for k in range(ncomm): ratchetx += c[k] * dGx[k] ratchety += c[k] * dGy[k] q[i + 1, 0] = q[i, 0] + fx * tstep + Dt * np.random.normal( 0, 1) + kr * ratchetx * (zmax - z) * tstep q[i + 1, 1] = q[i, 1] + fy * tstep + Dt * np.random.normal( 0, 1) + kr * ratchety * (zmax - z) * tstep i += 1 s = state(q[i, 0], q[i, 1]) # Output in the case we do not find a reactive coordinate, so that the function does not crash if tmp == 0: print('No reactive trajectory found!') out = np.empty((1, 2), dtype=np.float64) out[0, 0] = 0.0 out[0, 1] = 0.0 outM = np.empty((1, ncomm, ncomm), dtype=np.float64) for k in range(ncomm): for l in range(ncomm): outM[i, k, l] = 0.0 return out, outM return q[j + 1:i - 1, :], M[j + 1:i - 1, :, :]
def main(): print("Algorithm has started") ## Parameters of the run temperature = 1.0 # Temperature diffusion = 1.0 # diffusion coefficient tstep = 0.01 # time interval for MD simulations Nsim = 1000 # Number of MD simulations to determine boundary conditions stepsim = 5000 # maximum number of steps for MD simulations ## Parameters of the grid xlimleft = -3.0 xlimright = 3.0 nxstep = 50 ylimdown = -3.0 ylimup = 3.0 nystep = 50 ## Name of file if we want to save the committor savefile = False namefile = "" ## Parameters if we want to save committor plot saveplot = False nameplot = "" axisticslabelfontsize = 9 axisticslabelfontsizeinset = 7 axislabelfontsize = 11 axislabelfontsizeinset = 9 legendfontsize = 7 lineswidth = 2 ncontour = 25 with open("input", "r") as f: for line in f: line = re.sub("#.*$", "", line) line = re.sub(" *$", "", line) words = line.split() if len(words) == 0: continue key = words[0] if key == "temperature": temperature = float(words[1]) elif key == "diffusion": diffusion = float(words[1]) elif key == "tstep": tstep = float(words[1]) elif key == "Nsim": Nsim = int(words[1]) elif key == "stepsim": stepsim = int(words[1]) elif key == "tstep": tstep = float(words[1]) elif key == "xlimleft": xlimleft = float(words[1]) elif key == "xlimright": xlimright = float(words[1]) elif key == "nxstep": nxstep = int(words[1]) elif key == "ylimup": ylimup = float(words[1]) elif key == "ylimdown": ylimdown = float(words[1]) elif key == "nystep": nystep = int(words[1]) elif key == "namefile": savefile = True namefile = words[1] elif key == "nameplot": saveplot = True nameplot = words[1] elif key == "axisticslabelfontsize": axisticslabelfontsize = int(words[1]) elif key == "axisticslabelfontsizeinset": axisticslabelfontsizeinset = int(words[1]) elif key == "axislabelfontsize": axislabelfontsize = int(words[1]) elif key == "axislabelfontsizeinset": axislabelfontsizeinset = int(words[1]) elif key == "legendfontsize": legendfontsize = int(words[1]) elif key == "lineswidth": lineswidth = float(words[1]) elif key == "ncontour": ncontour = int(words[1]) else: raise Exception("Unknown keyword: " + key) print("Parameters loaded correctly") x = np.linspace(xlimleft, xlimright, nxstep) y = np.linspace(ylimdown, ylimup, nystep) beta = 1.0 / temperature # 1/k_{B}T dx = x[1] - x[0] # step of the grid along the x direction dy = y[1] - y[0] # step of the grid along the y direction I = len(x) - 1 # index of the last cell along x J = len(y) - 1 # index of the last cell along y N = I * ( J + 1 ) + J # index of the last cell in the 1D vector that contains all the I*(J+1)+J+1 = N+1 cells in the system q = np.zeros( shape=(N + 1) ) # vector that contains the N+1 values of the committor for each grid point P = np.zeros( shape=(N + 1, N + 1) ) # matrix with (N+1)*(N+1) elements, that determines the linear system to solve P*q = R R = np.zeros(shape=( N + 1 )) # vector with the N+1 elements of results of the backward F-P equation bd = 0 # counter for boundary points on which the MD is finished ## Precompute some coefficients D1 = diffusion * beta * tstep D2 = np.sqrt(2. * diffusion * tstep) print("Total number of boundary points = ", 2 * (nxstep + nystep) - 4) now = time.time() # construction of P and R i = 0 while i < len(x): xp = x[i] j = 0 while j < len(y): yp = y[j] Fx, Fy = force(xp, yp) n = i * ( J + 1 ) + j # for each grid point i,j computes the corresponding index n in the 1D vectors and computes the coefficients A,B,C,D,E A = diffusion / (dx**2) + (beta * diffusion * Fx) / (2 * dx) B = 2. * diffusion / (dx**2) + 2. * diffusion / (dy**2) C = diffusion / (dx**2) - (beta * diffusion * Fx) / (2 * dx) D = diffusion / (dy**2) + (beta * diffusion * Fy) / (2 * dy) E = diffusion / (dy**2) - (beta * diffusion * Fy) / (2 * dy) if state( xp, yp ) != 0: # if you are inside the reactant basin or the product basin impose boundary condition of q = 0 in Reactant and q = 1 in Product P[n, n] = 1. if xp > 0.: R[n] = 1. elif ( (i == 0) or (i == I) ): # if you are on the two boundaries along x, do MD simulations for each boundary point to find the committor on the edges of the grid t = 0 nr = 0 nt = 0 while t < Nsim: # 1000 trajectories for each point xi = x[ i] # for each trajectory in a given grid point on the edge, set as initial conditions the coordinates of that grid point yi = y[j] k = 0 while ( state(xi, yi) == 0 and k < stepsim ): # keep evolving the system untill you enter in Reactant or Product Fx, Fy = force(xi, yi) xf = xi + Fx * D1 + D2 * np.random.normal( loc=0., scale=1. ) # evolve x and y with the equations of motion for a passive particle performing brownian motion in a potential energy landscape yf = yi + Fy * D1 + D2 * np.random.normal(loc=0., scale=1.) xi = xf yi = yf k += 1 if xf < 0.: # if you enter in Reactant nr += 1 elif xf > 0.: # if you enter in Product nt += 1 t += 1 if t != (nt + nr): # just a check print("Something wrong occurred during MD simulation!") bd += 1 print( bd ) # print the index of the boundary point in which you finished the MD simulations P[n, n] = 1. R[n] = nt / (nt + nr) # value of the committor in that point elif ( (i != 0) and (i != I) and ((j == 0) or (j == J)) ): # if you are on the boundaries along y do MD simulation for each grid point on the boundary, except those included in the boundaries of x that are already done t = 0 nr = 0 nt = 0 while t < Nsim: xi = x[i] yi = y[j] k = 0 while (state(xi, yi) == 0 and k < stepsim): Fx, Fy = force(xi, yi) xf = xi + Fx * D1 + D2 * np.random.normal(loc=0., scale=1.) yf = yi + Fy * D1 + D2 * np.random.normal(loc=0., scale=1.) xi = xf yi = yf k += 1 if xf < 0.: nr += 1 elif xf > 0.: nt += 1 t += 1 if t != (nt + nr): print("Something wrong occurred during MD simulation!") bd += 1 print(bd) P[n, n] = 1. R[n] = nt / (nt + nr) else: # if you are in every other point of the grid fill the P matrix according to the usual pattern P[n, (i - 1) * (J + 1) + j] = C P[n, i * (J + 1) + j - 1] = E P[n, i * (J + 1) + j] = -B P[n, i * (J + 1) + j + 1] = D P[n, (i + 1) * (J + 1) + j] = A j += 1 i += 1 print("System initialized") q = scipy.linalg.solve(P, R) # solve linear system to find the committor for el in q: if el > 1.: # some errors in the solution of the system are inevitable, so don't mind if you get some of these errors, as long as the values of the committor are not too much larger than 1 or too much smaller than 0 print("Error! Committor larger than 1!") elif el < 0.: print("Error! Committor smaller than 0!") q = np.reshape( q, (I + 1, J + 1)) # reshape the committor from 1D vector to 2D grid print("Simulation time ", time.time() - now) # Save committor on a File if savefile == True: with open(namefile, "w") as f: np.savetxt(f, q, fmt="%10.10f") print("Committor saved correctly") # Make the plot if saveplot == True: xplot = np.empty(shape=( len(x) + 1 )) # set x and y coordinates for the edges of the bins in the grid yplot = np.empty(shape=(len(y) + 1)) k = 0 for el in x: xplot[k] = x[k] - (dx / 2.) k += 1 xplot[len(x)] = x[len(x) - 1] + (dx / 2.) k = 0 for el in y: yplot[k] = y[k] - (dy / 2.) k += 1 yplot[len(y)] = y[len(y) - 1] + (dy / 2.) with PdfPages(nameplot) as pdf: fmt1 = '%r %%' fig = plt.figure(figsize=(4., 2.8), dpi=600) plt.rc('text') panel = fig.add_axes([ 0.15, 0.15, 0.72, 0.75 ]) # dimensions and location of the panel within the figure cmap = plt.get_cmap('RdBu') # choose colormap for the committor pcm = panel.pcolormesh(xplot, yplot, q.T, cmap=cmap, zorder=0, vmin=0., vmax=1.) # plot the committor in the grid cbar = plt.colorbar(pcm, format=ticker.FuncFormatter( fmt)) # plot colorbar and select format cbar.ax.tick_params(labelsize=axisticslabelfontsize - 2) # dimension of the labels of the colorbar panel.set_xlabel( r'$x$', fontsize=axislabelfontsize, labelpad=2 ) # labels and ticklabels along x with their fontsize and location, x limits and same for y below for tick in panel.xaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_xlim(xlimleft - 0.1, xlimright + 0.1) panel.xaxis.set_major_locator(MultipleLocator(1)) panel.xaxis.set_minor_locator(MultipleLocator(0.2)) panel.set_ylabel(r'$y$', fontsize=axislabelfontsize, labelpad=2) for tick in panel.yaxis.get_major_ticks(): tick.label.set_fontsize(axisticslabelfontsize) panel.set_ylim(ylimdown - 0.1, ylimup + 0.1) panel.yaxis.set_major_locator(MultipleLocator(1)) panel.yaxis.set_minor_locator(MultipleLocator(0.2)) # Grid for contour lines x = np.arange(xlimleft, xlimright, 0.025) y = np.arange(ylimdown, ylimup, 0.025) X, Y = np.meshgrid(x, y) # Potential contour lines Z = X * 0 for i in range(X.shape[0]): for j in range(X.shape[1]): Z[i, j] = potential(X[i, j], Y[i, j]) CS = panel.contour(X, Y, Z, ncontour, colors='k', linewidths=0.5) plt.clabel(CS, fontsize=4, inline=1) # Basins contour lines P = X * 0 for i in range(X.shape[0]): for j in range(X.shape[1]): P[i, j] = state(X[i, j], Y[i, j]) levelsb = [-1.0, 0.0, 1.0] contour = panel.contour(X, Y, P, levels=levelsb, colors="white", linewidths=0.5, linestyles='dashed') plt.title(r"$q(x,y)$") # title pdf.savefig(fig) print("Committor plot saved correctly")