Esempio n. 1
0
def test_analyse_forces():
    from ase.build import molecule
    from ase.calculators.emt import EMT
    from ase.optimize import BFGSLineSearch
    from carmm.analyse.forces import is_converged
    from ase.constraints import FixAtoms

    fmax = 0.01  # eV/Angstrom
    atoms = molecule("CO2")
    atoms.calc = EMT()

    # Returns False prior to optimisation (no forces in calculator)
    opt = BFGSLineSearch(atoms)
    print(is_converged(atoms, fmax))
    assert (is_converged(atoms, fmax) == False)
    print(atoms.calc.forces)

    # Returns False if optimisation has not reached to/below fmax
    opt.run(fmax=fmax * 30)
    print(is_converged(atoms, fmax))
    assert (is_converged(atoms, fmax) == False)

    # Returns True if optimised to or below desired fmax with constraints
    c = FixAtoms(indices=[0, 1])
    atoms.set_constraint(c)
    opt.run(fmax=fmax)
    print(is_converged(atoms, fmax))
    assert (is_converged(atoms, fmax) == True)

    # Returns True if optimised to or below desired fmax without constraints
    atoms.set_constraint()
    opt.run(fmax=fmax)
    print(is_converged(atoms, fmax))
    assert (is_converged(atoms, fmax) == True)
Esempio n. 2
0
def relax_VarianceBreak(structure, calc, label='', niter_max=10, forcemax=0.1):
    '''
    Relax a structure and saves the trajectory based in the index i

    Parameters
    ----------
    structure : ase Atoms object to be relaxed

    Returns
    -------
    '''

    # Set calculator
    structure.set_calculator(calc)

    # loop a number of times to capture if minimization stops with high force
    # due to the VariansBreak calls
    niter = 0

    # If the structure is already fully relaxed just return it
    if (structure.get_forces()**2).sum(axis=1).max()**0.5 < forcemax:
        return structure

    while (structure.get_forces()**
           2).sum(axis=1).max()**0.5 > forcemax and niter < niter_max:
        dyn = BFGSLineSearch(structure, logfile=label + '.log')
        vb = VariansBreak(structure, dyn, min_stdev=0.01, N=15)
        dyn.attach(vb)
        dyn.run(fmax=forcemax, steps=200)
        niter += 1

    return structure
Esempio n. 3
0
    def prepare_slab_opt(self, slab: Atoms) -> None:
        ''' Prepare slab optimization with Quantum Espresso '''

        balsamcalc_module = __import__('pynta.balsamcalc',
                                       fromlist=[self.socket_calculator])

        sock_calc = getattr(balsamcalc_module, self.socket_calculator)

        # n_kpts = IO().get_kpoints(self.repeats_surface)

        job_kwargs = self.balsam_exe_settings.copy()
        extra_calc_keywords = self.calc_keywords.copy()
        # add kpoints and distribute it among nodes = n_kpts
        # extra_calc_keywords['kpts'] = self.repeats_surface
        # extra_calc_keywords['job_args'] = '-nk {}'.format(n_kpts)
        # change how k-points are distrubuted among nodes
        # job_kwargs.update([('num_nodes', n_kpts)])

        slab.pbc = (True, True, False)

        if self.socket_calculator == 'EspressoBalsamSocketIO':
            slab.calc = sock_calc(workflow='QE_Socket',
                                  job_kwargs=job_kwargs,
                                  pseudopotentials=self.pseudopotentials,
                                  pseudo_dir=self.pseudo_dir,
                                  **extra_calc_keywords)
        else:
            slab.calc = sock_calc(workflow='QE_Socket',
                                  job_kwargs=job_kwargs,
                                  **extra_calc_keywords)

        fname = os.path.join(self.creation_dir, self.slab_name)

        opt = BFGSLineSearch(atoms=slab, trajectory=fname + '.traj')
        opt.run(fmax=0.01)
        slab.get_potential_energy()
        slab.get_forces()
        slab.calc.close()
        write(fname + '.xyz', slab)
