Example #1
0
def save_muonconf_dftb(a, folder, params, dftbargs={}):

    from pymuonsuite.data.dftb_pars import DFTBArgs

    name = os.path.split(folder)[-1]

    a.set_pbc(params['dftb_pbc'])

    dargs = DFTBArgs(params['dftb_set'])

    custom_species = a.get_array('castep_custom_species')
    muon_index = np.where(custom_species == params['mu_symbol'])[0][0]

    is_spinpol = params.get('spin_polarized', False)
    if is_spinpol:
        dargs.set_optional('spinpol.json', True)

    # Add muon mass
    args = dargs.args
    args['Driver_'] = 'ConjugateGradient'
    args['Driver_Masses_'] = ''
    args['Driver_Masses_Mass_'] = ''
    args['Driver_Masses_Mass_Atoms'] = '{}'.format(muon_index)
    args['Driver_Masses_Mass_MassPerAtom [amu]'] = '0.1138'

    args['Driver_MaxForceComponent [eV/AA]'] = params['geom_force_tol']
    args['Driver_MaxSteps'] = params['geom_steps']
    args['Driver_MaxSccIterations'] = params['max_scc_steps']

    if is_spinpol:
        # Configure initial spins
        spins = np.array(a.get_initial_magnetic_moments())
        args['Hamiltonian_SpinPolarisation_InitialSpins'] = '{'
        args['Hamiltonian_SpinPolarisation_' +
             'InitialSpins_AllAtomSpins'] = '{' + '\n'.join(
            map(str, spins)) + '}'
        args['Hamiltonian_SpinPolarisation_UnpairedElectrons'] = str(
            np.sum(spins))

    # Add any custom arguments
    if isinstance(dftbargs, DFTBArgs):
        args.update(dftbargs.args)
    else:
        args.update(dftbargs)

    if params['dftb_pbc']:
        dcalc = Dftb(label=name, atoms=a,
                     kpts=params['k_points_grid'],
                     run_manyDftb_steps=True, **args)
    else:
        dcalc = Dftb(label=name, atoms=a, run_manyDftb_steps=True, **args)

    dcalc.directory = folder
    dcalc.write_input(a)
Example #2
0
def asephonons_entry():

    from ase import io
    from ase.calculators.dftb import Dftb
    from pymuonsuite.data.dftb_pars import DFTBArgs

    parser = ap.ArgumentParser(description="Compute phonon modes with ASE and"
                               " DFTB+ for reuse in quantum effects "
                               "calculations.")
    parser.add_argument('structure_file',
                        type=str,
                        help="Structure for which to compute the phonons")
    parser.add_argument('parameter_file',
                        type=str,
                        help="YAML file containing relevant input parameters")

    args = parser.parse_args()

    # Load parameters
    params = load_input_file(args.parameter_file, AsePhononsSchema)

    fname, fext = os.path.splitext(args.structure_file)
    if params['name'] is None:
        params['name'] = fname

    # Load structure
    a = io.read(args.structure_file)
    # Create a Dftb calculator
    dargs = DFTBArgs(params['dftb_set'])
    # Is it periodic?
    if params['pbc']:
        a.set_pbc(True)
        calc = Dftb(atoms=a,
                    label='asephonons',
                    kpts=params['kpoint_grid'],
                    **dargs.args)
        ph_kpts = params['phonon_kpoint_grid']
    else:
        a.set_pbc(False)
        calc = Dftb(atoms=a, label='asephonons', **dargs.args)
        ph_kpts = None
    a.set_calculator(calc)
    phdata = ase_phonon_calc(a,
                             kpoints=ph_kpts,
                             ftol=params['force_tol'],
                             force_clean=params['force_clean'],
                             name=params['name'])

    # Save optimised structure
    io.write(params['name'] + '_opt' + fext, phdata.structure)

    # And write out the phonons
    outf = params['name'] + '_opt.phonons.pkl'
    pickle.dump(phdata, open(outf, 'wb'))
    write_phonon_report(args, params, phdata)
Example #3
0
def create_spinpol_dftbp_calculator(calc=None, param_set='3ob-3-1', kpts=None):
    """Create a calculator containing all necessary parameters for a DFTB+
    SCC spin polarised calculation"""
    from pymuonsuite.data.dftb_pars import DFTBArgs

    if not isinstance(calc, Dftb):
        calc = Dftb()
    else:
        calc = deepcopy(calc)

    # A bit of a hack for the k-points
    if kpts is not None:
        kc = Dftb(kpts=kpts)
        kargs = {k: v for k, v in kc.parameters.items() if 'KPoints' in k}
        calc.parameters.update(kargs)

    # Create the arguments
    dargs = DFTBArgs(param_set)
    # Make it spin polarised
    try:
        dargs.set_optional('spinpol.json', True)
    except KeyError:
        raise ValueError('DFTB+ parameter set does not allow spin polarised'
                         ' calculations')
    # Fix a few things, and add a spin on the muon
    args = dargs.args
    del (args['Hamiltonian_SpinPolarisation'])
    args['Hamiltonian_SpinPolarisation_'] = 'Colinear'
    args['Hamiltonian_SpinPolarisation_UnpairedElectrons'] = 1
    args['Hamiltonian_SpinPolarisation_InitialSpins_'] = ''
    args['Hamiltonian_SpinPolarisation_InitialSpins_Atoms'] = '-1'
    args['Hamiltonian_SpinPolarisation_InitialSpins_SpinPerAtom'] = 1

    calc.parameters.update(args)
    calc.do_forces = True

    return calc
