def struct_energy(e0_per_atom, filename):
    V_unrel = []
    V_rel = []
    E_unrel = []
    E_rel = []

    ats = ase.io.read(os.path.dirname(__file__) + "/" + filename,
                      index=':',
                      format='extxyz')
    for (i, at_orig) in enumerate(ats):
        at = at_orig.copy()
        at.set_calculator(model.calculator)
        # # The commented out bit that follows seems to break CASTEP_file - no minimization runs are set up, apparently because call to relax_atoms_cell doesn't actually trigger a calculate()
        # unrelaxed_e_per_atom  = at.get_potential_energy()/len(at)
        # print 'at unrelaxed energy per atom', unrelaxed_e_per_atom
        # E_unrel.append(unrelaxed_e_per_atom-e0_per_atom)

        # relax fully
        print "BOB: calling relax_atoms_cell"
        if os.path.basename(os.path.dirname(model.__file__)) == 'CASTEP_file':
            at = relax_atoms_cell(at,
                                  tol=fmax,
                                  traj_file="model-" + model.name +
                                  "-RSS-{}-".format(i) + filename +
                                  "-relaxed.opt.xyz")
        else:
            n_at = len(at)
            config_minim = UnitCellFilter(at)
            x = config_minim.get_positions()
            converged = False
            for i_minim in range(500):
                config_minim.set_positions(x)
                grad_f = -config_minim.get_forces()
                E = config_minim.get_potential_energy()
                try:
                    pred_err = predictive_error(config_minim.atoms)
                except:
                    pred_err = None
                if isinstance(config_minim, UnitCellFilter):
                    print i, "SD2: {} {} {} {}".format(
                        i_minim, E, np.max(np.abs(grad_f[:n_at])),
                        np.max(np.abs(grad_f[n_at:])))
                else:
                    print i, "SD2: {} {} {}".format(
                        i_minim, E, np.max(np.abs(grad_f[:n_at])))
                if np.max(np.abs(grad_f[:n_at])) < fmax and np.max(
                        np.abs(grad_f[n_at:])) < fmax:
                    converged = True
                    break
                if i_minim == 0:
                    alpha = 1.0e-6
                else:
                    alpha = np.sum(
                        (x - x_old) * (grad_f - grad_f_old)) / np.sum(
                            (grad_f - grad_f_old)**2)
                x_old = x.copy()
                grad_f_old = grad_f.copy()
                x -= np.abs(alpha) * grad_f
        print "BOB: done relax_atoms_cell"
        ase.io.write(sys.stdout, at, format='extxyz')

        print "BOB: calling get_potential_energy for relaxed"
        relaxed_e_per_atom = at.get_potential_energy() / len(at)
        print "BOB: done get_potential_energy for relaxed"
        print 'at relaxed energy per atom', relaxed_e_per_atom
        E_rel.append(relaxed_e_per_atom - e0_per_atom)

        V_rel.append(at.get_volume() / len(at))

    # This is a workaround for the problem mentioned above
    ats = ase.io.read(os.path.dirname(__file__) + "/" + filename,
                      index=':',
                      format='extxyz')
    for (i, at) in enumerate(ats):
        at.set_calculator(model.calculator)

        # relax fully
        print "BOB: calling get_potential_energy for unrelaxed"
        unrelaxed_e_per_atom = at.get_potential_energy() / len(at)
        print "BOB: done get_potential_energy for unrelaxed"
        print 'at unrelaxed energy per atom', unrelaxed_e_per_atom
        E_unrel.append(unrelaxed_e_per_atom - e0_per_atom)
        V_unrel.append(at.get_volume() / len(at))
    # end of workaround

    return (V_unrel, E_unrel, V_rel, E_rel)
