diff --git a/castep_outputs/castep_file_parser.py b/castep_outputs/castep_file_parser.py index 43f48e1..f94e5f0 100644 --- a/castep_outputs/castep_file_parser.py +++ b/castep_outputs/castep_file_parser.py @@ -1146,6 +1146,18 @@ def parse_castep_file(castep_file_in: TextIO, *, curr_run["elastic"].update(_process_elastic_properties(block)) + # DeltaSCF + + elif block := get_block(line, castep_file, + "Calculating MODOS weights", r"^\s*$"): + + if "scf" not in to_parse: + continue + + logger("Found delta SCF data") + + curr_run["delta_scf"] = _process_delta_scf(block) + # --- Extra blocks for testing # Hugoniot data @@ -2283,3 +2295,34 @@ def _process_elastic_properties(block: TextIO) -> Dict[str, Union[float, ThreeVe ) return accum + + +def _process_delta_scf(block: TextIO) -> Dict[str, Union[str, List[Dict[str, Any]]]]: + """Process MODOS delta SCF block""" + accum: Dict[str, Union[str, List[Dict[str, Any]]]] = {"states": []} + assert isinstance(accum["states"], list) + + for line in block: + if line.startswith("Taking band from"): + accum["file"] = line.split()[-1] + elif "MODOS state" in line: + accum["states"].append({}) + elif "nr." in line: + accum["states"][-1]["band"] = int(get_numbers(line)[0]) + elif "spin" in line: + accum["states"][-1]["spin"] = int(get_numbers(line)[0]) + elif "Population of state" in line: + numbers = get_numbers(line) + band, spin, pop = int(numbers[0]), int(numbers[1]), float(numbers[2]) + + for state in accum["states"]: + if state["band"] == band and state["spin"] == spin: + state["pop"] = pop + + elif "Writing file" in line: + band, spin = map(int, get_numbers(line)[-2:]) + for state in accum["states"]: + if state["band"] == band and state["spin"] == spin: + state["file"] = line.split()[-1] + + return accum diff --git a/castep_outputs/test/test_castep_parser.py b/castep_outputs/test/test_castep_parser.py index 95efa9a..f26a0e0 100644 --- a/castep_outputs/test/test_castep_parser.py +++ b/castep_outputs/test/test_castep_parser.py @@ -899,7 +899,8 @@ def test_get_target_stress(self): def test_delta_scf(self): test_text = io.StringIO(""" -+-------------------INPUT PARAMETERS-------------------+ + Calculating MODOS weights + +-------------------INPUT PARAMETERS-------------------+ Taking band from model N2-base.check MODOS state 1 MODOS band nr. 5 @@ -909,12 +910,22 @@ def test_delta_scf(self): MODOS band has spin 1 |DeltaSCF| Population of state: 5 1 1.000000 |DeltaSCF| Population of state: 6 1 0.000000 + Writing file N2-modos.modos_state_5_1 + Writing file N2-modos.modos_state_6_1 """) - self.skipTest("Not implemented yet") + test_dict = parse_castep_file(test_text)[0] - pprint.pprint(test_dict) - self.assertEqual(test_dict, {}) + + self.assertEqual(test_dict, {'delta_scf': {'file': 'N2-base.check', + 'states': [{'band': 5, + 'file': 'N2-modos.modos_state_5_1', + 'pop': 1.0, + 'spin': 1}, + {'band': 6, + 'file': 'N2-modos.modos_state_6_1', + 'pop': 0.0, + 'spin': 1}]}}) def test_get_scf(self): test_text = io.StringIO("""