|
2 | 2 | "cells": [ |
3 | 3 | { |
4 | 4 | "cell_type": "code", |
5 | | - "execution_count": 1, |
6 | | - "id": "b116c8b3-e927-401b-aed8-994fe5279b54", |
| 5 | + "execution_count": null, |
| 6 | + "id": "0", |
7 | 7 | "metadata": {}, |
8 | 8 | "outputs": [], |
9 | 9 | "source": [ |
10 | 10 | "from __future__ import annotations\n", |
11 | 11 | "\n", |
12 | | - "from emmet.core.tasks import TaskDoc\n", |
| 12 | + "from monty.os.path import zpath\n", |
13 | 13 | "from monty.serialization import loadfn\n", |
14 | 14 | "import os\n", |
| 15 | + "from pathlib import Path\n", |
15 | 16 | "\n", |
16 | | - "from pymatgen.io.validation import ValidationDoc\n", |
17 | | - "from pymatgen.io.validation.check_potcar import CheckPotcar\n", |
| 17 | + "from pymatgen.io.validation.validation import VaspValidator\n", |
18 | 18 | "\n", |
19 | 19 | "from pymatgen.io.vasp import PotcarSingle, Potcar" |
20 | 20 | ] |
21 | 21 | }, |
22 | 22 | { |
23 | | - "cell_type": "code", |
24 | | - "execution_count": 2, |
25 | | - "id": "80064515-1e98-43da-b075-5a4c41ede437", |
| 23 | + "cell_type": "markdown", |
| 24 | + "id": "1", |
26 | 25 | "metadata": {}, |
27 | | - "outputs": [], |
28 | 26 | "source": [ |
29 | | - "\"\"\"\n", |
30 | 27 | "For copyright reasons, the POTCAR for these calculations cannot be distributed with this file, but its summary stats can.\n", |
31 | | - "If you have the POTCAR resources set up in pymatgen, you can regenerate the POTCARs used here by enabling `regen_potcars`\n", |
32 | | - "\"\"\"\n", |
33 | 28 | "\n", |
| 29 | + "If you have the POTCAR resources set up in pymatgen, you can regenerate the POTCARs used here by enabling `regen_potcars`" |
| 30 | + ] |
| 31 | + }, |
| 32 | + { |
| 33 | + "cell_type": "code", |
| 34 | + "execution_count": null, |
| 35 | + "id": "2", |
| 36 | + "metadata": {}, |
| 37 | + "outputs": [], |
| 38 | + "source": [ |
34 | 39 | "regen_potcars = True\n", |
35 | 40 | "\n", |
36 | 41 | "def get_potcar_from_spec(potcar_spec : dict) -> Potcar | None:\n", |
37 | | - " potcar_checker = CheckPotcar()\n", |
38 | 42 | " \n", |
39 | 43 | " for functional in PotcarSingle._potcar_summary_stats:\n", |
40 | 44 | "\n", |
|
47 | 51 | " \n", |
48 | 52 | " for stats in PotcarSingle._potcar_summary_stats[functional].get(titel_no_spc,[]):\n", |
49 | 53 | " \n", |
50 | | - " if potcar_checker.compare_potcar_stats(spec[\"summary_stats\"], stats):\n", |
| 54 | + " if PotcarSingle.compare_potcar_stats(spec[\"summary_stats\"], stats):\n", |
51 | 55 | " potcar.append(PotcarSingle.from_symbol_and_functional(symbol=symbol, functional=functional))\n", |
52 | 56 | " matched[ispec] = True\n", |
53 | 57 | " break\n", |
54 | 58 | " \n", |
55 | 59 | " if all(matched):\n", |
56 | 60 | " return potcar\n", |
57 | 61 | " \n", |
58 | | - "def check_calc(calc_dir : str) -> ValidationDoc:\n", |
| 62 | + "def check_calc(calc_dir : str | Path) -> VaspValidator:\n", |
| 63 | + "\n", |
| 64 | + " calc_dir = Path(calc_dir)\n", |
59 | 65 | " potcar_filename = None\n", |
60 | 66 | " if regen_potcars:\n", |
61 | | - " potcar = get_potcar_from_spec(loadfn(os.path.join(calc_dir,\"POTCAR.spec.gz\")))\n", |
| 67 | + " potcar = get_potcar_from_spec(loadfn(calc_dir / \"POTCAR.spec.gz\"))\n", |
62 | 68 | " if potcar:\n", |
63 | | - " potcar_filename = os.path.join(calc_dir,\"POTCAR.gz\")\n", |
| 69 | + " potcar_filename = calc_dir / \"POTCAR.gz\"\n", |
64 | 70 | " potcar.write_file(potcar_filename)\n", |
65 | 71 | " \n", |
66 | | - " valid_doc = ValidationDoc.from_directory(calc_dir, check_potcar=(regen_potcars and potcar))\n", |
| 72 | + " vasp_files = {\n", |
| 73 | + " k.lower().split(\".\")[0] : zpath(calc_dir / k) for k in (\n", |
| 74 | + " \"INCAR\",\"KPOINTS\",\"POSCAR\",\"POTCAR\",\"OUTCAR\", \"vasprun.xml\"\n", |
| 75 | + " )\n", |
| 76 | + " }\n", |
67 | 77 | " \n", |
| 78 | + " valid_doc = VaspValidator.from_vasp_input(\n", |
| 79 | + " vasp_file_paths={\n", |
| 80 | + " k : v for k,v in vasp_files.items() if Path(v).exists()\n", |
| 81 | + " },\n", |
| 82 | + " check_potcar=(regen_potcars and potcar)\n", |
| 83 | + " )\n", |
| 84 | + "\n", |
68 | 85 | " if potcar_filename and potcar:\n", |
69 | 86 | " os.remove(potcar_filename)\n", |
70 | 87 | " \n", |
71 | 88 | " return valid_doc\n", |
72 | 89 | " " |
73 | 90 | ] |
74 | 91 | }, |
| 92 | + { |
| 93 | + "cell_type": "markdown", |
| 94 | + "id": "3", |
| 95 | + "metadata": {}, |
| 96 | + "source": [ |
| 97 | + "An example of an MP-compatible r2SCAN static calculation for GaAs is located in the `MP_compliant` directory." |
| 98 | + ] |
| 99 | + }, |
75 | 100 | { |
76 | 101 | "cell_type": "code", |
77 | | - "execution_count": 3, |
78 | | - "id": "0f660f54-ca8a-466c-b382-2f0fac46d8bf", |
| 102 | + "execution_count": null, |
| 103 | + "id": "4", |
79 | 104 | "metadata": {}, |
80 | | - "outputs": [ |
81 | | - { |
82 | | - "name": "stdout", |
83 | | - "output_type": "stream", |
84 | | - "text": [ |
85 | | - "True\n" |
86 | | - ] |
87 | | - } |
88 | | - ], |
| 105 | + "outputs": [], |
89 | 106 | "source": [ |
90 | | - "\"\"\"\n", |
91 | | - "An example of an MP-compatible r2SCAN static calculation for GaAs is located in the `MP_compliant` directory.\n", |
92 | | - "\"\"\"\n", |
93 | 107 | "mp_compliant_doc = check_calc(\"MP_compliant\")\n", |
94 | | - "print(mp_compliant_doc.valid)" |
| 108 | + "print(mp_compliant_doc.is_valid)" |
| 109 | + ] |
| 110 | + }, |
| 111 | + { |
| 112 | + "cell_type": "markdown", |
| 113 | + "id": "5", |
| 114 | + "metadata": {}, |
| 115 | + "source": [ |
| 116 | + "We also include `TaskDoc` objects generated with `atomate2`, the workflow software currently used by the Materials Project (MP) for high-throughput calculations. A `TaskDoc` is also the document schema for the MP `task` collection.\n", |
| 117 | + "\n", |
| 118 | + "If you have `emmet-core` (this is the software used to build Materials Project data) or `atomate2` installed, you can load a `TaskDoc` like this:" |
95 | 119 | ] |
96 | 120 | }, |
97 | 121 | { |
98 | 122 | "cell_type": "code", |
99 | | - "execution_count": 4, |
100 | | - "id": "25b85de2", |
| 123 | + "execution_count": null, |
| 124 | + "id": "6", |
101 | 125 | "metadata": {}, |
102 | | - "outputs": [ |
103 | | - { |
104 | | - "name": "stdout", |
105 | | - "output_type": "stream", |
106 | | - "text": [ |
107 | | - "True\n" |
108 | | - ] |
109 | | - } |
110 | | - ], |
| 126 | + "outputs": [], |
111 | 127 | "source": [ |
112 | | - "\"\"\"\n", |
113 | | - "TaskDocs for these calculations (generated with atomate2) are also saved in these directories.\n", |
114 | | - "You can load in the TaskDocs like so:\n", |
115 | | - "\"\"\"\n", |
| 128 | + "from emmet.core.tasks import TaskDoc\n", |
| 129 | + "from pymatgen.io.validation.emmet_validation import ValidationDoc\n", |
| 130 | + "\n", |
116 | 131 | "compliant_task_doc = TaskDoc(\n", |
117 | 132 | " **loadfn(os.path.join(\"MP_compliant\",\"MP_compatible_GaAs_r2SCAN_static.json.gz\"))\n", |
118 | 133 | ")\n", |
|
121 | 136 | ] |
122 | 137 | }, |
123 | 138 | { |
124 | | - "cell_type": "code", |
125 | | - "execution_count": 5, |
126 | | - "id": "c919fedd-38ef-4cf7-a2ed-54544eec8d82", |
| 139 | + "cell_type": "markdown", |
| 140 | + "id": "7", |
127 | 141 | "metadata": {}, |
128 | | - "outputs": [ |
129 | | - { |
130 | | - "name": "stdout", |
131 | | - "output_type": "stream", |
132 | | - "text": [ |
133 | | - "False\n", |
134 | | - "INPUT SETTINGS --> KPOINTS or KSPACING: 64 kpoints were used, but it should have been at least 194.\n", |
135 | | - "INPUT SETTINGS --> ENAUG: is 900.0, but should be >= 1360.\n", |
136 | | - "INPUT SETTINGS --> ENCUT: is 450.0, but should be >= 680.\n", |
137 | | - "False\n", |
138 | | - "True\n" |
139 | | - ] |
140 | | - } |
141 | | - ], |
142 | 142 | "source": [ |
143 | | - "\"\"\"\n", |
144 | | - "An example of an MP incompatible r2SCAN static calculation for GaAs is located in the `MP_non_compliant` directory.\n", |
| 143 | + "An example of an MP incompatible r<sup>2</sup>SCAN static calculation for GaAs is located in the `MP_non_compliant` directory.\n", |
145 | 144 | "\n", |
146 | 145 | "This calculation uses a lower ENCUT, ENAUG, and k-point density (larger KSPACING) than is permitted by the appropriate input set, `pymatgen.io.vasp.sets.MPScanStaticSet`.\n", |
147 | | - "These reasons are reflected transparently in the output reasons.\n", |
148 | | - "\"\"\"\n", |
149 | | - "mp_non_compliant_doc = check_calc(\"MP_non_compliant\")\n", |
150 | | - "print(mp_non_compliant_doc.valid)\n", |
151 | | - "for reason in mp_non_compliant_doc.reasons:\n", |
152 | | - " print(reason)\n", |
153 | | - "\n", |
154 | | - "non_compliant_task_doc = TaskDoc(\n", |
155 | | - " **loadfn(os.path.join(\"MP_non_compliant\",\"MP_incompatible_GaAs_r2SCAN_static.json.gz\"))\n", |
156 | | - ")\n", |
157 | | - "mp_non_compliant_doc_from_taskdoc = ValidationDoc.from_task_doc(non_compliant_task_doc)\n", |
158 | | - "print(mp_non_compliant_doc_from_taskdoc.valid)\n", |
159 | | - "print(mp_non_compliant_doc_from_taskdoc.reasons == mp_non_compliant_doc_from_taskdoc.reasons)" |
| 146 | + "These reasons are reflected transparently in the output reasons." |
160 | 147 | ] |
161 | 148 | }, |
162 | 149 | { |
163 | 150 | "cell_type": "code", |
164 | 151 | "execution_count": null, |
165 | | - "id": "128e49d1", |
| 152 | + "id": "8", |
166 | 153 | "metadata": {}, |
167 | 154 | "outputs": [], |
168 | | - "source": [] |
| 155 | + "source": [ |
| 156 | + "mp_non_compliant_doc = check_calc(\"MP_non_compliant\")\n", |
| 157 | + "print(mp_non_compliant_doc.is_valid)\n", |
| 158 | + "for reason in mp_non_compliant_doc.reasons:\n", |
| 159 | + " print(reason)" |
| 160 | + ] |
169 | 161 | } |
170 | 162 | ], |
171 | 163 | "metadata": { |
172 | | - "kernelspec": { |
173 | | - "display_name": "Python 3 (ipykernel)", |
174 | | - "language": "python", |
175 | | - "name": "python3" |
176 | | - }, |
177 | 164 | "language_info": { |
178 | 165 | "codemirror_mode": { |
179 | 166 | "name": "ipython", |
|
0 commit comments