示例#1
0
def create_hfine_castep_calculator(mu_symbol='H:mu',
                                   calc=None,
                                   param_file=None,
                                   kpts=[1, 1, 1]):
    """Create a calculator containing all the necessary parameters
    for a hyperfine calculation."""

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

    gamma_block = calc.cell.species_gamma.value
    calc.cell.species_gamma = add_to_castep_block(gamma_block, mu_symbol,
                                                  constants.m_gamma, 'gamma')

    calc.cell.kpoint_mp_grid = kpts

    if param_file is not None:
        calc.param = read_param(param_file).param

    calc.param.task = 'Magres'
    calc.param.magres_task = 'Hyperfine'

    return calc
示例#2
0
    def _create_calculator(self, calc_type=None):
        with silence_stdio():
            if self._calc is not None and isinstance(self._calc, Castep):
                calc = deepcopy(self._calc)
            else:
                calc = Castep()

        mu_symbol = self.params.get('mu_symbol', 'H:mu')

        # Start by ensuring that the muon mass and gyromagnetic ratios are
        # included
        gamma_block = calc.cell.species_gamma.value
        if gamma_block is None:
            calc.cell.species_gamma = add_to_castep_block(
                gamma_block, mu_symbol, constants.m_gamma, 'gamma')

            mass_block = calc.cell.species_mass.value
            calc.cell.species_mass = add_to_castep_block(
                mass_block, mu_symbol, constants.m_mu_amu, 'mass')

        # Now assign the k-points
        k_points_param = self.params.get('k_points_grid')

        if k_points_param is not None:
            calc.cell.kpoint_mp_grid = list_to_string(k_points_param)
        else:
            if calc.cell.kpoint_mp_grid is None:
                calc.cell.kpoint_mp_grid = list_to_string([1, 1, 1])

        # Read the parameters
        pfile = self.params.get('castep_param', None)
        if pfile is not None:
            with silence_stdio():
                calc.param = read_param(self.params['castep_param']).param

        self._calc = calc

        if calc_type == "MAGRES":
            calc = self._create_hfine_castep_calculator()
        elif calc_type == "GEOM_OPT":
            calc = self._create_geom_opt_castep_calculator()

        return self._calc
示例#3
0
    def _create_hfine_castep_calculator(self):
        """Update calculator to contain all the necessary parameters
        for a hyperfine calculation."""

        # Remove settings for geom_opt calculator:
        self._calc.param.geom_max_iter = None
        self._calc.param.geom_force_tol = None
        self._calc.param.max_scf_cycles = None
        self._calc.param.write_cell_structure = None
        self._calc.param.charge = None
        self._calc.cell.fix_all_cell = None

        pfile = self.params.get('castep_param', None)
        if pfile is not None:
            with silence_stdio():
                self._calc.param = read_param(
                    self.params['castep_param']).param

        self._calc.param.task = 'Magres'
        self._calc.param.magres_task = 'Hyperfine'

        return self._calc
示例#4
0
def create_muairss_castep_calculator(a, params={}, calc=None):
    """Create a calculator containing all the necessary parameters
    for a geometry optimization."""

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

    musym = params.get('mu_symbol', 'H:mu')

    # Start by ensuring that the muon mass and gyromagnetic ratios are included
    mass_block = calc.cell.species_mass.value
    calc.cell.species_mass = add_to_castep_block(mass_block, musym,
                                                 cnst.m_mu_amu,
                                                 'mass')

    gamma_block = calc.cell.species_gamma.value
    calc.cell.species_gamma = add_to_castep_block(gamma_block, musym,
                                                  851586494.1, 'gamma')

    # Now assign the k-points
    calc.cell.kpoint_mp_grid = list_to_string(
        params.get('k_points_grid', [1, 1, 1]))
    calc.cell.fix_all_cell = True   # Necessary for older CASTEP versions
    calc.param.charge = params.get('charged', False)*1.0

    # Read the parameters
    pfile = params.get('castep_param', None)
    if pfile is not None:
        calc.param = read_param(params['castep_param']).param

    calc.param.task = 'GeometryOptimization'
    calc.param.geom_max_iter = params.get('geom_steps', 30)
    calc.param.geom_force_tol = params.get('geom_force_tol', 0.05)
    calc.param.max_scf_cycles = params.get('max_scc_steps', 30)

    return calc