Esempio n. 4
0
def flosic_optimize(mode,
                    atoms,
                    charge,
                    spin,
                    xc,
                    basis,
                    ecp=None,
                    opt='FIRE',
                    maxstep=0.2,
                    label='OPT_FRMORB',
                    fmax=0.0001,
                    steps=1000,
                    max_cycle=300,
                    conv_tol=1e-5,
                    grid=7,
                    ghost=False,
                    use_newton=False,
                    use_chk=False,
                    verbose=0,
                    debug=False,
                    efield=None,
                    l_ij=None,
                    ods=None,
                    force_consistent=False,
                    fopt='force',
                    fix_fods=False,
                    ham_sic='HOO',
                    vsic_every=1):
    # -----------------------------------------------------------------------------------
    # Input
    # -----------------------------------------------------------------------------------
    # mode 			...	dft only optimize nuclei positions
    #				flosic only optimize FOD positions (one-shot)
    #				flosic-scf only optimize FOD positions (self-consistent)
    # atoms 		...	ase atoms object
    # charge 		... 	charge
    # spin			...	spin state = alpha - beta
    # xc			... 	exchange correlation functional
    # basis	 		... 	GTO basis set
    # ecp			...	if a ECP basis set is used you must give this extra argument
    # opt 			...	optimizer (FIRE, LBFGS, ...)
    # ----------------------------------------------------------------------------------
    # Additional/optional input
    # ----------------------------------------------------------------------------------
    # maxstep		...	stepwidth of the optimizer
    # label			...	label for the outputs (logfile and trajectory file)
    # fmax 			...	maximum force
    # steps 		...     maximum steps for the optimizer
    # max_cycle     	...     maxium scf cycles
    # conv_tol		...	energy threshold
    # grid			... 	numerical mesh
    # ghost 		...	use ghost atom at positions of FODs
    # use_newton		...	use newton scf cycle
    # use_chk		...	restart from chk fiels
    # verbose 		...	output verbosity
    # debug			...	extra output for debugging reasons
    # efield 		...	applying a external efield
    # l_ij			...	developer option: another optimitzation criterion, do not use for production
    # ods			...	developer option orbital damping sic, rescale SIC, do not use for production
    # force_cosistent	...     ase option energy consistent forces
    # fopt			...	optimization trarget, default FOD forces
    # fix_fods		...	freeze FODS during the optimization, might use for 1s/2s FODs
    # ham_sic		...	the different unified Hamiltonians HOO and HOOOV

    opt = opt.upper()
    mode = mode.lower()

    if fix_fods != False:
        c = FixAtoms(fix_fods)
        atoms.set_constraint(c)

    # Select the wished mode.
    # DFT mode
    if mode == 'dft':
        [geo, nuclei, fod1, fod2, included] = xyz_to_nuclei_fod(atoms)
        atoms = nuclei
        calc = PYFLOSIC(atoms=atoms,
                        charge=charge,
                        spin=spin,
                        xc=xc,
                        basis=basis,
                        mode='dft',
                        ecp=ecp,
                        max_cycle=max_cycle,
                        conv_tol=conv_tol,
                        grid=grid,
                        ghost=ghost,
                        use_newton=use_newton,
                        verbose=verbose,
                        debug=debug,
                        efield=efield,
                        l_ij=l_ij,
                        ods=ods,
                        fopt=fopt,
                        ham_sic=ham_sic,
                        vsic_every=vsic_every)
    # FLO-SIC one-shot (os) mode
    if mode == 'flosic-os':
        calc = PYFLOSIC(atoms=atoms,
                        charge=charge,
                        spin=spin,
                        xc=xc,
                        basis=basis,
                        mode='flosic-os',
                        ecp=ecp,
                        max_cycle=max_cycle,
                        conv_tol=conv_tol,
                        grid=grid,
                        ghost=ghost,
                        use_newton=use_newton,
                        verbose=verbose,
                        debug=debug,
                        efield=efield,
                        l_ij=l_ij,
                        ods=ods,
                        fopt=fopt,
                        ham_sic=ham_sic,
                        vsic_every=vsic_every)
    # FLO-SIC scf mode
    if mode == 'flosic-scf':
        calc = PYFLOSIC(atoms=atoms,
                        charge=charge,
                        spin=spin,
                        xc=xc,
                        basis=basis,
                        mode='flosic-scf',
                        ecp=ecp,
                        max_cycle=max_cycle,
                        conv_tol=conv_tol,
                        grid=grid,
                        ghost=ghost,
                        use_newton=use_newton,
                        verbose=verbose,
                        debug=debug,
                        efield=efield,
                        l_ij=l_ij,
                        ods=ods,
                        fopt=fopt,
                        ham_sic=ham_sic,
                        vsic_every=vsic_every)

    # Assign the ase-calculator to the ase-atoms object.
    atoms.set_calculator(calc)

    # Select the wisehd ase-optimizer.
    if opt == 'FIRE':
        dyn = FIRE(atoms,
                   logfile=label + '.log',
                   trajectory=label + '.traj',
                   dt=0.15,
                   maxmove=maxstep)
        #force_consistent=force_consistent)

    if opt == 'LBFGS':
        dyn = LBFGS(atoms,
                    logfile=label + '.log',
                    trajectory=label + '.traj',
                    use_line_search=False,
                    maxstep=maxstep,
                    memory=10)
        #force_consistent=force_consistent)

    if opt == 'BFGS':
        dyn = BFGS(atoms,
                   logfile=label + '.log',
                   trajectory=label + '.traj',
                   maxstep=maxstep)

    if opt == 'LineSearch':
        dyn = BFGSLineSearch(atoms,
                             logfile=label + '.log',
                             trajectory=label + '.traj',
                             maxstep=maxstep)
        #force_consistent = force_consistent)

    if opt == 'CG':
        dyn = SciPyFminCG(atoms,
                          logfile=label + '.log',
                          trajectory=label + '.traj',
                          callback_always=False,
                          alpha=70.0,
                          master=None)
        #force_consistent=force_consistent)
    if opt == 'GPMin':
        from ase.optimize import GPMin
        dyn = GPMin(atoms,
                    logfile=label + '.log',
                    trajectory=label + '.traj',
                    update_prior_strategy='average',
                    update_hyperparams=True)

    # Run the actuall optimization.
    dyn.run(fmax=fmax, steps=steps)
    return atoms
