|
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",
|
|
73 | 90 | ]
|
74 | 91 | },
|
75 | 92 | {
|
76 |
| - "cell_type": "code", |
77 |
| - "execution_count": 3, |
78 |
| - "id": "0f660f54-ca8a-466c-b382-2f0fac46d8bf", |
| 93 | + "cell_type": "markdown", |
| 94 | + "id": "3", |
79 | 95 | "metadata": {},
|
80 |
| - "outputs": [ |
81 |
| - { |
82 |
| - "name": "stdout", |
83 |
| - "output_type": "stream", |
84 |
| - "text": [ |
85 |
| - "True\n" |
86 |
| - ] |
87 |
| - } |
88 |
| - ], |
89 | 96 | "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 |
| - "mp_compliant_doc = check_calc(\"MP_compliant\")\n", |
94 |
| - "print(mp_compliant_doc.valid)" |
| 97 | + "An example of an MP-compatible r2SCAN static calculation for GaAs is located in the `MP_compliant` directory. 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." |
95 | 98 | ]
|
96 | 99 | },
|
97 | 100 | {
|
98 | 101 | "cell_type": "code",
|
99 |
| - "execution_count": 4, |
100 |
| - "id": "25b85de2", |
| 102 | + "execution_count": null, |
| 103 | + "id": "4", |
101 | 104 | "metadata": {},
|
102 |
| - "outputs": [ |
103 |
| - { |
104 |
| - "name": "stdout", |
105 |
| - "output_type": "stream", |
106 |
| - "text": [ |
107 |
| - "True\n" |
108 |
| - ] |
109 |
| - } |
110 |
| - ], |
| 105 | + "outputs": [], |
111 | 106 | "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", |
116 |
| - "compliant_task_doc = TaskDoc(\n", |
117 |
| - " **loadfn(os.path.join(\"MP_compliant\",\"MP_compatible_GaAs_r2SCAN_static.json.gz\"))\n", |
118 |
| - ")\n", |
119 |
| - "mp_compliant_doc = ValidationDoc.from_task_doc(compliant_task_doc)\n", |
| 107 | + "mp_compliant_doc = check_calc(\"MP_compliant\")\n", |
120 | 108 | "print(mp_compliant_doc.valid)"
|
121 | 109 | ]
|
122 | 110 | },
|
123 | 111 | {
|
124 |
| - "cell_type": "code", |
125 |
| - "execution_count": 5, |
126 |
| - "id": "c919fedd-38ef-4cf7-a2ed-54544eec8d82", |
| 112 | + "cell_type": "markdown", |
| 113 | + "id": "5", |
127 | 114 | "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 | 115 | "source": [
|
143 |
| - "\"\"\"\n", |
144 |
| - "An example of an MP incompatible r2SCAN static calculation for GaAs is located in the `MP_non_compliant` directory.\n", |
| 116 | + "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 | 117 | "\n",
|
146 | 118 | "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)" |
| 119 | + "These reasons are reflected transparently in the output reasons." |
160 | 120 | ]
|
161 | 121 | },
|
162 | 122 | {
|
163 | 123 | "cell_type": "code",
|
164 | 124 | "execution_count": null,
|
165 |
| - "id": "128e49d1", |
| 125 | + "id": "6", |
166 | 126 | "metadata": {},
|
167 | 127 | "outputs": [],
|
168 |
| - "source": [] |
| 128 | + "source": [ |
| 129 | + "mp_non_compliant_doc = check_calc(\"MP_non_compliant\")\n", |
| 130 | + "print(mp_non_compliant_doc.valid)\n", |
| 131 | + "for reason in mp_non_compliant_doc.reasons:\n", |
| 132 | + " print(reason)" |
| 133 | + ] |
169 | 134 | }
|
170 | 135 | ],
|
171 | 136 | "metadata": {
|
172 |
| - "kernelspec": { |
173 |
| - "display_name": "Python 3 (ipykernel)", |
174 |
| - "language": "python", |
175 |
| - "name": "python3" |
176 |
| - }, |
177 | 137 | "language_info": {
|
178 | 138 | "codemirror_mode": {
|
179 | 139 | "name": "ipython",
|
|
0 commit comments