示例#5
0
def convert_single_structure(gen_file, param_file, directory="."):
    atoms = io.read(gen_file)
    params = load_input_file(param_file)

    # Muon mass and gyromagnetic ratio
    mass_block = 'AMU\n{0}       0.1138'
    gamma_block = 'radsectesla\n{0}        851586494.1'

    ccalc = Castep(castep_command=params['castep_command'])
    ccalc.cell.kpoint_mp_grid.value = list_to_string(params['k_points_grid'])
    ccalc.cell.species_mass = mass_block.format(
        params['mu_symbol']).split('\n')
    ccalc.cell.species_gamma = gamma_block.format(
        params['mu_symbol']).split('\n')
    ccalc.cell.fix_all_cell = True  # To make sure for older CASTEP versions

    atoms.set_calculator(ccalc)

    symbols = atoms.get_chemical_symbols()
    symbols[-1] = params['mu_symbol']
    atoms.set_array('castep_custom_species', np.array(symbols))

    name = "{}.cell".format(params['name'])
    cell_file = os.path.join(directory, name)
    io.write(cell_file, atoms)

    # Param file?
    if params['castep_param'] is not None:
        p = read_param(params['castep_param']).param
        # Set up task and geometry optimization steps
        p.task.value = 'GeometryOptimization'
        p.geom_max_iter.value = params['geom_steps']
        p.geom_force_tol.value = params['geom_force_tol']

        param_file = os.path.join(directory, "{}.param".format(params['name']))
        write_param(param_file, p, force_write=True)
示例#6
0
def main(seedname, cmdline_task):

    seedpath, basename = os.path.split(seedname)

    utils.check_pyversion()

    print(__intromsg__)

    print('Reading {0}.conv'.format(seedname))

    try:
        with open('{0}.conv'.format(seedname)) as f:
            convpars = parse_convfile(f.read())
    except IOError:
        utils.warn('.conv file not found - using default parameters')
        convpars = parse_convfile()

    task = cmdline_task if cmdline_task is not None else convpars['ctsk']

    # Now open the base cell and param files
    cname = '{0}.cell'.format(seedname)
    print('Reading ' + cname)

    # Necessary because of ASE's annoying messages...
    cfile = read_castep_cell(open(cname),
                             calculator_args={'keyword_tolerance': 3})

    pname = '{0}.param'.format(seedname)
    print('Reading ' + pname)
    try:
        read_param(pname, calc=cfile.calc)
    except FileNotFoundError:
        print('File {0} not found, skipping'.format(pname))

    print('')

    # Now go for clearing
    if task == 'clear':

        to_del = [basename + f for f in [_in_dir, _out_dir, _json_file]]

        print('The following files and folders will be removed:\n\t' +
              '\n\t'.join(to_del))
        ans = utils.safe_input('Continue (y/N)? ')

        if ans.lower() == 'y':
            for f in to_del:
                if not os.path.exists(f):
                    continue
                try:
                    os.remove(f)
                except OSError:
                    shutil.rmtree(f)

        return

    # Strip the files
    cfile.calc.param.task = 'SinglePoint'
    cfile.calc.param.calculate_stress = convpars['cnvstr']

    # Clean up all references to kpoints
    kclean = [
        'kpoints_mp_grid', 'kpoint_mp_grid', 'kpoints_mp_spacing',
        'kpoint_mp_spacing', 'kpoints_list', 'kpoint_list'
    ]
    # These, clean up only in the presence of the relevant option
    if convpars['gamma']:
        kclean += ['kpoints_mp_offset', 'kpoint_mp_offset']

    for k in kclean:
        cfile.calc.cell.__setattr__(k, None)

    # Get the kpoint basis
    invcell = cfile.get_reciprocal_cell()
    kpnbase = np.linalg.norm(invcell, axis=1)
    kpnbase = kpnbase / min(kpnbase)

    # Convergence ranges?
    convranges = make_ranges(convpars, kpnbase)

    # Ask for confirmation
    if task in ('input', 'inputrun', 'all'):
        try:
            os.mkdir(basename + _in_dir)
        except OSError:
            utils.warn('Input directory existing - some files could be '
                       'overwritten.')
            ans = utils.safe_input('Continue (y/N)? ')
            if ans.lower() != 'y':
                return

    if task in ('output', 'all'):
        try:
            os.mkdir(basename + _out_dir)
        except OSError:
            utils.warn('Output directory existing - some files could be '
                       'overwritten.')
            ans = utils.safe_input('Continue (y/N)? ')
            if ans.lower() != 'y':
                return

    # The Worktree object is useful for a number of things in all tasks
    wtree = Worktree(basename, convpars, convranges)

    ### PHASE 1: Input ###
    if task in ('input', 'inputrun', 'all'):
        # Now look for pseudopotentials
        find_pspots(cfile, basename, seedpath)

        add_castepopts(cfile, convpars['c8plus'])

        # If required, rattle the atoms
        if convpars['displ'] != 0:
            cfile.rattle(abs(convpars['displ']))
            cfile.calc.cell.symmetry_generate = None
            cfile.calc.cell.symmetry_ops = None

        wtree.write(cfile)

    ### PHASE 2: Running ###
    if task in ('inputrun', 'all'):

        # Not waiting only makes sense for inputrun
        wait = convpars['jwait'] or (task == 'all')
        wtree.run(convpars['rcmd'], wait)

    ### PHASE 3: Output processing ###
    if task in ('output', 'all'):

        data_curves = wtree.read_data()

        print('Writing output to ' + basename + _out_dir)

        write_dat(basename, data_curves, basename + _out_dir)

        write_report(basename, data_curves, convpars['nrgtol'],
                     convpars['fortol'], convpars['strtol'],
                     basename + _out_dir)

        if convpars['outp'] == 'gnuplot':
            gp_plot(basename, data_curves, basename + _out_dir)
        elif convpars['outp'] == 'grace':
            agr_plot(basename, data_curves, basename + _out_dir)