Esempio n. 5
0
atoms.set_calculator(calc)

print(calc.parameters)

# test energy call
print(atoms.get_potential_energy())
# test force call
print(atoms.get_forces())


calc = Psi4('psi4-calc')

print(calc.parameters)
# test interface with ASE optimizers
relax = BFGSLineSearch(atoms)
relax.run(fmax = 0.05)


# test mutliplicity and charge kwargs

atoms = molecule('H2')

calc = Psi4(atoms = atoms,
            charge = 1,
            multiplicity =  2,
            reference = 'uhf')
print(atoms.get_potential_energy())


del atoms[1]
Esempio n. 6
0
def mof_bfgs_run(workflow,
                 mof,
                 calc,
                 kpts,
                 steps=100,
                 fmax=0.05,
                 force_nupdown=False):
    """
	Run ASE BFGSLineSearch calculation
	Args:
		workflow (class): pymofscreen.screen_phases.worfklow class

		mof (ASE Atoms object): ASE Atoms object for MOF

		calc (dict): ASE Vasp calculator

		kpts (list of ints): k-point grid

		steps (int): maximum number of steps

		fmax (int): force tolerance

		force_nupdown (bool): force NUPDOWN to nearest int

	Returns:
		mof (ASE Atoms object): updated ASE Atoms object

		dyn (class): ASE dynamics class

		calc_swaps (list of strings): calc swaps
	"""

    nprocs = workflow.nprocs
    ppn = workflow.ppn
    calc_swaps = workflow.calc_swaps
    refcode = workflow.refcode
    stdout_file = workflow.stdout_file
    calc_swaps = workflow.calc_swaps
    gamma = workflow.kpts_dict['gamma']

    if force_nupdown:
        init_mags = mof.get_initial_magnetic_moments()
        summed_mags = np.sum(np.abs(init_mags))
        nupdown = int(np.round(summed_mags, 0))
        calc.int_params['nupdown'] = nupdown
    elif workflow.nupdown is not None:
        calc.int_params['nupdown'] = workflow.nupdown

    if sum(kpts) == 3:
        gpt_version = True
    else:
        gpt_version = False

    nprocs = check_nprocs(len(mof), nprocs, ppn)
    choose_vasp_version(gpt_version, nprocs)
    calc.input_params['kpts'] = kpts
    calc.input_params['gamma'] = gamma
    if calc.int_params['ncore'] is None and calc.int_params['npar'] is None:
        calc.int_params['ncore'] = int(ppn / 2.0)
    calc, calc_swaps = update_calc(calc, calc_swaps)
    mof.set_calculator(calc)
    dyn = BFGSLineSearch(mof, trajectory='opt.traj')
    success = False

    try:
        dyn.run(fmax=fmax, steps=steps)
        success = True
    except:

        if not os.path.isfile('STOPCAR'):

            old_error_len = 0
            restart_files = ['WAVECAR', 'CHGCAR']

            while True:

                errormsg = get_error_msgs('OUTCAR', refcode, stdout_file)
                print(errormsg)
                calc, calc_swaps = update_calc_after_errors(
                    calc, calc_swaps, errormsg)
                error_len = len(errormsg)
                if error_len == old_error_len:
                    break

                clean_files(restart_files)
                mof = continue_mof()
                mof.set_calculator(calc)
                dyn = BFGSLineSearch(mof, trajectory='opt.traj')

                try:
                    dyn.run(fmax=fmax, steps=steps)
                    success = True
                except:
                    pass

                old_error_len = error_len

    if not success:
        mof = None

    return mof, dyn, calc_swaps
