def test_opts(self): z = cs.ZMatrix(file2str("butane1.zmt")) new_coords = z.get_internals() * 1.15 z.set_internals(new_coords) string_rep = z.xyz_str() z.set_calculator(test_calc()) dyn = ase.LBFGS(z) print "Running z-matrix optimisation" dyn.run(steps=5) e1 = z.get_potential_energy() xyz = cs.XYZ(string_rep) xyz.set_calculator(test_calc()) dyn = ase.LBFGS(xyz) print "Running cartesian optimisation" dyn.run(steps=5) e2 = xyz.get_potential_energy() self.assert_(e1 < e2)
def test_ComplexCoordSys_pickling(self): calc = test_calc() x = cs.XYZ(file2str("H2.xyz")) a = cs.RotAndTrans(numpy.array([1., 0., 0., 3., 1., 1.]), parent=x) z = cs.ZMatrix(file2str("butane1.zmt"), anchor=a) parts = [x, z] ccs = cs.ComplexCoordSys(parts) ccs.set_calculator(calc) forces0 = ccs.get_forces() ccs_pickled = pickle.loads(pickle.dumps(ccs)) ccs_pickled.set_calculator(calc) forces_pickled0 = ccs.get_forces() dyn = ase.LBFGS(ccs_pickled) dyn.run(steps=3) forces_pickled1 = ccs_pickled.get_forces() dyn = ase.LBFGS(ccs) dyn.run(steps=3) forces1 = ccs.get_forces() self.assert_((forces0 == forces_pickled0).all()) self.assert_((forces1 == forces_pickled1).all()) self.assert_((forces0 != forces1).any())
def test_var_mask_big_water_opt(self): print "Running optimisation tests with masking of variables:" print " Lots of water molecules with internal and rotational coordinates frozen." ccs, var_types = self.form_ccs_waters(16) def gen_mask(c): if c == 'i': return False elif c == 'r': return True elif c == 'p': return True else: raise False mask = map(gen_mask, var_types) ccs.set_var_mask(mask) ccs.set_calculator(test_calc()) opt = ase.LBFGS(ccs) list = [] for i in range(8): opt.run(steps=1, fmax=0.0) list.append(ccs.atoms.copy()) if visual: ase.view(list)
def test_ComplexCoordSys(self): x = cs.XYZ(file2str("H2.xyz")) a_h2o1 = cs.RotAndTrans(numpy.array([1., 0., 0., 3., 1., 1.]), parent=x) a_h2o2 = cs.RotAndTrans(numpy.array([1., 0., 0., 1., 1., 1.]), parent=x) a_ch4 = cs.RotAndTrans(numpy.array([1., 0., 0., 1., -1., 1.]), parent=x) h2o1 = cs.ZMatrix(file2str("H2O.zmt"), anchor=a_h2o1) h2o2 = cs.ZMatrix(file2str("H2O.zmt"), anchor=a_h2o2) ch4 = cs.ZMatrix(file2str("CH4.zmt"), anchor=a_ch4) parts = [x, h2o1, h2o2, ch4] ccs = cs.ComplexCoordSys(parts) ccs.set_calculator(test_calc()) dyn = ase.LBFGS(ccs) list = [] for i in range(8): list.append(ccs.atoms.copy()) dyn.run(steps=1, fmax=0.01) list.append(ccs.atoms.copy()) if visual: ase.view(list)
def test_ComplexCoordSys_var_mask_opt(self): print "Running tests with masking of variables" #ch4 = cs.ZMatrix(file2str("CH4.zmt")) ccs, x, h2o1, a_h2o1 = self.form_ccs1( ) #, h2o2, ch4, a_h2o2, a_ch4 = self.form_ccs() ccs.set_calculator(test_calc()) #m = [True for i in range(0)] + [True for i in range(ccs.dims)] parts = [x, h2o1, a_h2o1] #, h2o2, a_h2o2, ch4, a_ch4] dims = [p._dims for p in parts] print dims torf = lambda d, f: [f for i in range(d)] fs = [False, False, True] #, True, False, False, False] m1 = [torf(d, f) for d, f in zip(dims, fs)] print m1 m = [m_ for d, f in zip(dims, fs) for m_ in torf(d, f)] print m mask = numpy.array(m) ccs.set_var_mask(mask) self.assert_(sum(ccs._var_mask) == ccs.dims) self.assertAlmostEqualVec(ccs._coords, ccs._demask(ccs.get_internals())) before = ccs._coords.copy() #print ccs.int2cart(ccs.get_internals()) after = ccs._coords.copy() self.assert_((before == after).all()) print "_coords", ccs._coords if visual: ase.view(ccs.atoms) print "_coords", ccs._coords print ccs.get_internals() if visual: ase.view(ccs.atoms) dyn = ase.LBFGS(ccs) list = [] for i in range(8): list.append(ccs.atoms.copy()) dyn.run(steps=1, fmax=0.01) list.append(ccs.atoms.copy()) #if visual: ase.view(list)
def test_CoordSys_pickling(self): print "Creating a Z-matrix, pickling it, then performing an dientical" print "optimisation on each one, then checking that the forces are identical." z1 = cs.ZMatrix(file2str("butane1.zmt")) s = pickle.dumps(z1) z1.set_calculator(test_calc()) opt = ase.LBFGS(z1) opt.run(steps=4) forces1 = z1.get_forces() z2 = pickle.loads(s) z2.set_calculator(test_calc()) opt = ase.LBFGS(z2) opt.run(steps=4) forces2 = z2.get_forces() self.assert_((forces1 == forces2).all())
def beadopt_calc(mi, params, indices): """Check that points with the specified indices are minima and minimise if necessary.""" for i in indices: mol = mi.build_coord_sys(mi.reagent_coords[i]) opt = ase.LBFGS(mol) s, l = 0, [] # FIXME: the final force norm printed by the optimiser is greater than the one specified here maxit = params['maxit'] tol = params['tol'] while numpy.max(mol.get_forces()) > tol: opt.run(steps=1) s += 1 l.append(mol.atoms.copy()) if s >= maxit: print "Max iterations exceeded." break ase.view(l)
def test_ComplexCoordSys2(self): x = cs.XYZ(file2str("H2.xyz")) a = cs.RotAndTrans(numpy.array([1., 0., 0., 3., 1., 1.]), parent=x) z = cs.ZMatrix(file2str("butane1.zmt"), anchor=a) parts = [x, z] ccs = cs.ComplexCoordSys(parts) ccs.set_calculator(test_calc()) print ccs.get_potential_energy() print ccs.get_forces() dyn = ase.LBFGS(ccs) list = [] for i in range(8): dyn.run(steps=1, fmax=0.01) list.append(ccs.atoms.copy()) if visual: ase.view(list)
def main(argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "ho", ["help", "optimise"]) except getopt.error, msg: raise PickleRunnerException(msg) mode = "calc_eg" for o, a in opts: if o in ("-h", "--help"): usage() return 0 if o in ("-o", "--optimise"): mode = "optimise" else: usage() return -1 if len(args) != 1: raise PickleRunnerException( "Exactly one input file must be given.") # calc_filename = os.path.abspath(args[0]) mol_filename = os.path.abspath(args[0]) # calc_pickled = open(calc_filename, "rb") mol_pickled = open(mol_filename, "rb") print "About to unpickle" # create atoms object based on pickled inputs mol, data = pickle.load(mol_pickled) f = None print "mol", str(mol) #if not mol._atoms.get_calculator(): # raise PickleRunnerException("Molecule object had no calculator.") jobname = mol_filename.split(".")[0] # setup directories, filenames isolation_dir = jobname print "isolation_dir", isolation_dir old_dir = os.getcwd() # if a tmp directory is specified, then use it tmp_dir = common.get_tmp_dir() os.chdir(tmp_dir) # Create/change into isolation directory. This directory holds temporary files # specific to a computation, not including input and output files. if not os.path.exists(isolation_dir): os.mkdir(isolation_dir) os.chdir(isolation_dir) # Perform final tasks, e.g. copy the # WAVECAR or blah.chk file here. if f != None: if not callable(f): raise PickleRunnerException( "Supplied function was neither callable nor None.") f(mol.get_calculator(), data) result_file = os.path.join(tmp_dir, jobname + common.OUTPICKLE_EXT) if mode == "calc_eg": # run job using ASE calculator print "Running pickle job in", os.getcwd() print "isolation_dir", isolation_dir print "type(mol._atoms.calc)", type(mol._atoms.calc) g = -mol.get_forces().flatten() assert len(g.shape) == 1 e = mol.get_potential_energy() result = (e, g, os.getcwd()) os.chdir(old_dir) pickle.dump(result, open(result_file, "w"), protocol=2) # just for testing... print pickle.load(open(result_file, "r")) elif mode == "optimise": optim = ase.LBFGS(mol, trajectory='opt.traj') optim.run(steps=10) os.chdir(old_dir) ase.io.write(result_file, mol._atoms, format="traj") else: raise PickleRunnerException("Unrecognised mode: " + mode)
def runopt_inner(name, CoS, ftol, maxit, callback, maxstep=0.2, **kwargs): global opt if name == 'scipy_lbfgsb': def fun(x): CoS.state_vec = x return CoS.obj_func() def fprime(x): CoS.state_vec = x # Attention: here it is expected that only one # gradient call per iteration step is done return CoS.obj_func_grad() class nums: def __init__(self): pass def get_number_of_steps(self): return lbfgs.n_function_evals opt = nums() opt2, energy, dict = lbfgs.fmin_l_bfgs_b( fun, CoS.get_state_as_array(), fprime=fprime, callback=callback, maxfun=maxit, pgtol=ftol, factr=10, # stops when step is < factr*machine_precision maxstep=maxstep) return dict elif name == 'multiopt': from pts.cosopt.multiopt import MultiOpt opt = MultiOpt(CoS, maxstep=maxstep, **kwargs) opt.string = CoS.string opt.attach(lambda: callback(None), interval=1) opt.run(steps=max_it) # convergence handled by callback return None elif name == 'conj_grad': from pts.cosopt.conj_grad import conj_grad_opt opt = conj_grad_opt(CoS, maxstep=maxstep, **kwargs) opt.attach(lambda: callback(None), interval=1) opt.run(steps=max_it) # convergence handled by callback return None elif name == 'steep_des': from pts.cosopt.conj_grad import conj_grad_opt opt = conj_grad_opt(CoS, maxstep=maxstep, reduce_to_steepest_descent=True, **kwargs) opt.attach(lambda: callback(None), interval=1) opt.run() # convergence handled by callback return None elif name == 'fire': from pts.cosopt.fire import fire_opt opt = fire_opt(CoS, maxstep=maxstep, **kwargs) opt.attach(lambda: callback(None), interval=1) opt.run(steps=maxit) # convergence handled by callback return None elif name[0:4] == 'ase_': if name == 'ase_lbfgs': opt = ase.LBFGS(CoS, maxstep=maxstep, **kwargs) elif name == 'ase_bfgs': opt = ase.BFGS(CoS, maxstep=maxstep, **kwargs) elif name == 'ase_lbfgs_line': opt = ase.LineSearchLBFGS(CoS, maxstep=maxstep) elif name == 'ase_fire': opt = ase.FIRE(CoS, maxmove=maxstep) elif name == 'ase_scipy_cg': opt = ase.SciPyFminCG(CoS) elif name == 'ase_scipy_lbfgsb': opt = pts.cosopt.optimizers.SciPyFminLBFGSB(CoS, alpha=400) else: assert False, ' '.join( ["Unrecognised algorithm", name, "not in"] + names) opt.string = CoS.string # attach optimiser to print out each step in opt.attach(lambda: callback(None), interval=1) opt.run(fmax=ftol, steps=maxit) return None else: assert False, ' '.join(["Unrecognised algorithm", name, "not in"] + names)
import sys # contents of the variables in the following are arbitrary since they are # set based on the cartesian objects. Make sure, however, that the z-matrix # variables are non-zero, since this can cause a divide by zero error. fn = sys.argv[1] print "Filename", fn ccs = ComplexCoordSys(file2str(fn)) #print ccs._coords #print ccs.get_internals() #exit() g = Gaussian() ccs.set_calculator((Gaussian, [], {'charge': 0, 'mult': 3})) opt = ase.LBFGS(ccs) pt = PickleTrajectory("test.traj", mode='w') def cb(): print ccs.xyz_str() print "internals", ccs.get_internals().round(2) pt.write(ccs.atoms.copy()) opt.attach(cb) print ccs.get_internals().round(2) opt.run(fmax=0.1)
def test_NEB(): from scipy.optimize import fmin_bfgs default_spr_const = 1. neb = NEB([reactants, products], lambda x: True, GaussianPES(), default_spr_const, beads_count=12) init_state = neb.get_state_as_array() surf_plot = SurfPlot(GaussianPES()) # Wrapper callback function def mycb(x): #surf_plot.plot(path = x) print neb return x from scipy.optimize.lbfgsb import fmin_l_bfgs_b # opt = fmin_bfgs(neb.obj_func, init_state, fprime=neb.obj_func_grad, callback=mycb, gtol=0.05) # opt, energy, dict = fmin_l_bfgs_b(neb.obj_func, init_state, fprime=neb.obj_func_grad, callback=mycb, pgtol=0.05) # opt = opt_gd(neb.obj_func, init_state, neb.obj_func_grad, callback=mycb) import ase optimizer = ase.LBFGS(neb) optimizer.run(fmax=0.04) opt = neb.state_vec print "opt =", opt print dict #wt() gr = neb.obj_func_grad(opt) n = linalg.norm(gr) i = 0 """while n > 0.001 and i < 4: print "n =",n opt = fmin_bfgs(neb.obj_func, opt, fprime=neb.obj_func_grad) gr = neb.obj_func_grad(opt) n = linalg.norm(gr) i += 1""" # Points on grid to draw PES ps = 20.0 xrange = arange(ps) * (5.0 / ps) - 1 yrange = arange(ps) * (5.0 / ps) - 1 # Make a 2-d array containing a function of x and y. First create # xm and ym which contain the x and y values in a matrix form that # can be `broadcast' into a matrix of the appropriate shape: gpes = GaussianPES() g = Gnuplot.Gnuplot(debug=1) g('set data style lines') g('set hidden') g.xlabel('Molecular Coordinate A') g.ylabel('Molecular Coordinate B') g.zlabel('Energy') g('set linestyle lw 5') # Get some tmp filenames ( fd, tmpPESDataFile, ) = tempfile.mkstemp(text=1) ( fd, tmpPathDataFile, ) = tempfile.mkstemp(text=1) Gnuplot.funcutils.compute_GridData(xrange, yrange, lambda x, y: gpes.energy([x, y]), filename=tmpPESDataFile, binary=0) opt.shape = (-1, 2) print "opt = ", opt pathEnergies = array(map(gpes.energy, opt.tolist())) print "pathEnergies = ", pathEnergies pathEnergies += 0.05 xs = array(opt[:, 0]) ys = array(opt[:, 1]) print "xs =", xs, "ys =", ys data = transpose((xs, ys, pathEnergies)) Gnuplot.Data(data, filename=tmpPathDataFile, inline=0, binary=0) # PLOT SURFACE AND PATH g('set xrange [-0.2:3.2]') g('set yrange [-0.2:3.2]') g('set zrange [-1:2]') print tmpPESDataFile, tmpPathDataFile g.splot(Gnuplot.File(tmpPESDataFile, binary=0), Gnuplot.File(tmpPathDataFile, binary=0, with_="lines")) raw_input('Press to continue...\n') os.unlink(tmpPESDataFile) os.unlink(tmpPathDataFile) return opt
def neb_calc(molinterface, calc_man, params): """Setup NEB object, optimiser, etc.""" spr_const = float(params["spr_const"]) beads_count = int(params["beads_count"]) neb = pts.searcher.NEB(molinterface.reagent_coords, calc_man, spr_const, beads_count, parallel=True) # initial path #dump_beads(molinterface, neb, params) dump_steps(neb) # callback function mycb = lambda x: generic_callback(x, molinterface, neb, **params) # opt params maxit = params['maxit'] tol = params['tol'] print "Launching optimiser..." if params["optimizer"] == "l_bfgs_b": import cosopt.lbfgsb as so #import ase #dyn = ase.LBFGS(neb) #dyn.run() opt, energy, dict = so.fmin_l_bfgs_b(neb.obj_func, neb.get_state_as_array(), fprime=neb.obj_func_grad, callback=mycb, pgtol=tol, maxfun=maxit) elif params["optimizer"] == "bfgs": from scipy.optimize import fmin_bfgs opt = fmin_bfgs(neb.obj_func, neb.get_state_as_array(), fprime=neb.obj_func_grad, callback=mycb, maxiter=maxit) elif params["optimizer"] == "ase_lbfgs": import ase optimizer = ase.LBFGS(neb) optimizer.run(fmax=tol) opt = neb.state_vec elif params["optimizer"] == "grad_descent": opt = opt_gd(neb.obj_func, neb.get_state_as_array(), fprime=neb.obj_func_grad, callback=mycb) else: raise ParseError("Unknown optimizer: " + params["optimizer"]) # PRODUCE OUTPUT print "Finished" # print opt # print energy dump_beads(molinterface, neb, params) print "steps" dump_steps(neb)
def string_calc(molinterface, calc_man, reagent_coords, params): """Setup String object, optimiser, etc.""" beads_count = int(params["beads_count"]) string = pts.searcher.GrowingString(molinterface.reagent_coords, calc_man, beads_count, rho=lambda x: 1, growing=params['growing'], parallel=True) # initial path dump_beads(molinterface, string, params) #dump_steps(string) mycb = lambda x: generic_callback(x, molinterface, string, **params) # opt params maxit = params['maxit'] tol = params['tol'] print "Launching optimiser..." if params['growing']: gqs = pts.searcher.QuadraticStringMethod(string, callback=mycb, update_trust_rads=True) while True: opt = gqs.opt() # grow the string, but break if not possible print "Growing" if not string.grow_string(): break elif params["optimizer"] == "l_bfgs_b": import cosopt.lbfgsb as so opt, energy, dict = so.fmin_l_bfgs_b(string.obj_func, string.get_state_as_array(), fprime=string.obj_func_grad, callback=mycb, pgtol=tol, maxfun=maxit) print opt print energy print dict elif params["optimizer"] == "quadratic_string": qs = pts.searcher.QuadraticStringMethod(string, callback=mycb, update_trust_rads=True) opt = qs.opt() print opt elif params["optimizer"] == "ase_lbfgs": import ase dyn = ase.LBFGS(string) dyn.run() else: raise ParseError("Unknown optimizer: " + params["optimizer"])
def main(argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "ho", ["help", "optimise"]) except getopt.error, msg: raise ASEIsolatorException(msg) mode = "calc_eg" for o, a in opts: if o in ("-h", "--help"): usage() return 0 if o in ("-o", "--optimise"): mode = "optimise" else: usage() return -1 if len(args) != 2: raise ASEIsolatorException( "Exactly two input files must be given.") ase_job_settings = os.path.abspath(args[0]) molecule = os.path.abspath(args[1]) # create atoms object based on molecular geometry in file atoms = ase.io.read(molecule) jobname = os.path.splitext(molecule)[0] # setup directories, filenames isolation_dir = os.path.basename(jobname) print isolation_dir old_dir = os.getcwd() # if a tmp directory is specified, then use it tmp_dir = common.get_tmp_dir() os.chdir(tmp_dir) # Create/change into isolation directory. This directory holds temporary files # specific to a computation, not including input and output files. if not os.path.exists(isolation_dir): os.mkdir(isolation_dir) os.chdir(isolation_dir) # set up calculators, etc. exec open(ase_job_settings).read() # Based on what was found in ase_job_settings, perform further # setup for 'atoms' if 'mycell' in locals(): atoms.set_cell(mycell) if 'mypbc' in locals(): atoms.set_pbc(mypbc) if not 'mycalc' in locals(): raise ASEIsolatorException("'mycalc' not defined in " + ase_job_settings) atoms.set_calculator(mycalc) result_file = os.path.join(tmp_dir, jobname + common.LOGFILE_EXT) if mode == "calc_eg": # run job using ASE calculator g = atoms.get_forces().flatten() e = atoms.get_potential_energy() os.chdir(old_dir) result = (e, g) pickle.dump(result, open(result_file, "w"), protocol=2) # just for testing... #print pickle.load(open(result_file, "r")) elif mode == "optimise": optim = ase.LBFGS(atoms, trajectory='opt.traj') optim.run() os.chdir(old_dir) ase.io.write(result_file, atoms, format="traj") else: raise ASEIsolatorException("Unrecognised mode: " + mode)