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
def test_create_calc(self): params = {"mu_symbol": "mu", "k_points_grid": [7, 7, 7]} reader = ReadWriteCastep(params=params) reader._create_calculator() calc_geom = reader._update_calculator("GEOM_OPT") self.assertEqual(calc_geom.param.task.value, "GeometryOptimization") calc_magres = reader._update_calculator(calc_type="MAGRES") # Tests that the calculators have the correct tasks set: self.assertEqual(calc_magres.param.task.value, "Magres") self.assertEqual(calc_magres.param.magres_task.value, "Hyperfine") # Tests that k_points_grid gets set in both calculators self.assertEqual(calc_geom.cell.kpoint_mp_grid.value, list_to_string(params['k_points_grid'])) self.assertEqual(calc_magres.cell.kpoint_mp_grid.value, list_to_string(params['k_points_grid']))
def save_muonconf_castep(a, folder, params): # Muon mass and gyromagnetic ratio mass_block = 'AMU\n{0} 0.1138' gamma_block = 'radsectesla\n{0} 851586494.1' if isinstance(a.calc, Castep): ccalc = a.calc else: ccalc = Castep() 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 a.set_calculator(ccalc) name = os.path.split(folder)[-1] io.write(os.path.join(folder, '{0}.cell'.format(name)), a) ccalc.atoms = a if params['castep_param'] is not None: castep_params = yaml.load(open(params['castep_param'], 'r')) else: castep_params = {} # Parameters from .yaml will overwrite parameters from .param castep_params['task'] = "GeometryOptimization" castep_params['geom_max_iter'] = params['geom_steps'] castep_params['geom_force_tol'] = params['geom_force_tol'] castep_params['max_scf_cycles'] = params['max_scc_steps'] parameter_file = os.path.join(folder, '{0}.param'.format(name)) yaml.safe_dump(castep_params, open(parameter_file, 'w'), default_flow_style=False)
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
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()
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)