Esempio n. 7
0
def adsorb(db, height=1.2, nlayers=3, nkpts=7, ecut=400):
    """Adsorb nitrogen in hcp-site on Ru(0001) surface.

    Do calculations for N/Ru(0001), Ru(0001) and a nitrogen atom
    if they have not already been done.

    db: Database
        Database for collecting results.
    height: float
        Height of N-atom above top Ru-layer.
    nlayers: int
        Number of Ru-layers.
    nkpts: int
        Use a (nkpts * nkpts) Monkhorst-Pack grid that includes the
        Gamma point.
    ecut: float
        Cutoff energy for plane waves.

    Returns height.
    """

    name = f'Ru{nlayers}-{nkpts}x{nkpts}-{ecut:.0f}'

    parameters = dict(mode=PW(ecut),
                      eigensolver=Davidson(niter=2),
                      poissonsolver={'dipolelayer': 'xy'},
                      kpts={'size': (nkpts, nkpts, 1), 'gamma': True},
                      xc='PBE')

    # N/Ru(0001):
    slab = hcp0001('Ru', a=a, c=c, size=(1, 1, nlayers))
    z = slab.positions[:, 2].max() + height
    x, y = np.dot([2 / 3, 2 / 3], slab.cell[:2, :2])
    slab.append('N')
    slab.positions[-1] = [x, y, z]
    slab.center(vacuum=vacuum, axis=2)  # 2: z-axis

    # Fix first nlayer atoms:
    slab.constraints = FixAtoms(indices=list(range(nlayers)))

    id = db.reserve(name=f'N/{nlayers}Ru(0001)', nkpts=nkpts, ecut=ecut)
    if id is not None:  # skip calculation if already done
        slab.calc = GPAW(txt='N' + name + '.txt',
                         **parameters)
        optimizer = BFGSLineSearch(slab, logfile='N' + name + '.opt')
        optimizer.run(fmax=0.01)
        height = slab.positions[-1, 2] - slab.positions[:-1, 2].max()
        del db[id]
        db.write(slab,
                 name=f'N/{nlayers}Ru(0001)', nkpts=nkpts, ecut=ecut,
                 height=height)

    # Clean surface (single point calculation):
    id = db.reserve(name=f'{nlayers}Ru(0001)', nkpts=nkpts, ecut=ecut)
    if id is not None:
        del slab[-1]  # remove nitrogen atom
        slab.calc = GPAW(txt=name + '.txt',
                         **parameters)
        slab.get_forces()
        del db[id]
        db.write(slab,
                 name=f'{nlayers}Ru(0001)', nkpts=nkpts, ecut=ecut)

    # Nitrogen atom:
    id = db.reserve(name='N-atom', ecut=ecut)
    if id is not None:
        # Create spin-polarized nitrogen atom:
        molecule = Atoms('N', magmoms=[3])
        molecule.center(vacuum=4.0)
        # Remove parameters that make no sense for an isolated atom:
        del parameters['kpts']
        del parameters['poissonsolver']
        # Calculate energy:
        molecule.calc = GPAW(txt=name + '.txt', **parameters)
        molecule.get_potential_energy()
        del db[id]
        db.write(molecule, name='N-atom', ecut=ecut)

    return height
Esempio n. 8
0
water = molecule('H2O')
print(water)
print(water.positions)

#iron = bulk('Fe', cubic = True)
#view(iron)