示例#7
0
    def testCASTEP(self):
        try:
            yaml_file = os.path.join(_TESTDATA_DIR, "Si2-muairss-castep.yaml")
            cell_file = os.path.join(_TESTDATA_DIR, "Si2.cell")
            param_file = os.path.join(_TESTDATA_DIR, "Si2.param")
            input_params = load_input_file(yaml_file, MuAirssSchema)
            with silence_stdio(True, True):
                castep_param = read_param(param_file).param

            # Run Muairss write:
            sys.argv[1:] = ["-tw", cell_file, yaml_file]
            os.chdir(_TESTDATA_DIR)
            run_muairss()
            # Check all folders contain a yaml file
            for (rootDir, subDirs, files) in os.walk("muon-airss-out-castep/castep/"):
                for s in subDirs:
                    expected_file = os.path.join(
                        "muon-airss-out-castep/castep/" + s, s + ".cell"
                    )
                    script_file = input_params["script_file"]
                    if script_file is not None:
                        expected_script = os.path.join(
                            "muon-airss-out-castep/castep/" + s, "script.sh"
                        )
                        self.assertTrue(os.path.exists(expected_script))

                    self.assertTrue(os.path.exists(expected_file))
                    with silence_stdio():
                        atoms = io.read(expected_file)
                    self.assertEqual(
                        atoms.calc.cell.kpoint_mp_grid.value,
                        list_to_string(input_params["k_points_grid"]),
                    )
                    expected_param_file = os.path.join(
                        "muon-airss-out-castep/castep/" + s, s + ".param"
                    )
                    self.assertTrue(os.path.exists(expected_param_file))
                    with silence_stdio():
                        output_castep_param = read_param(expected_param_file).param
                    self.assertEqual(
                        output_castep_param.cut_off_energy,
                        castep_param.cut_off_energy,
                    )
                    self.assertEqual(
                        output_castep_param.elec_energy_tol,
                        castep_param.elec_energy_tol,
                    )
                    # below test didn't work as cell positions get rounded...
                    # equal = atoms.cell == input_atoms.cell
                    # self.assertTrue(equal.all())

            yaml_file = os.path.join(_TESTDATA_DIR, "Si2-muairss-castep-read.yaml")
            sys.argv[1:] = [cell_file, yaml_file]
            run_muairss()

            self.assertTrue(os.path.exists("Si2_clusters.txt"))
            self.assertTrue(os.path.exists("Si2_Si2_castep_clusters.dat"))

            # Test clustering_write_input has produced files we expect:
            self.assertTrue(os.path.exists("Si2_clusters"))
            calc_folder = "Si2_clusters/castep/"
            for (rootDir, subDirs, files) in os.walk(calc_folder):
                for s in subDirs:
                    expected_file = os.path.join(calc_folder + s, s + ".cell")
                    self.assertTrue(os.path.exists(expected_file))
                    with silence_stdio():
                        atoms = io.read(expected_file)
                    self.assertEqual(
                        atoms.calc.cell.kpoint_mp_grid.value,
                        list_to_string(input_params["k_points_grid"]),
                    )
                    expected_param_file = os.path.join(calc_folder + s, s + ".param")
                    self.assertTrue(os.path.exists(expected_param_file))
                    with silence_stdio():
                        output_castep_param = read_param(expected_param_file).param
                    self.assertEqual(
                        output_castep_param.cut_off_energy,
                        castep_param.cut_off_energy,
                    )
                    self.assertEqual(
                        output_castep_param.elec_energy_tol,
                        castep_param.elec_energy_tol,
                    )
        finally:
            # Remove all created files and folders
            _clean_testdata_dir()