Example #2
0
     model.geom_method = 'tpsd'
     model.geom_force_tol = tol
     model.geom_stress_tol = tol
     model.geom_energy_tol = 1.0e8
     model.geom_disp_tol = 1.0e8
     print "BOB relax atoms"
     at = relax_atoms_cell(at, tol=tol)
     i_minim = -1
     converged = True
 else:
     config_minim = UnitCellFilter(at)
     x = config_minim.get_positions()
     converged = False
     for i_minim in range(500):
         config_minim.set_positions(x)
         grad_f = -config_minim.get_forces()
         E = config_minim.get_potential_energy()
         try:
             pred_err = predictive_error(config_minim.atoms)
         except:
             pred_err = None
         if isinstance(config_minim, UnitCellFilter):
             print config_i, "SD2: {} {} {} {}".format(
                 i_minim, E, np.max(np.abs(grad_f[:n_at])),
                 np.max(np.abs(grad_f[n_at:])))
         else:
             print config_i, "SD2: {} {} {}".format(
                 i_minim, E, np.max(np.abs(grad_f[:n_at])))
         if np.max(np.abs(grad_f[:n_at])) < tol and np.max(
                 np.abs(grad_f[n_at:])) < tol:
             converged = True
    def relax_use_method(xc,
                         method,
                         fmax=0.002,
                         steps=100,
                         clear=False):  # allow only up to 100 steps
        atoms = mater.copy()  # same start point!
        if xc.upper() not in ("PBE", "LDA"):
            raise ValueError("XC method not known!")
        if method.upper() not in ("UCF", "ECF", "IT"):
            raise ValueError("Optimization method not known!")
        parprint("Running {}-{} for {}-{}".format(xc, method, name, prototype))

        calc = GPAW(
            mode=dict(name="pw", ecut=800),
            occupations=dict(name="fermi-dirac", width=0.01),
            basis="dzp",
            xc=xc.upper(),
            kpts=dict(gamma=True, density=4.0),  # Very rough k-density
            txt=os.path.join(base_dir,
                             "{}-{}.txt".format(xc.upper(), method.upper())))
        atoms.set_calculator(calc)
        traj_filename = os.path.join(
            base_dir, "{}-{}.traj".format(xc.upper(), method.upper()))

        log_filename = os.path.join(
            base_dir, "{}-{}.log".format(xc.upper(), method.upper()))

        if clear is True:
            with open(traj_filename, "w") as _:
                pass
            with open(log_filename, "w") as _:
                pass

            res_fmax = None
            if method.upper() == "UCF":  # UnitCellFilter
                ff = UnitCellFilter(atoms)
                opt = ase.optimize.BFGS(ff,
                                        trajectory=traj_filename,
                                        logfile=log_filename)
                opt.run(fmax=fmax, steps=steps)
                f = ff.get_forces()
                smax = numpy.sqrt((f**2).sum(axis=1).max())
            elif method.upper() == "ECF":  # ExpCellFilter
                ff = ExpCellFilter(atoms)
                opt = ase.optimize.BFGS(ff,
                                        trajectory=traj_filename,
                                        logfile=log_filename)
                opt.run(fmax=fmax, steps=steps)
                f = ff.get_forces()
                smax = numpy.sqrt((f**2).sum(axis=1).max())
            elif method.upper() == "IT":  # Iterative
                sf = StrainFilter(atoms)
                opt_strain = ase.optimize.BFGS(sf,
                                               trajectory=traj_filename,
                                               logfile=log_filename)
                opt_force = ase.optimize.BFGS(atoms,
                                              trajectory=traj_filename,
                                              logfile=log_filename)
                opt_strain.run(fmax=fmax, steps=steps)
                opt_force.run(fmax=fmax, steps=steps)
                f = atoms.get_forces()
                smax = numpy.sqrt((f**2).sum(axis=1).max())

        a, b, c, *_ = atoms.get_cell_lengths_and_angles()
        if "smax" not in dir():
            smax = None
        res_entry = dict(name=name,
                         prototype=prototype,
                         xc=xc.upper(),
                         method=method.upper(),
                         abc=(a, b, c),
                         max_force=smax)
        return res_entry