Spaces:
Running
Running
add notebooks
Browse files
mlip_arena/tasks/diatomics/alignn/run.ipynb
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": null,
|
6 |
+
"id": "3200850a-b8fb-4f50-9815-16ae8da0f942",
|
7 |
+
"metadata": {
|
8 |
+
"tags": []
|
9 |
+
},
|
10 |
+
"outputs": [],
|
11 |
+
"source": [
|
12 |
+
"from ase import Atoms, Atom\n",
|
13 |
+
"from ase.io import read, write\n",
|
14 |
+
"from ase.data import chemical_symbols, covalent_radii, vdw_alvarez\n",
|
15 |
+
"from ase.parallel import paropen as open\n",
|
16 |
+
"\n",
|
17 |
+
"from pathlib import Path\n",
|
18 |
+
"import os\n",
|
19 |
+
"import numpy as np\n",
|
20 |
+
"from pymatgen.core import Element\n",
|
21 |
+
"from tqdm.auto import tqdm\n",
|
22 |
+
"import pandas as pd\n",
|
23 |
+
"\n",
|
24 |
+
"\n",
|
25 |
+
"from alignn.ff.ff import AlignnAtomwiseCalculator,default_path\n",
|
26 |
+
"\n",
|
27 |
+
"\n",
|
28 |
+
"model_path = default_path()\n",
|
29 |
+
"calc = AlignnAtomwiseCalculator(path=model_path, device='cuda')\n",
|
30 |
+
"\n",
|
31 |
+
"model_name = 'ALIGNN'\n"
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"cell_type": "code",
|
36 |
+
"execution_count": null,
|
37 |
+
"id": "90887faa-1601-4c4c-9c44-d16731471d7f",
|
38 |
+
"metadata": {
|
39 |
+
"scrolled": true,
|
40 |
+
"tags": []
|
41 |
+
},
|
42 |
+
"outputs": [],
|
43 |
+
"source": [
|
44 |
+
"\n",
|
45 |
+
"\n",
|
46 |
+
"for symbol in tqdm(chemical_symbols):\n",
|
47 |
+
" \n",
|
48 |
+
" s = set([symbol])\n",
|
49 |
+
" \n",
|
50 |
+
" if 'X' in s:\n",
|
51 |
+
" continue\n",
|
52 |
+
" \n",
|
53 |
+
" try:\n",
|
54 |
+
" atom = Atom(symbol)\n",
|
55 |
+
" rmin = covalent_radii[atom.number] * 0.95\n",
|
56 |
+
" rvdw = vdw_alvarez.vdw_radii[atom.number] if atom.number < len(vdw_alvarez.vdw_radii) else np.nan \n",
|
57 |
+
" rmax = 3.1 * rvdw if not np.isnan(rvdw) else 6\n",
|
58 |
+
" rstep = 0.01 #if rmin < 1 else 0.4\n",
|
59 |
+
"\n",
|
60 |
+
" a = 2 * rmax\n",
|
61 |
+
"\n",
|
62 |
+
" npts = int((rmax - rmin)/rstep)\n",
|
63 |
+
"\n",
|
64 |
+
" rs = np.linspace(rmin, rmax, npts)\n",
|
65 |
+
" e = np.zeros_like(rs)\n",
|
66 |
+
"\n",
|
67 |
+
" da = symbol + symbol\n",
|
68 |
+
"\n",
|
69 |
+
" out_dir = Path(str(da))\n",
|
70 |
+
"\n",
|
71 |
+
" os.makedirs(out_dir, exist_ok=True)\n",
|
72 |
+
"\n",
|
73 |
+
" skip = 0\n",
|
74 |
+
" \n",
|
75 |
+
" element = Element(symbol)\n",
|
76 |
+
" \n",
|
77 |
+
" try:\n",
|
78 |
+
" m = element.valence[1]\n",
|
79 |
+
" if element.valence == (0, 2):\n",
|
80 |
+
" m = 0\n",
|
81 |
+
" except:\n",
|
82 |
+
" m = 0\n",
|
83 |
+
" \n",
|
84 |
+
" \n",
|
85 |
+
" r = rs[0]\n",
|
86 |
+
" \n",
|
87 |
+
" positions = [\n",
|
88 |
+
" [a/2-r/2, a/2, a/2],\n",
|
89 |
+
" [a/2+r/2, a/2, a/2],\n",
|
90 |
+
" ]\n",
|
91 |
+
" \n",
|
92 |
+
" traj_fpath = out_dir / f\"{model_name}.extxyz\"\n",
|
93 |
+
"\n",
|
94 |
+
" if traj_fpath.exists():\n",
|
95 |
+
" traj = read(traj_fpath, index=\":\")\n",
|
96 |
+
" skip = len(traj)\n",
|
97 |
+
" atoms = traj[-1]\n",
|
98 |
+
" else:\n",
|
99 |
+
" # Create the unit cell with two atoms\n",
|
100 |
+
" atoms = Atoms(\n",
|
101 |
+
" da, \n",
|
102 |
+
" positions=positions,\n",
|
103 |
+
" # magmoms=magmoms,\n",
|
104 |
+
" cell=[a, a+0.001, a+0.002], \n",
|
105 |
+
" pbc=True\n",
|
106 |
+
" )\n",
|
107 |
+
" \n",
|
108 |
+
" print(atoms)\n",
|
109 |
+
"\n",
|
110 |
+
" calc = calc\n",
|
111 |
+
"\n",
|
112 |
+
" atoms.calc = calc\n",
|
113 |
+
"\n",
|
114 |
+
" for i, r in enumerate(tqdm(rs)):\n",
|
115 |
+
"\n",
|
116 |
+
" if i < skip:\n",
|
117 |
+
" continue\n",
|
118 |
+
"\n",
|
119 |
+
" positions = [\n",
|
120 |
+
" [a/2-r/2, a/2, a/2],\n",
|
121 |
+
" [a/2+r/2, a/2, a/2],\n",
|
122 |
+
" ]\n",
|
123 |
+
" \n",
|
124 |
+
" # atoms.set_initial_magnetic_moments(magmoms)\n",
|
125 |
+
" \n",
|
126 |
+
" atoms.set_positions(positions)\n",
|
127 |
+
"\n",
|
128 |
+
" e[i] = atoms.get_potential_energy()\n",
|
129 |
+
" \n",
|
130 |
+
" atoms.calc.results.update({\n",
|
131 |
+
" \"forces\": atoms.get_forces()\n",
|
132 |
+
" })\n",
|
133 |
+
"\n",
|
134 |
+
" write(traj_fpath, atoms, append=\"a\")\n",
|
135 |
+
" except Exception as e:\n",
|
136 |
+
" print(e)\n"
|
137 |
+
]
|
138 |
+
},
|
139 |
+
{
|
140 |
+
"cell_type": "code",
|
141 |
+
"execution_count": null,
|
142 |
+
"id": "a0ac2c09-370b-4fdd-bf74-ea5c4ade0215",
|
143 |
+
"metadata": {},
|
144 |
+
"outputs": [],
|
145 |
+
"source": [
|
146 |
+
"\n",
|
147 |
+
"\n",
|
148 |
+
"df = pd.DataFrame(columns=['name', 'method', 'R', 'E', 'F', 'S^2'])\n",
|
149 |
+
"\n",
|
150 |
+
"for symbol in tqdm(chemical_symbols):\n",
|
151 |
+
" \n",
|
152 |
+
" da = symbol + symbol\n",
|
153 |
+
" \n",
|
154 |
+
" out_dir = Path(da)\n",
|
155 |
+
" \n",
|
156 |
+
" traj_fpath = out_dir / f\"{model_name}.extxyz\"\n",
|
157 |
+
"\n",
|
158 |
+
"\n",
|
159 |
+
" if traj_fpath.exists():\n",
|
160 |
+
" traj = read(traj_fpath, index=\":\")\n",
|
161 |
+
" else:\n",
|
162 |
+
" continue\n",
|
163 |
+
" \n",
|
164 |
+
" Rs, Es, Fs, S2s = [], [], [], []\n",
|
165 |
+
" for atoms in traj:\n",
|
166 |
+
" \n",
|
167 |
+
" vec = atoms.positions[1] - atoms.positions[0]\n",
|
168 |
+
" r = np.linalg.norm(vec)\n",
|
169 |
+
" e = atoms.get_potential_energy()\n",
|
170 |
+
" f = np.inner(vec/r, atoms.get_forces()[1])\n",
|
171 |
+
" # s2 = np.mean(np.power(atoms.get_magnetic_moments(), 2))\n",
|
172 |
+
" \n",
|
173 |
+
" Rs.append(r)\n",
|
174 |
+
" Es.append(e)\n",
|
175 |
+
" Fs.append(f)\n",
|
176 |
+
" # S2s.append(s2)\n",
|
177 |
+
" \n",
|
178 |
+
" data = {\n",
|
179 |
+
" 'name': da,\n",
|
180 |
+
" 'method': 'ALIGNN',\n",
|
181 |
+
" 'R': Rs,\n",
|
182 |
+
" 'E': Es,\n",
|
183 |
+
" 'F': Fs,\n",
|
184 |
+
" 'S^2': S2s\n",
|
185 |
+
" }\n",
|
186 |
+
"\n",
|
187 |
+
" df = pd.concat([df, pd.DataFrame([data])], ignore_index=True)\n",
|
188 |
+
"\n",
|
189 |
+
"json_fpath = 'homonuclear-diatomics.json'\n",
|
190 |
+
"\n",
|
191 |
+
"df.to_json(json_fpath, orient='records') "
|
192 |
+
]
|
193 |
+
},
|
194 |
+
{
|
195 |
+
"cell_type": "code",
|
196 |
+
"execution_count": null,
|
197 |
+
"id": "e0dd4367-3dca-440f-a7a9-7fdd84183f2c",
|
198 |
+
"metadata": {
|
199 |
+
"tags": []
|
200 |
+
},
|
201 |
+
"outputs": [],
|
202 |
+
"source": [
|
203 |
+
"df"
|
204 |
+
]
|
205 |
+
},
|
206 |
+
{
|
207 |
+
"cell_type": "code",
|
208 |
+
"execution_count": null,
|
209 |
+
"id": "4e6ae884-89f3-43f2-8fd9-19bf00c91566",
|
210 |
+
"metadata": {},
|
211 |
+
"outputs": [],
|
212 |
+
"source": []
|
213 |
+
}
|
214 |
+
],
|
215 |
+
"metadata": {
|
216 |
+
"kernelspec": {
|
217 |
+
"display_name": "mlip-arena",
|
218 |
+
"language": "python",
|
219 |
+
"name": "mlip-arena"
|
220 |
+
},
|
221 |
+
"language_info": {
|
222 |
+
"codemirror_mode": {
|
223 |
+
"name": "ipython",
|
224 |
+
"version": 3
|
225 |
+
},
|
226 |
+
"file_extension": ".py",
|
227 |
+
"mimetype": "text/x-python",
|
228 |
+
"name": "python",
|
229 |
+
"nbconvert_exporter": "python",
|
230 |
+
"pygments_lexer": "ipython3",
|
231 |
+
"version": "3.11.8"
|
232 |
+
},
|
233 |
+
"widgets": {
|
234 |
+
"application/vnd.jupyter.widget-state+json": {
|
235 |
+
"state": {},
|
236 |
+
"version_major": 2,
|
237 |
+
"version_minor": 0
|
238 |
+
}
|
239 |
+
}
|
240 |
+
},
|
241 |
+
"nbformat": 4,
|
242 |
+
"nbformat_minor": 5
|
243 |
+
}
|
mlip_arena/tasks/diatomics/gpaw/run.ipynb
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": null,
|
6 |
+
"id": "08ee4c09-7fb5-4ce1-a7a3-5c5c52a6d4d5",
|
7 |
+
"metadata": {
|
8 |
+
"tags": []
|
9 |
+
},
|
10 |
+
"outputs": [],
|
11 |
+
"source": [
|
12 |
+
"from ase import Atoms, Atom\n",
|
13 |
+
"from ase.io import read, write\n",
|
14 |
+
"from ase.data import chemical_symbols, covalent_radii, vdw_alvarez\n",
|
15 |
+
"from ase.parallel import paropen as open\n",
|
16 |
+
"from gpaw import GPAW, PW, FermiDirac, LCAO\n",
|
17 |
+
"from gpaw import Davidson\n",
|
18 |
+
"from gpaw import Mixer, MixerSum, MixerDif\n",
|
19 |
+
"from gpaw.directmin.etdm_lcao import LCAOETDM\n",
|
20 |
+
"from gpaw.cdft.cdft import CDFT\n",
|
21 |
+
"from pathlib import Path\n",
|
22 |
+
"import os\n",
|
23 |
+
"import numpy as np\n",
|
24 |
+
"from pymatgen.core import Element\n",
|
25 |
+
"from tqdm.auto import tqdm\n",
|
26 |
+
"import pandas as pd"
|
27 |
+
]
|
28 |
+
},
|
29 |
+
{
|
30 |
+
"cell_type": "code",
|
31 |
+
"execution_count": null,
|
32 |
+
"id": "90887faa-1601-4c4c-9c44-d16731471d7f",
|
33 |
+
"metadata": {
|
34 |
+
"tags": []
|
35 |
+
},
|
36 |
+
"outputs": [],
|
37 |
+
"source": [
|
38 |
+
"\n",
|
39 |
+
"magnetism = 'NM'\n",
|
40 |
+
"\n",
|
41 |
+
"for symbol in tqdm(chemical_symbols):\n",
|
42 |
+
" \n",
|
43 |
+
" s = set([symbol])\n",
|
44 |
+
" \n",
|
45 |
+
" if 'X' in s:\n",
|
46 |
+
" continue\n",
|
47 |
+
" \n",
|
48 |
+
" try:\n",
|
49 |
+
" atom = Atom(symbol)\n",
|
50 |
+
" rmin = covalent_radii[atom.number] * 2 * 0.6\n",
|
51 |
+
" rvdw = vdw_alvarez.vdw_radii[atom.number] if atom.number < len(vdw_alvarez.vdw_radii) else np.nan \n",
|
52 |
+
" rmax = 3.1 * rvdw if not np.isnan(rvdw) else 6\n",
|
53 |
+
" rstep = 0.2 #if rmin < 1 else 0.4\n",
|
54 |
+
"\n",
|
55 |
+
" a = 2 * rmax\n",
|
56 |
+
"\n",
|
57 |
+
" npts = int((rmax - rmin)/rstep)\n",
|
58 |
+
"\n",
|
59 |
+
" rs = np.linspace(rmin, rmax, npts)\n",
|
60 |
+
" e = np.zeros_like(rs)\n",
|
61 |
+
"\n",
|
62 |
+
" da = symbol + symbol\n",
|
63 |
+
"\n",
|
64 |
+
" out_dir = Path(str(da + f\"_{magnetism}\"))\n",
|
65 |
+
"\n",
|
66 |
+
" os.makedirs(out_dir, exist_ok=True)\n",
|
67 |
+
"\n",
|
68 |
+
" skip = 0\n",
|
69 |
+
" \n",
|
70 |
+
" element = Element(symbol)\n",
|
71 |
+
" \n",
|
72 |
+
" try:\n",
|
73 |
+
" m = element.valence[1]\n",
|
74 |
+
" if element.valence == (0, 2):\n",
|
75 |
+
" m = 0\n",
|
76 |
+
" except:\n",
|
77 |
+
" m = 0\n",
|
78 |
+
" \n",
|
79 |
+
" \n",
|
80 |
+
" r = rs[0]\n",
|
81 |
+
" \n",
|
82 |
+
" positions = [\n",
|
83 |
+
" [a/2-r/2, a/2, a/2],\n",
|
84 |
+
" [a/2+r/2, a/2, a/2],\n",
|
85 |
+
" ]\n",
|
86 |
+
" \n",
|
87 |
+
" if magnetism == 'FM':\n",
|
88 |
+
" if m == 0:\n",
|
89 |
+
" continue\n",
|
90 |
+
" magmoms = [m, m]\n",
|
91 |
+
" elif magnetism == 'AFM':\n",
|
92 |
+
" if m == 0:\n",
|
93 |
+
" continue\n",
|
94 |
+
" magmoms = [m, -m]\n",
|
95 |
+
" elif magnetism == 'NM':\n",
|
96 |
+
" magmoms = [0, 0]\n",
|
97 |
+
" \n",
|
98 |
+
" traj_fpath = out_dir / \"traj.extxyz\"\n",
|
99 |
+
"\n",
|
100 |
+
" if traj_fpath.exists():\n",
|
101 |
+
" traj = read(traj_fpath, index=\":\")\n",
|
102 |
+
" skip = len(traj)\n",
|
103 |
+
" atoms = traj[-1]\n",
|
104 |
+
" else:\n",
|
105 |
+
" # Create the unit cell with two atoms\n",
|
106 |
+
" atoms = Atoms(\n",
|
107 |
+
" da, \n",
|
108 |
+
" positions=positions,\n",
|
109 |
+
" magmoms=magmoms,\n",
|
110 |
+
" cell=[a, a+0.001, a+0.002], \n",
|
111 |
+
" pbc=True\n",
|
112 |
+
" )\n",
|
113 |
+
" \n",
|
114 |
+
" print(atoms)\n",
|
115 |
+
" \n",
|
116 |
+
" restart_fpath = out_dir / 'restart.gpw'\n",
|
117 |
+
"\n",
|
118 |
+
" calc = GPAW(\n",
|
119 |
+
" mode=PW(1000),\n",
|
120 |
+
" xc='PBE',\n",
|
121 |
+
" spinpol=True,\n",
|
122 |
+
" # basis='dzp'\n",
|
123 |
+
" basis='szp(dzp)',\n",
|
124 |
+
" # h=0.25,\n",
|
125 |
+
" # nbands=0 if element.is_noble_gas else '110%',\n",
|
126 |
+
" hund=False,\n",
|
127 |
+
" mixer=MixerDif(0.01, 1, 1) if element.is_transition_metal else MixerDif(0.25, 3, 10),\n",
|
128 |
+
" eigensolver='cg', #'rmm-diis', #Davidson(3), # This solver can parallelize over bands Davidson(3), #\n",
|
129 |
+
" occupations=FermiDirac(0.0, fixmagmom=False), # if not element.is_metal else FermiDirac(0.2, fixmagmom=False),\n",
|
130 |
+
" # eigensolver=LCAOETDM(),\n",
|
131 |
+
" # # searchdir_algo={'name': 'l-bfgs-p', 'memory': 10}),\n",
|
132 |
+
" # occupations={'name': 'fixed-uniform'},\n",
|
133 |
+
" # mixer={'backend': 'no-mixing'},\n",
|
134 |
+
" # nbands='nao',\n",
|
135 |
+
" symmetry={'point_group': False},\n",
|
136 |
+
" txt=out_dir / 'out.txt',\n",
|
137 |
+
" convergence={\n",
|
138 |
+
" 'eigenstates': 1e-5,\n",
|
139 |
+
" 'density': 5e-3,\n",
|
140 |
+
" 'energy': 5e-4,\n",
|
141 |
+
" # 'bands': 4\n",
|
142 |
+
" },\n",
|
143 |
+
" # {'energy': 0.0005, # eV / electron\n",
|
144 |
+
" # 'density': 1.0e-4, # electrons / electron\n",
|
145 |
+
" # 'eigenstates': 4.0e-8, # eV^2 / electron\n",
|
146 |
+
" # 'bands': 'occupied'}\n",
|
147 |
+
" )\n",
|
148 |
+
" # calc.attach(calc.write, 10, restart_fpath, mode='all')\n",
|
149 |
+
"\n",
|
150 |
+
" atoms.calc = calc\n",
|
151 |
+
" \n",
|
152 |
+
" # cdft = CDFT(calc=calc, atoms=atoms, spinspin_regions= \n",
|
153 |
+
" # atoms.calc = cdft\n",
|
154 |
+
"\n",
|
155 |
+
" for i, r in enumerate(tqdm(np.flip(rs))):\n",
|
156 |
+
"\n",
|
157 |
+
" if i < skip:\n",
|
158 |
+
" continue\n",
|
159 |
+
"\n",
|
160 |
+
" positions = [\n",
|
161 |
+
" [a/2-r/2, a/2, a/2],\n",
|
162 |
+
" [a/2+r/2, a/2, a/2],\n",
|
163 |
+
" ]\n",
|
164 |
+
" \n",
|
165 |
+
" # if i > 0: \n",
|
166 |
+
" # magmoms = atoms.get_magnetic_moments()\n",
|
167 |
+
" # m = min(abs(magmoms[0])*1.2, m)\n",
|
168 |
+
" # magmoms = magmoms*m/np.abs(magmoms)\n",
|
169 |
+
" \n",
|
170 |
+
" atoms.set_initial_magnetic_moments(magmoms)\n",
|
171 |
+
" \n",
|
172 |
+
" atoms.set_positions(positions)\n",
|
173 |
+
"\n",
|
174 |
+
" e[i] = atoms.get_potential_energy()\n",
|
175 |
+
" \n",
|
176 |
+
" atoms.calc.results.update({\n",
|
177 |
+
" \"forces\": atoms.get_forces()\n",
|
178 |
+
" })\n",
|
179 |
+
"\n",
|
180 |
+
" write(traj_fpath, atoms, append=\"a\")\n",
|
181 |
+
" except Exception as e:\n",
|
182 |
+
" print(e)\n"
|
183 |
+
]
|
184 |
+
},
|
185 |
+
{
|
186 |
+
"cell_type": "code",
|
187 |
+
"execution_count": null,
|
188 |
+
"id": "a0ac2c09-370b-4fdd-bf74-ea5c4ade0215",
|
189 |
+
"metadata": {},
|
190 |
+
"outputs": [],
|
191 |
+
"source": [
|
192 |
+
"\n",
|
193 |
+
"\n",
|
194 |
+
"df = pd.DataFrame(columns=['name', 'method', 'R', 'E', 'F', 'S^2'])\n",
|
195 |
+
"\n",
|
196 |
+
"\n",
|
197 |
+
"\n",
|
198 |
+
"for symbol in tqdm(chemical_symbols):\n",
|
199 |
+
" \n",
|
200 |
+
" for magnetism in ['AFM', 'FM', 'NM']:\n",
|
201 |
+
" \n",
|
202 |
+
" da = symbol + symbol\n",
|
203 |
+
"\n",
|
204 |
+
" # out_dir = Path(da)\n",
|
205 |
+
" out_dir = Path(str(da + f\"_{magnetism}\"))\n",
|
206 |
+
"\n",
|
207 |
+
" traj_fpath = out_dir / \"traj.extxyz\"\n",
|
208 |
+
"\n",
|
209 |
+
" if traj_fpath.exists():\n",
|
210 |
+
" traj = read(traj_fpath, index=\":\")\n",
|
211 |
+
" else:\n",
|
212 |
+
" continue\n",
|
213 |
+
"\n",
|
214 |
+
" Rs, Es, Fs, S2s = [], [], [], []\n",
|
215 |
+
" for atoms in traj:\n",
|
216 |
+
"\n",
|
217 |
+
" vec = atoms.positions[1] - atoms.positions[0]\n",
|
218 |
+
" r = np.linalg.norm(vec)\n",
|
219 |
+
" e = atoms.get_potential_energy()\n",
|
220 |
+
" # f = np.inner(vec/r, atoms.get_forces()[1])\n",
|
221 |
+
" # s2 = np.mean(np.power(atoms.get_magnetic_moments(), 2))\n",
|
222 |
+
"\n",
|
223 |
+
" Rs.append(r)\n",
|
224 |
+
" Es.append(e)\n",
|
225 |
+
" # Fs.append(f)\n",
|
226 |
+
" # S2s.append(s2)\n",
|
227 |
+
"\n",
|
228 |
+
" data = {\n",
|
229 |
+
" 'name': da,\n",
|
230 |
+
" 'method': f'GGA-PBE (GPAW): {magnetism}',\n",
|
231 |
+
" 'R': Rs,\n",
|
232 |
+
" 'E': Es,\n",
|
233 |
+
" 'F': Fs,\n",
|
234 |
+
" 'S^2': S2s\n",
|
235 |
+
" }\n",
|
236 |
+
"\n",
|
237 |
+
" df = pd.concat([df, pd.DataFrame([data])], ignore_index=True)\n",
|
238 |
+
"\n",
|
239 |
+
"json_fpath = 'homonuclear-diatomics.json'\n",
|
240 |
+
"\n",
|
241 |
+
"df.to_json(json_fpath, orient='records') "
|
242 |
+
]
|
243 |
+
},
|
244 |
+
{
|
245 |
+
"cell_type": "code",
|
246 |
+
"execution_count": null,
|
247 |
+
"id": "5d4a7312-a619-411f-9c6f-36c40cd47a34",
|
248 |
+
"metadata": {},
|
249 |
+
"outputs": [],
|
250 |
+
"source": []
|
251 |
+
}
|
252 |
+
],
|
253 |
+
"metadata": {
|
254 |
+
"kernelspec": {
|
255 |
+
"display_name": "mlip-arena",
|
256 |
+
"language": "python",
|
257 |
+
"name": "mlip-arena"
|
258 |
+
},
|
259 |
+
"language_info": {
|
260 |
+
"codemirror_mode": {
|
261 |
+
"name": "ipython",
|
262 |
+
"version": 3
|
263 |
+
},
|
264 |
+
"file_extension": ".py",
|
265 |
+
"mimetype": "text/x-python",
|
266 |
+
"name": "python",
|
267 |
+
"nbconvert_exporter": "python",
|
268 |
+
"pygments_lexer": "ipython3",
|
269 |
+
"version": "3.11.8"
|
270 |
+
},
|
271 |
+
"widgets": {
|
272 |
+
"application/vnd.jupyter.widget-state+json": {
|
273 |
+
"state": {},
|
274 |
+
"version_major": 2,
|
275 |
+
"version_minor": 0
|
276 |
+
}
|
277 |
+
}
|
278 |
+
},
|
279 |
+
"nbformat": 4,
|
280 |
+
"nbformat_minor": 5
|
281 |
+
}
|
mlip_arena/tasks/diatomics/vasp/run.ipynb
ADDED
@@ -0,0 +1,509 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": null,
|
6 |
+
"metadata": {
|
7 |
+
"tags": []
|
8 |
+
},
|
9 |
+
"outputs": [],
|
10 |
+
"source": [
|
11 |
+
"from datetime import timedelta\n",
|
12 |
+
"from typing import Union\n",
|
13 |
+
"import os\n",
|
14 |
+
"from pathlib import Path\n",
|
15 |
+
"from itertools import combinations, combinations_with_replacement\n",
|
16 |
+
"import psutil\n",
|
17 |
+
"import subprocess\n",
|
18 |
+
"\n",
|
19 |
+
"import numpy as np\n",
|
20 |
+
"import pandas as pd\n",
|
21 |
+
"import torch\n",
|
22 |
+
"from ase import Atoms, Atom\n",
|
23 |
+
"from ase.calculators.calculator import Calculator\n",
|
24 |
+
"from ase.calculators.singlepoint import SinglePointCalculator\n",
|
25 |
+
"from ase.calculators.vasp import Vasp\n",
|
26 |
+
"from ase.data import chemical_symbols, covalent_radii, vdw_alvarez\n",
|
27 |
+
"from ase.io import read, write\n",
|
28 |
+
"from dask.distributed import Client\n",
|
29 |
+
"from dask_jobqueue import SLURMCluster\n",
|
30 |
+
"from prefect import flow, task\n",
|
31 |
+
"from prefect.tasks import task_input_hash\n",
|
32 |
+
"from prefect_dask import DaskTaskRunner\n",
|
33 |
+
"\n",
|
34 |
+
"from pymatgen.core import Element\n",
|
35 |
+
"from pymatgen.io.ase import AseAtomsAdaptor\n",
|
36 |
+
"from pymatgen.io.vasp.inputs import Kpoints\n",
|
37 |
+
"from pymatgen.command_line.chargemol_caller import ChargemolAnalysis\n",
|
38 |
+
"\n",
|
39 |
+
"from mlip_arena.models import MLIPCalculator\n",
|
40 |
+
"from mlip_arena.models.utils import EXTMLIPEnum, MLIPMap, external_ase_calculator\n",
|
41 |
+
"from jobflow import run_locally\n",
|
42 |
+
"\n",
|
43 |
+
"from atomate2.vasp.jobs.mp import MPGGAStaticMaker\n",
|
44 |
+
"from atomate2.vasp.sets.mp import MPGGAStaticSetGenerator"
|
45 |
+
]
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"cell_type": "code",
|
49 |
+
"execution_count": null,
|
50 |
+
"metadata": {
|
51 |
+
"scrolled": true,
|
52 |
+
"tags": []
|
53 |
+
},
|
54 |
+
"outputs": [],
|
55 |
+
"source": [
|
56 |
+
"\n",
|
57 |
+
"nodes_per_alloc = 1\n",
|
58 |
+
"cpus_per_task = 16\n",
|
59 |
+
"gpus_per_node = 1\n",
|
60 |
+
"# tasks_per_node = int(128/4)\n",
|
61 |
+
"ntasks = 1\n",
|
62 |
+
"\n",
|
63 |
+
"\n",
|
64 |
+
"cluster_kwargs = dict(\n",
|
65 |
+
" cores=1,\n",
|
66 |
+
" memory=\"64 GB\",\n",
|
67 |
+
" shebang=\"#!/bin/bash\",\n",
|
68 |
+
" account=\"m3828\",\n",
|
69 |
+
" walltime=\"01:00:00\",\n",
|
70 |
+
" # processes=16,\n",
|
71 |
+
" # nanny=True,\n",
|
72 |
+
" job_mem=\"0\",\n",
|
73 |
+
" job_script_prologue=[\n",
|
74 |
+
" \"source ~/.bashrc\",\n",
|
75 |
+
" \"module load python\",\n",
|
76 |
+
" \"source activate /pscratch/sd/c/cyrisinstance.conda/mlip-arena\",\n",
|
77 |
+
" \"module load vasp/6.4.1-gpu\",\n",
|
78 |
+
" \n",
|
79 |
+
" \"export DDEC6_ATOMIC_DENSITIES_DIR='/global/homes/c/cyrusyc/chargemol/atomic_densities/'\",\n",
|
80 |
+
" f\"export OMP_NUM_THREADS={gpus_per_node}\",\n",
|
81 |
+
" \"export OMP_PLACES=threads\",\n",
|
82 |
+
" \"export OMP_PROC_BIND=spread\",\n",
|
83 |
+
" f\"export ASE_VASP_COMMAND='srun -n {ntasks} -c {4*gpus_per_node} --cpu-bind=cores --gpus-per-node {gpus_per_node} vasp_ncl'\"\n",
|
84 |
+
" # f\"export ASE_VASP_COMMAND='srun -N {nodes_per_alloc} --ntasks-per-node={tasks_per_node} -c {cpus_per_task} --cpu-bind=cores vasp_std'\"\n",
|
85 |
+
" # \"export ATOMATE2_CONFIG_FILE='/global/homes/c/cyrusyc/atomate2/config/atomate2-prefect-cpu-node.yaml'\"\n",
|
86 |
+
" ],\n",
|
87 |
+
" job_directives_skip=[\"-n\", \"--cpus-per-task\", \"-J\"],\n",
|
88 |
+
" job_extra_directives=[\n",
|
89 |
+
" \"-J diatomics\",\n",
|
90 |
+
" \"-q regular\",\n",
|
91 |
+
" f\"-N {nodes_per_alloc}\",\n",
|
92 |
+
" \"-C gpu\",\n",
|
93 |
+
" # \"-n 1\",\n",
|
94 |
+
" # \"-c 16\",\n",
|
95 |
+
" # \"--gpus-per-task=1\",\n",
|
96 |
+
" # \"--threads-per-task=1\",\n",
|
97 |
+
" # \"--gpu-bind=single:1\",\n",
|
98 |
+
" # \"--comment=00:20:00\",\n",
|
99 |
+
" # \"--time-min=00:05:00\",\n",
|
100 |
+
" # \"--signal=B:USR1@60\",\n",
|
101 |
+
" # \"--requeue\",\n",
|
102 |
+
" # \"--open-mode=append\",\n",
|
103 |
+
" # \"--mail-type=end,requeue\",\n",
|
104 |
+
" # \"--mail-user=cyrusyc@lbl.gov\",\n",
|
105 |
+
" ],\n",
|
106 |
+
" # python=\"srun python\",\n",
|
107 |
+
" death_timeout=86400, #float('inf')\n",
|
108 |
+
")\n",
|
109 |
+
"\n",
|
110 |
+
"\n",
|
111 |
+
"cluster = SLURMCluster(**cluster_kwargs)\n",
|
112 |
+
"print(cluster.job_script())\n",
|
113 |
+
"# cluster.scale(3)\n",
|
114 |
+
"cluster.adapt(minimum_jobs=50, maximum_jobs=100)\n",
|
115 |
+
"client = Client(cluster)"
|
116 |
+
]
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"cell_type": "code",
|
120 |
+
"execution_count": null,
|
121 |
+
"metadata": {
|
122 |
+
"tags": []
|
123 |
+
},
|
124 |
+
"outputs": [],
|
125 |
+
"source": [
|
126 |
+
"\n",
|
127 |
+
"\n",
|
128 |
+
"@task(cache_key_fn=task_input_hash, cache_expiration=timedelta(hours=24), log_prints=True)\n",
|
129 |
+
"def calculate_single_diatomic(\n",
|
130 |
+
" calculator: str | EXTMLIPEnum | Calculator,\n",
|
131 |
+
" calculator_kwargs: dict | None,\n",
|
132 |
+
" atom1: str,\n",
|
133 |
+
" atom2: str,\n",
|
134 |
+
" rmin: float = 1.25,\n",
|
135 |
+
" rmax: float = 6.25,\n",
|
136 |
+
" rstep: float = 0.2,\n",
|
137 |
+
" magnetism: str = \"FM\"\n",
|
138 |
+
"):\n",
|
139 |
+
"\n",
|
140 |
+
" calculator_kwargs = calculator_kwargs or {}\n",
|
141 |
+
"\n",
|
142 |
+
" if isinstance(calculator, str) and calculator.lower() == 'vasp-mp-gga':\n",
|
143 |
+
" calc = Vasp(**calculator_kwargs)\n",
|
144 |
+
" calc.name = 'vasp-mp-gga'\n",
|
145 |
+
" # calc.name='atomate2'\n",
|
146 |
+
" elif isinstance(calculator, EXTMLIPEnum) and calculator in EXTMLIPEnum:\n",
|
147 |
+
" calc = external_ase_calculator(calculator, **calculator_kwargs)\n",
|
148 |
+
" elif calculator in MLIPMap:\n",
|
149 |
+
" calc = MLIPMap[calculator](**calculator_kwargs)\n",
|
150 |
+
" elif issubclass(calculator, Calculator):\n",
|
151 |
+
" calc = calculator(**calculator_kwargs)\n",
|
152 |
+
"\n",
|
153 |
+
" a = 2 * rmax\n",
|
154 |
+
"\n",
|
155 |
+
" npts = int((rmax - rmin)/rstep)\n",
|
156 |
+
"\n",
|
157 |
+
" rs = np.linspace(rmin, rmax, npts)\n",
|
158 |
+
" e = np.zeros_like(rs)\n",
|
159 |
+
" f = np.zeros_like(rs)\n",
|
160 |
+
"\n",
|
161 |
+
" da = atom1 + atom2\n",
|
162 |
+
" \n",
|
163 |
+
" assert isinstance(calc, Calculator)\n",
|
164 |
+
" \n",
|
165 |
+
" out_dir = Path(str(da + f\"_{magnetism}\"))\n",
|
166 |
+
" os.makedirs(out_dir, exist_ok=True)\n",
|
167 |
+
" \n",
|
168 |
+
" calc.directory = out_dir\n",
|
169 |
+
" \n",
|
170 |
+
" print(f\"write output to {calc.directory}\")\n",
|
171 |
+
" \n",
|
172 |
+
" element = Element(atom1)\n",
|
173 |
+
" \n",
|
174 |
+
" try:\n",
|
175 |
+
" m = element.valence[1]\n",
|
176 |
+
" if element.valence == (0, 2):\n",
|
177 |
+
" m = 0\n",
|
178 |
+
" except:\n",
|
179 |
+
" m = 0\n",
|
180 |
+
" \n",
|
181 |
+
" r = rs[0]\n",
|
182 |
+
" \n",
|
183 |
+
" positions = [\n",
|
184 |
+
" [a/2-r/2, a/2, a/2],\n",
|
185 |
+
" [a/2+r/2, a/2, a/2],\n",
|
186 |
+
" ]\n",
|
187 |
+
" \n",
|
188 |
+
" if magnetism == 'FM':\n",
|
189 |
+
" if m == 0:\n",
|
190 |
+
" return {}\n",
|
191 |
+
" magmoms = [m, m]\n",
|
192 |
+
" elif magnetism == 'AFM':\n",
|
193 |
+
" if m == 0:\n",
|
194 |
+
" return {}\n",
|
195 |
+
" magmoms = [m, -m]\n",
|
196 |
+
" elif magnetism == 'NM':\n",
|
197 |
+
" magmoms = [0, 0]\n",
|
198 |
+
" \n",
|
199 |
+
" traj_fpath = out_dir / \"traj.extxyz\"\n",
|
200 |
+
" \n",
|
201 |
+
" skip = 0\n",
|
202 |
+
" if traj_fpath.exists():\n",
|
203 |
+
" traj = read(traj_fpath, index=\":\")\n",
|
204 |
+
" skip = len(traj)\n",
|
205 |
+
" atoms = traj[-1]\n",
|
206 |
+
" else:\n",
|
207 |
+
" atoms = Atoms(\n",
|
208 |
+
" da, \n",
|
209 |
+
" positions=positions,\n",
|
210 |
+
" magmoms=magmoms,\n",
|
211 |
+
" cell=[a, a+0.001, a+0.002], \n",
|
212 |
+
" pbc=True\n",
|
213 |
+
" )\n",
|
214 |
+
" \n",
|
215 |
+
" # \n",
|
216 |
+
" \n",
|
217 |
+
" structure = AseAtomsAdaptor().get_structure(atoms)\n",
|
218 |
+
" \n",
|
219 |
+
" if magnetism == 'FM':\n",
|
220 |
+
" I_CONSTRAINED_M = 2\n",
|
221 |
+
" LAMBDA = 10\n",
|
222 |
+
" M_CONSTR = [0, 0, 1, 0, 0, 1] # \" \".join(map(str, [0, 0, 1])) + \" \" + \" \".join(map(str, [0, 0, 1]))\n",
|
223 |
+
" elif magnetism == 'AFM':\n",
|
224 |
+
" I_CONSTRAINED_M = 2\n",
|
225 |
+
" LAMBDA = 10\n",
|
226 |
+
" M_CONSTR = [0, 0, 1, 0, 0, -1] # \" \".join(map(str, [0, 0, 1])) + \" \" + \" \".join(map(str, [0, 0, -1]))\n",
|
227 |
+
" elif magnetism == 'NM':\n",
|
228 |
+
" I_CONSTRAINED_M = 1\n",
|
229 |
+
" LAMBDA = 10\n",
|
230 |
+
" M_CONSTR = [0, 0, 0, 0, 0, 0] #\" \".join(map(str, [0, 0, 0])) + \" \" + \" \".join(map(str, [0, 0, 0]))\n",
|
231 |
+
"\n",
|
232 |
+
" input_set_generator = MPGGAStaticSetGenerator(\n",
|
233 |
+
" user_incar_settings=dict(\n",
|
234 |
+
" ISYM = 0, # symmetry is off\n",
|
235 |
+
" ISPIN = 2,\n",
|
236 |
+
" ISMEAR = 0, # Gaussian smearing, otherwise negative occupancies might come up\n",
|
237 |
+
" SIGMA = 0.002, # tiny smearing width to safely break symmetry\n",
|
238 |
+
" AMIX = 0.2, # mixing set manually\n",
|
239 |
+
" BMIX = 0.0001,\n",
|
240 |
+
" LSUBROT= True, # spin orbit coupling (non collinear)\n",
|
241 |
+
" ALGO = \"Accurate\",\n",
|
242 |
+
" PREC = \"High\",\n",
|
243 |
+
" ENCUT = 1000,\n",
|
244 |
+
" ENAUG = 2000,\n",
|
245 |
+
" ISTART = 1,\n",
|
246 |
+
" ICHARG = 1,\n",
|
247 |
+
" NELM = 200,\n",
|
248 |
+
" TIME = 0.2,\n",
|
249 |
+
" LELF = False,\n",
|
250 |
+
" LMAXMIX=max(max(map(lambda a: \"spdf\".index(Element(a.symbol).block) * 2, atoms)), 2),\n",
|
251 |
+
" LMIXTAU=False,\n",
|
252 |
+
" VOSKOWN = 1,\n",
|
253 |
+
" I_CONSTRAINED_M = I_CONSTRAINED_M,\n",
|
254 |
+
" M_CONSTR = M_CONSTR,\n",
|
255 |
+
" LAMBDA = LAMBDA,\n",
|
256 |
+
" # performance\n",
|
257 |
+
" # lplane=False,\n",
|
258 |
+
" # npar=int(sqrt(ncpus)),\n",
|
259 |
+
" # nsim=1,\n",
|
260 |
+
" # LPLANE = True,\n",
|
261 |
+
" # # NCORE = 128,\n",
|
262 |
+
" # LSCALU = False,\n",
|
263 |
+
" # NSIM = 4,\n",
|
264 |
+
" # LPLANE = False,\n",
|
265 |
+
" # NPAR = 16,\n",
|
266 |
+
" # NSIM = 1,\n",
|
267 |
+
" # LSCALU = False,\n",
|
268 |
+
" # GPU\n",
|
269 |
+
" KPAR = gpus_per_node,\n",
|
270 |
+
" NSIM = 64,\n",
|
271 |
+
"\n",
|
272 |
+
" LVTOT = False,\n",
|
273 |
+
" LAECHG = True, # AECCARs\n",
|
274 |
+
" LASPH = True, # aspherical charge density\n",
|
275 |
+
" LCHARG = True, # CHGCAR\n",
|
276 |
+
" LWAVE = True\n",
|
277 |
+
" ),\n",
|
278 |
+
" user_kpoints_settings=Kpoints(), # Gamma point only\n",
|
279 |
+
" user_potcar_settings={\n",
|
280 |
+
" \"Yb\": \"Yb_3\"\n",
|
281 |
+
" },\n",
|
282 |
+
" sort_structure=False\n",
|
283 |
+
" )\n",
|
284 |
+
"\n",
|
285 |
+
" vis = input_set_generator.get_input_set(structure=structure)\n",
|
286 |
+
" vis.incar.pop(\"MAGMOM\")\n",
|
287 |
+
"\n",
|
288 |
+
" incar = {key.lower(): value for key, value in vis.incar.items()} \n",
|
289 |
+
" calc.set(kpts=1, gamma=True, **incar)\n",
|
290 |
+
" \n",
|
291 |
+
" atoms.calc = calc\n",
|
292 |
+
"\n",
|
293 |
+
" for i, r in enumerate(np.flip(rs)):\n",
|
294 |
+
"\n",
|
295 |
+
" \n",
|
296 |
+
" if i < skip:\n",
|
297 |
+
" continue\n",
|
298 |
+
"\n",
|
299 |
+
" positions = [\n",
|
300 |
+
" [a/2-r/2, a/2, a/2],\n",
|
301 |
+
" [a/2+r/2, a/2, a/2],\n",
|
302 |
+
" ]\n",
|
303 |
+
" \n",
|
304 |
+
" if i > 0: \n",
|
305 |
+
" magmoms = atoms.get_magnetic_moments()\n",
|
306 |
+
" \n",
|
307 |
+
" atoms.set_initial_magnetic_moments(magmoms)\n",
|
308 |
+
" atoms.set_positions(positions)\n",
|
309 |
+
"\n",
|
310 |
+
" print(f\"{atoms} separated by {r} A ({i+1}/{len(rs)})\")\n",
|
311 |
+
" \n",
|
312 |
+
"\n",
|
313 |
+
" e[i] = atoms.get_potential_energy()\n",
|
314 |
+
" f[i] = np.inner(np.array([1, 0, 0]), atoms.get_forces()[1])\n",
|
315 |
+
" \n",
|
316 |
+
" atoms.calc.results.update(dict(\n",
|
317 |
+
" magmoms=atoms.get_magnetic_moments()\n",
|
318 |
+
" ))\n",
|
319 |
+
" \n",
|
320 |
+
" write(out_dir / \"traj.extxyz\", atoms, append=\"a\")\n",
|
321 |
+
" \n",
|
322 |
+
"# additional_results = {}\n",
|
323 |
+
" \n",
|
324 |
+
"# try:\n",
|
325 |
+
"# ncpus = psutil.cpu_count(logical=True)\n",
|
326 |
+
"# nthreads = os.environ[\"OMP_NUM_THREADS\"]\n",
|
327 |
+
"# subprocess.run([\"export\", f\"OMP_NUM_THREADS={ncpus}\"], shell=True)\n",
|
328 |
+
" \n",
|
329 |
+
"# ca = ChargemolAnalysis(path=out_dir)\n",
|
330 |
+
" \n",
|
331 |
+
"# if charges := ca.ddec_charges:\n",
|
332 |
+
"# additional_results[\"charges\"] = np.array(charges)\n",
|
333 |
+
"# if dipoles := ca.dipoles:\n",
|
334 |
+
"# additional_results[\"dipoles\"] = np.array(dipoles)\n",
|
335 |
+
"# if magmoms := ca.ddec_spin_moments:\n",
|
336 |
+
"# additional_results[\"magmoms\"] = np.array(magmoms)\n",
|
337 |
+
" \n",
|
338 |
+
"# subprocess.run([\"export\", f\"OMP_NUM_THREADS={nthreads}\"], shell=True)\n",
|
339 |
+
"# except:\n",
|
340 |
+
"# print(\"DDEC failed\")\n",
|
341 |
+
" \n",
|
342 |
+
" \n",
|
343 |
+
"# atoms.calc.results.update(additional_results)\n",
|
344 |
+
" \n",
|
345 |
+
" return {\"r\": rs, \"E\": e, \"F\": f, \"da\": da}\n",
|
346 |
+
"\n"
|
347 |
+
]
|
348 |
+
},
|
349 |
+
{
|
350 |
+
"cell_type": "code",
|
351 |
+
"execution_count": null,
|
352 |
+
"metadata": {
|
353 |
+
"tags": []
|
354 |
+
},
|
355 |
+
"outputs": [],
|
356 |
+
"source": [
|
357 |
+
"@flow(task_runner=DaskTaskRunner(address=client.scheduler.address), log_prints=True)\n",
|
358 |
+
"def calculate_multiple_diatomics(calculator_name, calculator_kwargs):\n",
|
359 |
+
"\n",
|
360 |
+
" futures = []\n",
|
361 |
+
" for sa in chemical_symbols:\n",
|
362 |
+
" \n",
|
363 |
+
" s = set([sa])\n",
|
364 |
+
" \n",
|
365 |
+
" if 'X' in s:\n",
|
366 |
+
" continue\n",
|
367 |
+
" \n",
|
368 |
+
" atom = Atom(sa)\n",
|
369 |
+
" rmin = covalent_radii[atom.number] * 2 * 0.6\n",
|
370 |
+
" rvdw = vdw_alvarez.vdw_radii[atom.number] if atom.number < len(vdw_alvarez.vdw_radii) else np.nan \n",
|
371 |
+
" rmax = 3.1 * rvdw if not np.isnan(rvdw) else 6\n",
|
372 |
+
" rstep = 0.2 #if rmin < 1 else 0.4\n",
|
373 |
+
" \n",
|
374 |
+
" futures.append(\n",
|
375 |
+
" calculate_single_diatomic.submit(\n",
|
376 |
+
" calculator_name, calculator_kwargs, sa, sa,\n",
|
377 |
+
" rmin=rmin, rmax=rmax,\n",
|
378 |
+
" rstep=rstep,\n",
|
379 |
+
" magnetism=\"FM\"\n",
|
380 |
+
" # npts=16 if 'H' in s else 21\n",
|
381 |
+
" )\n",
|
382 |
+
" )\n",
|
383 |
+
" futures.append(\n",
|
384 |
+
" calculate_single_diatomic.submit(\n",
|
385 |
+
" calculator_name, calculator_kwargs, sa, sa,\n",
|
386 |
+
" rmin=rmin, rmax=rmax,\n",
|
387 |
+
" rstep=rstep, #0.1 if rmin < 1 else 0.25,\n",
|
388 |
+
" magnetism=\"AFM\"\n",
|
389 |
+
" # npts=16 if 'H' in s else 21\n",
|
390 |
+
" )\n",
|
391 |
+
" )\n",
|
392 |
+
" futures.append(\n",
|
393 |
+
" calculate_single_diatomic.submit(\n",
|
394 |
+
" calculator_name, calculator_kwargs, sa, sa,\n",
|
395 |
+
" rmin=rmin, rmax=rmax,\n",
|
396 |
+
" rstep=rstep, #0.1 if rmin < 1 else 0.25,\n",
|
397 |
+
" magnetism=\"NM\"\n",
|
398 |
+
" # npts=16 if 'H' in s else 21\n",
|
399 |
+
" )\n",
|
400 |
+
" )\n",
|
401 |
+
"# for sa, sb in combinations_with_replacement(chemical_symbols, 2):\n",
|
402 |
+
" \n",
|
403 |
+
"# if 'X' in set([sa, sb]):\n",
|
404 |
+
"# continue\n",
|
405 |
+
" \n",
|
406 |
+
"# futures.append(\n",
|
407 |
+
"# calculate_single_diatomic.submit(\n",
|
408 |
+
"# calculator_name, calculator_kwargs, sa, sb,\n",
|
409 |
+
"# rmin=0.5, rmax=6.5,\n",
|
410 |
+
"# npts=16\n",
|
411 |
+
"# )\n",
|
412 |
+
"# )\n",
|
413 |
+
"\n",
|
414 |
+
" return [i for future in futures for i in future.result()]\n",
|
415 |
+
"\n"
|
416 |
+
]
|
417 |
+
},
|
418 |
+
{
|
419 |
+
"cell_type": "code",
|
420 |
+
"execution_count": null,
|
421 |
+
"metadata": {
|
422 |
+
"scrolled": true,
|
423 |
+
"tags": []
|
424 |
+
},
|
425 |
+
"outputs": [],
|
426 |
+
"source": [
|
427 |
+
"calculate_multiple_diatomics(\n",
|
428 |
+
" \"vasp-mp-gga\", \n",
|
429 |
+
" dict(\n",
|
430 |
+
" xc=\"pbe\",\n",
|
431 |
+
" kpts=1,\n",
|
432 |
+
" # Massively parallel machines (Cray)\n",
|
433 |
+
" # lplane=False,\n",
|
434 |
+
" # npar=int(sqrt(ncpus)),\n",
|
435 |
+
" # nsim=1\n",
|
436 |
+
" # Multicore modern linux machines\n",
|
437 |
+
" # lplane=True,\n",
|
438 |
+
" # npar=2,\n",
|
439 |
+
" # lscalu=False,\n",
|
440 |
+
" # nsim=4\n",
|
441 |
+
" )\n",
|
442 |
+
")\n"
|
443 |
+
]
|
444 |
+
},
|
445 |
+
{
|
446 |
+
"cell_type": "code",
|
447 |
+
"execution_count": null,
|
448 |
+
"metadata": {
|
449 |
+
"scrolled": true,
|
450 |
+
"tags": []
|
451 |
+
},
|
452 |
+
"outputs": [],
|
453 |
+
"source": [
|
454 |
+
"\n",
|
455 |
+
"calculate_homonuclear_diatomics(\n",
|
456 |
+
" \"vasp-mp-gga\", \n",
|
457 |
+
" dict(\n",
|
458 |
+
" xc=\"pbe\",\n",
|
459 |
+
" kpts=1,\n",
|
460 |
+
" # Massively parallel machines (Cray)\n",
|
461 |
+
" # lplane=False,\n",
|
462 |
+
" # npar=int(sqrt(ncpus)),\n",
|
463 |
+
" # nsim=1\n",
|
464 |
+
" # Multicore modern linux machines\n",
|
465 |
+
" # lplane=True,\n",
|
466 |
+
" # npar=2,\n",
|
467 |
+
" # lscalu=False,\n",
|
468 |
+
" # nsim=4\n",
|
469 |
+
" )\n",
|
470 |
+
")\n"
|
471 |
+
]
|
472 |
+
},
|
473 |
+
{
|
474 |
+
"cell_type": "code",
|
475 |
+
"execution_count": null,
|
476 |
+
"metadata": {},
|
477 |
+
"outputs": [],
|
478 |
+
"source": []
|
479 |
+
}
|
480 |
+
],
|
481 |
+
"metadata": {
|
482 |
+
"kernelspec": {
|
483 |
+
"display_name": "mlip-arena",
|
484 |
+
"language": "python",
|
485 |
+
"name": "mlip-arena"
|
486 |
+
},
|
487 |
+
"language_info": {
|
488 |
+
"codemirror_mode": {
|
489 |
+
"name": "ipython",
|
490 |
+
"version": 3
|
491 |
+
},
|
492 |
+
"file_extension": ".py",
|
493 |
+
"mimetype": "text/x-python",
|
494 |
+
"name": "python",
|
495 |
+
"nbconvert_exporter": "python",
|
496 |
+
"pygments_lexer": "ipython3",
|
497 |
+
"version": "3.11.8"
|
498 |
+
},
|
499 |
+
"widgets": {
|
500 |
+
"application/vnd.jupyter.widget-state+json": {
|
501 |
+
"state": {},
|
502 |
+
"version_major": 2,
|
503 |
+
"version_minor": 0
|
504 |
+
}
|
505 |
+
}
|
506 |
+
},
|
507 |
+
"nbformat": 4,
|
508 |
+
"nbformat_minor": 4
|
509 |
+
}
|