calc = EMT()
water.set_calculator(calc)
energy = water.get_potential_energy()
forces = water.get_forces()

print(energy)
print(forces)

relax = BFGSLineSearch(atoms=water)
relax.run(
    fmax=0.05)  # relax the structure until the maximum force is 0.05 eV/A

print(water.positions)
#view(water)

O2 = molecule('O2')
O2.set_calculator(EMT())

dyn = QuasiNewton(O2)
dyn.run()
E_O2 = O2.get_potential_energy()

H2 = molecule('H2')
H2.set_calculator(EMT())
Esempio n. 9
0
def example():
    from ase.calculators.lj import LennardJones
    from theforce.util.flake import Hex
    from ase.io.trajectory import Trajectory
    from ase.optimize import BFGSLineSearch
    from ase.io import Trajectory

    # initial state + dft calculator
    ini_atoms = TorchAtoms(positions=Hex().array(), cutoff=3.0)
    dftcalc = LennardJones()
    ini_atoms.set_calculator(dftcalc)
    BFGSLineSearch(ini_atoms).run(fmax=0.01)
    vel = np.random.uniform(-1., 1., size=ini_atoms.positions.shape) * 1.
    vel -= vel.mean(axis=0)
    ini_atoms.set_velocities(vel)

    # use a pretrained model by writing it to the checkpoint
    # (alternatively set, for example, itrain=10*[5] in mlmd)
    pre = """GaussianProcessPotential([PairKernel(RBF(signal=3.2251566545458794, lengthscale=tensor([0.1040])),
    0, 0, factor=PolyCut(3.0, n=2))], White(signal=0.1064043798026091, requires_grad=True))""".replace(
        '\n', '')
    with open('gp.chp', 'w') as chp:
        chp.write(pre)

    # run(md)
    mlmd(ini_atoms,
         3.0,
         0.5,
         0.03,
         tolerance=0.18,
         max_steps=100,
         soap=False,
         itrain=10 * [3],
         retrain_every=5,
         retrain=5)

    # recalculate all with the actual calculator and compare
    traj = Trajectory('md.traj')
    energies = []
    forces = []
    dum = 0
    for atoms in traj:
        dum += 1
        e = atoms.get_potential_energy()
        f = atoms.get_forces()
        dftcalc.calculate(atoms)
        ee = dftcalc.results['energy']
        ff = dftcalc.results['forces']
        energies += [(e, ee)]
        forces += [(f.reshape(-1), ff.reshape(-1))]

    import pylab as plt
    get_ipython().run_line_magic('matplotlib', 'inline')
    fig, axes = plt.subplots(1, 2, figsize=(8, 3))
    axes[0].scatter(*zip(*energies))
    axes[0].set_xlabel('ml')
    axes[0].set_ylabel('dft')
    a, b = (np.concatenate(v) for v in zip(*forces))
    axes[1].scatter(a, b)
    axes[1].set_xlabel('ml')
    axes[1].set_ylabel('dft')
    fig.tight_layout()
    fig.text(0.2, 0.8, 'energy')
    fig.text(0.7, 0.8, 'forces')
Esempio n. 10
0
with open('%s_results.txt' % prefix, 'w') as fout:
    fout.write('id  evaluations\n')
# Loop over all molecules in the bechmark set
for i in range(1, 31):
    atoms = read('%02d.xyz' % i)
    calc = QChem(label='calculations/%s/mol_%02d' % (prefix, i),
                 scratch='calculations/%s/scratch' % prefix,
                 nt=4,
                 jobtype='force',
                 method='HF',
                 basis='STO-3G',
                 scf_algorithm='DIIS_GDM',
                 max_scf_cycles='500',
                 scf_convergence='7',
                 charge=0,
                 multiplicity=1)
    atoms.set_calculator(EvalCountingCalculator(calc))
    # Do first evaluation
    atoms.get_forces()
    # and switch scf_guess to read
    calc.set(scf_guess='read')

    opt = BFGSLineSearch(atoms)
    opt.run(fmax=0.01)
    # Append to the results file
    with open('%s_results.txt' % prefix, 'a') as fout:
        fout.write('%2d    % 3d\n' % (i, atoms.calc.n_evals))
    sum_evals += atoms.calc.n_evals
with open('%s_results.txt' % prefix, 'a') as fout:
    fout.write('sum   % 3d\n' % sum_evals)