示例#8
0
    def test_write(self):
        # read in cell file to get atom
        try:
            input_folder = _TESTDATA_DIR + "/Si2"
            output_folder = os.path.join(_TESTDATA_DIR, "test_save")
            os.mkdir(output_folder)

            os.chdir(input_folder)

            yaml_file = os.path.join(input_folder, "Si2-muairss-castep.yaml")
            cell_file = os.path.join(input_folder, "Si2.cell")
            param_file = os.path.join(input_folder, "Si2.param")
            input_params = load_input_file(yaml_file, MuAirssSchema)

            with silence_stdio():
                castep_param = read_param(param_file).param
                atoms = io.read(cell_file)

            # test writing geom_opt output
            reader = ReadWriteCastep(params=input_params)
            reader.write(
                atoms,
                output_folder,
                sname="Si2_geom_opt",
                calc_type="GEOM_OPT",
            )

            reader.write(atoms, output_folder, sname="Si2_magres", calc_type="MAGRES")

            # # read back in and check that atom locations are preserved
            with silence_stdio():
                geom_opt_atoms = io.read(
                    os.path.join(output_folder, "Si2_geom_opt.cell")
                )
                magres_atoms = io.read(os.path.join(output_folder, "Si2_magres.cell"))
            equal = atoms.positions == geom_opt_atoms.positions
            # self.assertTrue(equal.all()) # is not true due to to rounding
            equal = geom_opt_atoms.positions == magres_atoms.positions
            self.assertTrue(equal.all())
            self.assertEqual(
                geom_opt_atoms.calc.cell.kpoint_mp_grid.value,
                list_to_string(input_params["k_points_grid"]),
            )
            self.assertEqual(
                magres_atoms.calc.cell.kpoint_mp_grid.value,
                list_to_string(input_params["k_points_grid"]),
            )

            # Test if parameters file have correct tasks:
            with silence_stdio():
                geom_params = read_param(
                    os.path.join(output_folder, "Si2_geom_opt.param")
                ).param
                magres_params = read_param(
                    os.path.join(output_folder, "Si2_magres.param")
                ).param
            self.assertEqual(geom_params.task.value, "GeometryOptimization")
            self.assertEqual(magres_params.task.value, "Magres")
            self.assertEqual(magres_params.magres_task.value, "Hyperfine")
            # These are only set in the param file only so should equal
            # the value in the param file:
            self.assertEqual(geom_params.geom_max_iter, castep_param.geom_max_iter)
            self.assertEqual(geom_params.cut_off_energy, castep_param.cut_off_energy)
            self.assertEqual(geom_params.elec_energy_tol, castep_param.elec_energy_tol)
            # This is set in the input yaml and param file so should equal
            # the value in the yaml file:
            self.assertEqual(
                geom_params.geom_force_tol.value,
                str(input_params["geom_force_tol"]),
            )

            self.assertEqual(magres_params.cut_off_energy, castep_param.cut_off_energy)
            self.assertEqual(
                magres_params.elec_energy_tol, castep_param.elec_energy_tol
            )

        finally:
            shutil.rmtree(output_folder)