| 1732 | } |
| 1733 | |
| 1734 | def execute(self, spec: SimulationSpec, paths: RunPaths) -> BackendRunResult: |
| 1735 | module = self._ensure_module() |
| 1736 | with _temporary_env("MaterialDFT_OSZICAR_PATH", str(paths.artifacts_dir / "OSZICAR")): |
| 1737 | if spec.mode == "relax": |
| 1738 | payload = self._execute_relax(module, spec) |
| 1739 | else: |
| 1740 | input_obj = copy.deepcopy(spec.input) |
| 1741 | settings = input_obj.get("settings") |
| 1742 | if isinstance(settings, dict): |
| 1743 | if not _settings_has_key_case_insensitive(settings, "ediff"): |
| 1744 | settings["ediff"] = VASP_DEFAULT_EDIFF |
| 1745 | self._apply_gate_min_nelm(spec, settings) |
| 1746 | settings["return_density"] = True |
| 1747 | potential_overrides = self._build_potential_overrides(spec) |
| 1748 | request = { |
| 1749 | "case_id": spec.case_id, |
| 1750 | "mode": spec.mode, |
| 1751 | "input": input_obj, |
| 1752 | "resources": spec.resources, |
| 1753 | "runtime_policy": spec.runtime_policy, |
| 1754 | } |
| 1755 | request = self._apply_potential_overrides(spec, request, potential_overrides) |
| 1756 | payload = self._invoke_cpp_with_symmetry(module, request) |
| 1757 | |
| 1758 | output = payload.get("output") |
| 1759 | if not isinstance(output, dict): |
| 1760 | raise BackendExecutionError("cpp_core payload missing output object", "RUNTIME_ERROR", "POSTPROCESS") |
| 1761 | self._convert_stress_to_vasp_convention(output) |
| 1762 | |
| 1763 | diagnostics = payload.get("diagnostics") |
| 1764 | if not isinstance(diagnostics, dict): |
| 1765 | diagnostics = {} |
| 1766 | diagnostics = self._normalize_diagnostics(spec.mode, output, diagnostics) |
| 1767 | |
| 1768 | run_meta = payload.get("run_meta") |
| 1769 | if not isinstance(run_meta, dict): |
| 1770 | run_meta = {} |
| 1771 | spec_settings = self._input_obj(spec).get("settings") |
| 1772 | if isinstance(spec_settings, dict): |
| 1773 | run_meta.setdefault("isym", self._parse_isym(spec_settings)) |
| 1774 | run_meta.setdefault("backend", self.name) |
| 1775 | run_meta.setdefault("case_id", spec.case_id) |
| 1776 | if self._compute_stress_requested(spec): |
| 1777 | self._mark_missing_requested_stress_error(output, diagnostics, run_meta) |
| 1778 | |
| 1779 | files: dict[str, Any] = {} |
| 1780 | if output.get("scf_truncated_before_diagonalization", False): |
| 1781 | files = write_truncated_paw_json_outputs( |
| 1782 | run_dir=paths.run_dir, |
| 1783 | artifacts_dir=paths.artifacts_dir, |
| 1784 | output=output, |
| 1785 | ) |
| 1786 | else: |
| 1787 | files = write_vasp_like_outputs( |
| 1788 | run_dir=paths.run_dir, |
| 1789 | artifacts_dir=paths.artifacts_dir, |
| 1790 | spec_input=spec.input, |
| 1791 | output=output, |