Example #4
0
    def test_create_calc(self):
        # Tests whether the correct values of the parameters are set
        # when creating a calculator that would be used for writing
        # a dftb input file.

        def check_geom_opt_params(params, calc_params):
            self.assertEqual(calc_params["Hamiltonian_Charge"], params["charged"] * 1.0)
            self.assertEqual(calc_params["Driver_MaxSteps"], params["geom_steps"])
            self.assertEqual(
                calc_params["Driver_MaxForceComponent [eV/AA]"],
                params["geom_force_tol"],
            )
            self.assertEqual(
                calc_params["Hamiltonian_MaxSccIterations"],
                params["max_scc_steps"],
            )

        # In the case that a params dict is provided, the values for the
        # parameters should be taken from here.
        params = {
            "k_points_grid": [2, 2, 2],
            "geom_force_tol": 0.01,
            "dftb_set": "pbc-0-3",
            "dftb_optionals": [],
            "geom_steps": 500,
            "max_scc_steps": 150,
            "charged": False,
            "dftb_pbc": True,
        }
        reader = ReadWriteDFTB(params=params)
        # First test a geom opt calculator:
        calc_geom_opt = reader._create_calculator(calc_type="GEOM_OPT")
        calc_params = calc_geom_opt.parameters
        check_geom_opt_params(params, calc_params)
        self.assertEqual(calc_geom_opt.kpts, params["k_points_grid"])

        # Next a spinpol calculator:
        calc_magres = reader._create_calculator(calc_type="SPINPOL")
        self.assertEqual(calc_magres.kpts, params["k_points_grid"])

        # In the case that a calculator is provided, the new calculator should
        # retain the same properties.
        args = {
            "Hamiltonian_Charge": params["charged"] * 1.0,
            "Driver_MaxSteps": params["geom_steps"],
            "Driver_MaxForceComponent [eV/AA]": params["geom_force_tol"],
            "Hamiltonian_MaxSccIterations": params["max_scc_steps"],
        }
        dargs = DFTBArgs(params["dftb_set"])
        dargs.set_optional("spinpol.json", True)
        args.update(dargs.args)
        calc = Dftb(kpts=params["k_points_grid"], **args)
        reader = ReadWriteDFTB(calc=calc)
        # First test a geom opt calculator:
        calc_geom_opt = reader._create_calculator(calc_type="GEOM_OPT")
        calc_params = calc_geom_opt.parameters
        check_geom_opt_params(params, calc_params)
        self.assertEqual(calc_geom_opt.kpts, params["k_points_grid"])
        # Next a spinpol calculator:
        calc_magres = reader._create_calculator(calc_type="SPINPOL")
        self.assertEqual(calc_magres.kpts, params["k_points_grid"])

        # In the case that we do not supply a params dict or a calculator,
        # the new calculator should get the default settings:
        params = {
            "k_points_grid": None,
            "geom_force_tol": 0.05,
            "dftb_set": "3ob-3-1",
            "geom_steps": 30,
            "max_scc_steps": 200,
            "charged": False,
        }
        reader = ReadWriteDFTB()
        # First test a geom opt calculator:
        calc_geom_opt = reader._create_calculator(calc_type="GEOM_OPT")
        calc_params = calc_geom_opt.parameters
        self.assertEqual(calc_geom_opt.kpts, params["k_points_grid"])
        check_geom_opt_params(params, calc_params)
        # Next a spinpol calculator:
        calc_magres = reader._create_calculator(calc_type="SPINPOL")
        self.assertEqual(calc_magres.kpts, params["k_points_grid"])
def asephonons_entry():

    from ase import io
    from ase.calculators.dftb import Dftb
    from pymuonsuite.data.dftb_pars import DFTBArgs

    parser = ap.ArgumentParser(
        description="Compute phonon modes with ASE and"
        " DFTB+ for reuse in quantum effects "
        "calculations."
    )
    parser.add_argument(
        "structure_file",
        type=str,
        help="Structure for which to compute the phonons",
    )
    parser.add_argument(
        "parameter_file",
        type=str,
        help="YAML file containing relevant input parameters",
    )

    args = parser.parse_args()

    # Load parameters
    params = load_input_file(args.parameter_file, AsePhononsSchema)

    fname, fext = os.path.splitext(args.structure_file)
    if params["name"] is None:
        params["name"] = fname

    # Load structure
    with silence_stdio():
        a = io.read(args.structure_file)

    # Create a Dftb calculator
    dargs = DFTBArgs(params["dftb_set"])
    # Is it periodic?
    if params["pbc"]:
        a.set_pbc(True)
        calc = Dftb(
            atoms=a, label="asephonons", kpts=params["kpoint_grid"], **dargs.args
        )
        ph_kpts = params["phonon_kpoint_grid"]
    else:
        a.set_pbc(False)
        calc = Dftb(atoms=a, label="asephonons", **dargs.args)
        ph_kpts = None
    a.calc = calc
    try:
        phdata = ase_phonon_calc(
            a,
            kpoints=ph_kpts,
            ftol=params["force_tol"],
            force_clean=params["force_clean"],
            name=params["name"],
        )
    except Exception as e:
        print(e)
        print("Error: Could not write phonons file, see asephonons.out for" " details.")
        sys.exit(1)

    # Save optimised structure
    with silence_stdio():
        io.write(params["name"] + "_opt" + fext, phdata.structure)

    # And write out the phonons
    outf = params["name"] + "_opt.phonons.pkl"
    pickle.dump(phdata, open(outf, "wb"))
    write_phonon_report(args, params, phdata)