Yuan (Cyrus) Chiang commited on
Commit
79edee4
·
unverified ·
1 Parent(s): 3397e50

Add plots, tex files, and missing MOF structure (#60)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .github/workflows/test.yaml +9 -5
  3. examples/bzo/dft.ipynb +0 -0
  4. examples/bzo/pbe/mode-1.npy +0 -0
  5. examples/bzo/pbe/phonopy_params.yaml +0 -0
  6. examples/c2db/ALIGNN.parquet +3 -0
  7. examples/c2db/CHGNet.parquet +3 -0
  8. examples/c2db/M3GNet.parquet +3 -0
  9. examples/c2db/MACE-MP(M).parquet +3 -0
  10. examples/c2db/MACE-MPA.parquet +3 -0
  11. examples/c2db/MatterSim.parquet +3 -0
  12. examples/c2db/ORBv2.parquet +3 -0
  13. examples/c2db/SevenNet.parquet +3 -0
  14. examples/c2db/analysis.ipynb +408 -0
  15. examples/c2db/c2db-confusion_matrices.pdf +0 -0
  16. examples/c2db/c2db-f1_bar.pdf +0 -0
  17. examples/c2db/c2db.db +3 -0
  18. examples/c2db/copy.parquet +3 -0
  19. examples/c2db/run.py +213 -0
  20. examples/eos_bulk/CHGNet_processed.parquet +2 -2
  21. examples/eos_bulk/M3GNet_processed.parquet +2 -2
  22. examples/eos_bulk/MACE-MP(M)_processed.parquet +2 -2
  23. examples/eos_bulk/MACE-MPA_processed.parquet +2 -2
  24. examples/eos_bulk/MatterSim_processed.parquet +2 -2
  25. examples/eos_bulk/ORBv2_processed.parquet +2 -2
  26. examples/eos_bulk/SevenNet_processed.parquet +2 -2
  27. examples/eos_bulk/analyze.py +223 -0
  28. examples/eos_bulk/eSEN_processed.parquet +2 -2
  29. examples/eos_bulk/plot.py +119 -0
  30. examples/eos_bulk/summary.csv +9 -9
  31. examples/eos_bulk/summary.tex +10 -10
  32. examples/mof/CHGNet.pkl +0 -0
  33. examples/mof/M3GNet.pkl +0 -0
  34. examples/mof/MACE-MP(M).pkl +0 -0
  35. examples/mof/MACE-MPA.pkl +0 -0
  36. examples/mof/MatterSim.pkl +0 -0
  37. examples/mof/ORBv2.pkl +0 -0
  38. examples/mof/structures/dac/SGU-29.cif +995 -0
  39. examples/stability/plot.ipynb +0 -0
  40. examples/stability/pressure.ipynb +194 -0
  41. examples/stability/temperature.ipynb +202 -0
  42. examples/vacancy_migration/Table-A1-fcc.csv +58 -0
  43. examples/vacancy_migration/Table-A2-hcp.csv +58 -0
  44. examples/vacancy_migration/analysis.py +284 -0
  45. examples/wbm_ev/analyze.py +210 -0
  46. mlip_arena/models/externals/fairchem.py +3 -3
  47. mlip_arena/tasks/diatomics/homonuclear-diatomics.tex +23 -0
  48. mlip_arena/tasks/registry.yaml +5 -0
  49. serve/ranks/homonuclear-diatomics.py +51 -25
  50. serve/tasks/eos_bulk.py +13 -7
.gitattributes CHANGED
@@ -8,3 +8,5 @@ examples/mof/classification/MACE-MPA.pkl filter=lfs diff=lfs merge=lfs -text
8
  examples/mof/classification/MACE-MP(M).pkl filter=lfs diff=lfs merge=lfs -text
9
  examples/mof/classification/MatterSim.pkl filter=lfs diff=lfs merge=lfs -text
10
  examples/mof/classification/ORBv2.pkl filter=lfs diff=lfs merge=lfs -text
 
 
 
8
  examples/mof/classification/MACE-MP(M).pkl filter=lfs diff=lfs merge=lfs -text
9
  examples/mof/classification/MatterSim.pkl filter=lfs diff=lfs merge=lfs -text
10
  examples/mof/classification/ORBv2.pkl filter=lfs diff=lfs merge=lfs -text
11
+ examples/c2db/*.db filter=lfs diff=lfs merge=lfs -text
12
+ examples/c2db/*.parquet filter=lfs diff=lfs merge=lfs -text
.github/workflows/test.yaml CHANGED
@@ -21,13 +21,11 @@ jobs:
21
  - name: Checkout PR with full history
22
  uses: actions/checkout@v4
23
  with:
24
- lfs: true
25
  fetch-depth: 0
26
 
27
  - name: Install uv
28
  uses: astral-sh/setup-uv@v6
29
  with:
30
- version: "latest"
31
  enable-cache: true
32
  cache-dependency-glob: "pyproject.toml"
33
 
@@ -51,14 +49,14 @@ jobs:
51
  env:
52
  PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
53
  PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
54
- run: pytest -vra -n 5 --dist=loadscope tests
55
 
56
  - name: Squash commits and trial push to Hugging Face
57
  if: github.event_name == 'pull_request'
58
  id: trial_push
59
  env:
60
  HF_TOKEN: ${{ secrets.HF_TOKEN }}
61
- TRIAL_BRANCH: trial-sync-${{ github.sha }}
62
  run: |
63
  # Configure Git user identity
64
  git config user.name "github-actions[ci]"
@@ -69,9 +67,15 @@ jobs:
69
  git reset --soft $BASE
70
  git commit -m "Squashed commit from PR #${{ github.event.pull_request.number }}"
71
 
 
 
 
 
 
72
  # Setup LFS
73
  git lfs fetch
74
  git lfs checkout
 
75
 
76
  # Push to temporary branch on Hugging Face
77
  git push -f https://HF_USERNAME:[email protected]/spaces/atomind/mlip-arena HEAD:refs/heads/$TRIAL_BRANCH
@@ -80,6 +84,6 @@ jobs:
80
  if: steps.trial_push.outcome == 'success'
81
  env:
82
  HF_TOKEN: ${{ secrets.HF_TOKEN }}
83
- TRIAL_BRANCH: trial-sync-${{ github.sha }}
84
  run: |
85
  git push https://HF_USERNAME:[email protected]/spaces/atomind/mlip-arena --delete $TRIAL_BRANCH || true
 
21
  - name: Checkout PR with full history
22
  uses: actions/checkout@v4
23
  with:
 
24
  fetch-depth: 0
25
 
26
  - name: Install uv
27
  uses: astral-sh/setup-uv@v6
28
  with:
 
29
  enable-cache: true
30
  cache-dependency-glob: "pyproject.toml"
31
 
 
49
  env:
50
  PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
51
  PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
52
+ run: pytest -vra -n 5 --basetemp=./.pytest_temp tests
53
 
54
  - name: Squash commits and trial push to Hugging Face
55
  if: github.event_name == 'pull_request'
56
  id: trial_push
57
  env:
58
  HF_TOKEN: ${{ secrets.HF_TOKEN }}
59
+ TRIAL_BRANCH: trial-sync-${{ github.sha }}-${{ matrix.python-version }}
60
  run: |
61
  # Configure Git user identity
62
  git config user.name "github-actions[ci]"
 
67
  git reset --soft $BASE
68
  git commit -m "Squashed commit from PR #${{ github.event.pull_request.number }}"
69
 
70
+ # Install Git LFS
71
+ sudo apt-get update
72
+ sudo apt-get install -y git-lfs
73
+ git lfs install
74
+
75
  # Setup LFS
76
  git lfs fetch
77
  git lfs checkout
78
+ # git config lfs.allowincompletepush true
79
 
80
  # Push to temporary branch on Hugging Face
81
  git push -f https://HF_USERNAME:[email protected]/spaces/atomind/mlip-arena HEAD:refs/heads/$TRIAL_BRANCH
 
84
  if: steps.trial_push.outcome == 'success'
85
  env:
86
  HF_TOKEN: ${{ secrets.HF_TOKEN }}
87
+ TRIAL_BRANCH: trial-sync-${{ github.sha }}-${{ matrix.python-version }}
88
  run: |
89
  git push https://HF_USERNAME:[email protected]/spaces/atomind/mlip-arena --delete $TRIAL_BRANCH || true
examples/bzo/dft.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
examples/bzo/pbe/mode-1.npy ADDED
Binary file (248 Bytes). View file
 
examples/bzo/pbe/phonopy_params.yaml ADDED
The diff for this file is too large to render. See raw diff
 
examples/c2db/ALIGNN.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce4d250afce0a7ef62dd27c5531b1e3a91f761035cc595e64ff6aae225e4ad73
3
+ size 272171
examples/c2db/CHGNet.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a6063fa72efb16a5255b79f5e1a03bd13409ed129016496ff1f494c6f83b98be
3
+ size 292909
examples/c2db/M3GNet.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:32e1517a85a1b64f12fb262a0948a95be58c69edde133ce7ddf683154b8f2a95
3
+ size 290358
examples/c2db/MACE-MP(M).parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f722eac6799bfecaa02188d59475862895a639cc596fa8b7d1e9d2b96cfb415b
3
+ size 293633
examples/c2db/MACE-MPA.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c3ea679b5f6c9940358a2121a496544be91ba01ed8383509c65773f9fc69b9ec
3
+ size 293820
examples/c2db/MatterSim.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d150c1b31b99ddcbbf21401189289aead13791c683aa379d75163b8bc4dbc6b4
3
+ size 293177
examples/c2db/ORBv2.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c2496f96d4aff1536936e58e65c1d608cc1953d41006221ba62ea2daab23f30b
3
+ size 293012
examples/c2db/SevenNet.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c2ee18ce70f24f70e65d70c2e54151e86dd0ccb3e412b8fbbc572e44e8bf5e8
3
+ size 293973
examples/c2db/analysis.ipynb ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0625f0a1",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import random\n",
11
+ "from pathlib import Path\n",
12
+ "\n",
13
+ "import numpy as np\n",
14
+ "from ase.db import connect\n",
15
+ "\n",
16
+ "random.seed(0)\n",
17
+ "\n",
18
+ "DATA_DIR = Path(\".\")\n",
19
+ "\n",
20
+ "db = connect(DATA_DIR / \"c2db.db\")\n",
21
+ "random_indices = random.sample(range(1, len(db) + 1), 1000)\n"
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "code",
26
+ "execution_count": null,
27
+ "id": "005708b9",
28
+ "metadata": {},
29
+ "outputs": [],
30
+ "source": [
31
+ "import itertools\n",
32
+ "\n",
33
+ "import pandas as pd\n",
34
+ "import phonopy\n",
35
+ "from tqdm.auto import tqdm\n",
36
+ "\n",
37
+ "from mlip_arena.models import MLIPEnum\n",
38
+ "\n",
39
+ "for row, model in tqdm(\n",
40
+ " itertools.product(db.select(filter=lambda r: r[\"id\"] in random_indices), MLIPEnum)\n",
41
+ "):\n",
42
+ " uid = row[\"uid\"]\n",
43
+ "\n",
44
+ " if Path(f\"{model.name}.parquet\").exists():\n",
45
+ " df = pd.read_parquet(f\"{model.name}.parquet\")\n",
46
+ " if uid in df[\"uid\"].unique():\n",
47
+ " continue\n",
48
+ " else:\n",
49
+ " df = pd.DataFrame(columns=[\"model\", \"uid\", \"eigenvalues\", \"frequencies\"])\n",
50
+ "\n",
51
+ " try:\n",
52
+ " path = Path(model.name) / uid\n",
53
+ " phonon = phonopy.load(path / \"phonopy.yaml\")\n",
54
+ " frequencies = phonon.get_frequencies(q=(0, 0, 0))\n",
55
+ "\n",
56
+ " data = np.load(path / \"elastic.npz\")\n",
57
+ "\n",
58
+ " eigenvalues = data[\"eigenvalues\"]\n",
59
+ "\n",
60
+ " new_row = pd.DataFrame(\n",
61
+ " [\n",
62
+ " {\n",
63
+ " \"model\": model.name,\n",
64
+ " \"uid\": uid,\n",
65
+ " \"eigenvalues\": eigenvalues,\n",
66
+ " \"frequencies\": frequencies,\n",
67
+ " }\n",
68
+ " ]\n",
69
+ " )\n",
70
+ "\n",
71
+ " df = pd.concat([df, new_row], ignore_index=True)\n",
72
+ " df.drop_duplicates(subset=[\"model\", \"uid\"], keep=\"last\", inplace=True)\n",
73
+ "\n",
74
+ " df.to_parquet(f\"{model.name}.parquet\", index=False)\n",
75
+ " except Exception:\n",
76
+ " pass\n"
77
+ ]
78
+ },
79
+ {
80
+ "cell_type": "code",
81
+ "execution_count": 6,
82
+ "id": "b8d87638",
83
+ "metadata": {},
84
+ "outputs": [],
85
+ "source": [
86
+ "uids = []\n",
87
+ "stabilities = []\n",
88
+ "for row in db.select(filter=lambda r: r[\"id\"] in random_indices):\n",
89
+ " stable = row.key_value_pairs[\"dyn_stab\"]\n",
90
+ " if stable.lower() == \"unknown\":\n",
91
+ " stable = None\n",
92
+ " else:\n",
93
+ " stable = True if stable.lower() == \"yes\" else False\n",
94
+ " uids.append(row.key_value_pairs[\"uid\"])\n",
95
+ " stabilities.append(stable)\n",
96
+ "\n",
97
+ "\n",
98
+ "stabilities = np.array(stabilities)\n",
99
+ "\n",
100
+ "(stabilities == True).sum(), (stabilities == False).sum(), (stabilities == None).sum()"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "markdown",
105
+ "id": "a3c516a7",
106
+ "metadata": {},
107
+ "source": []
108
+ },
109
+ {
110
+ "cell_type": "code",
111
+ "execution_count": 104,
112
+ "id": "0052d0ff",
113
+ "metadata": {},
114
+ "outputs": [],
115
+ "source": [
116
+ "%matplotlib inline\n",
117
+ "\n",
118
+ "from pathlib import Path\n",
119
+ "\n",
120
+ "import numpy as np\n",
121
+ "import pandas as pd\n",
122
+ "from matplotlib import pyplot as plt\n",
123
+ "from sklearn.metrics import (\n",
124
+ " ConfusionMatrixDisplay,\n",
125
+ " classification_report,\n",
126
+ " confusion_matrix,\n",
127
+ ")\n",
128
+ "\n",
129
+ "from mlip_arena.models import MLIPEnum\n",
130
+ "\n",
131
+ "thres = -1e-7\n",
132
+ "\n",
133
+ "select_models = [\n",
134
+ " \"ALIGNN\",\n",
135
+ " \"CHGNet\",\n",
136
+ " \"M3GNet\",\n",
137
+ " \"MACE-MP(M)\",\n",
138
+ " \"MACE-MPA\",\n",
139
+ " \"MatterSim\",\n",
140
+ " \"ORBv2\",\n",
141
+ " \"SevenNet\",\n",
142
+ "]\n",
143
+ "\n",
144
+ "with plt.style.context(\"default\"):\n",
145
+ " # plt.rcParams.update({\n",
146
+ " # # \"title.fontsize\": 10,\n",
147
+ " # \"axes.titlesize\": 10,\n",
148
+ " # \"axes.labelsize\": 8,\n",
149
+ " # })\n",
150
+ "\n",
151
+ " SMALL_SIZE = 8\n",
152
+ " MEDIUM_SIZE = 10\n",
153
+ " BIGGER_SIZE = 12\n",
154
+ " plt.rcParams.update(\n",
155
+ " {\n",
156
+ " \"font.size\": SMALL_SIZE,\n",
157
+ " \"axes.titlesize\": MEDIUM_SIZE,\n",
158
+ " \"axes.labelsize\": MEDIUM_SIZE,\n",
159
+ " \"xtick.labelsize\": MEDIUM_SIZE,\n",
160
+ " \"ytick.labelsize\": MEDIUM_SIZE,\n",
161
+ " \"legend.fontsize\": SMALL_SIZE,\n",
162
+ " \"figure.titlesize\": BIGGER_SIZE,\n",
163
+ " }\n",
164
+ " )\n",
165
+ "\n",
166
+ " fig, axs = plt.subplots(\n",
167
+ " nrows=int(np.ceil(len(MLIPEnum) / 4)),\n",
168
+ " ncols=4,\n",
169
+ " figsize=(6, 3 * int(np.ceil(len(select_models) / 4))),\n",
170
+ " sharey=True,\n",
171
+ " sharex=True,\n",
172
+ " layout=\"constrained\",\n",
173
+ " )\n",
174
+ " axs = axs.flatten()\n",
175
+ " plot_idx = 0\n",
176
+ "\n",
177
+ " for model in MLIPEnum:\n",
178
+ " fpath = DATA_DIR / f\"{model.name}.parquet\"\n",
179
+ " if not fpath.exists():\n",
180
+ " continue\n",
181
+ "\n",
182
+ " if model.name not in select_models:\n",
183
+ " continue\n",
184
+ "\n",
185
+ " df = pd.read_parquet(fpath)\n",
186
+ " df[\"eigval_min\"] = df[\"eigenvalues\"].apply(\n",
187
+ " lambda x: x.min() if np.isreal(x).all() else thres\n",
188
+ " )\n",
189
+ " df[\"freq_min\"] = df[\"frequencies\"].apply(\n",
190
+ " lambda x: x.min() if np.isreal(x).all() else thres\n",
191
+ " )\n",
192
+ " df[\"dyn_stab\"] = ~np.logical_or(\n",
193
+ " df[\"eigval_min\"] < thres, df[\"freq_min\"] < thres\n",
194
+ " )\n",
195
+ "\n",
196
+ " arg = np.argsort(uids)\n",
197
+ " uids_sorted = np.array(uids)[arg]\n",
198
+ " stabilities_sorted = stabilities[arg]\n",
199
+ "\n",
200
+ " sorted_df = (\n",
201
+ " df[df[\"uid\"].isin(uids_sorted)].set_index(\"uid\").reindex(uids_sorted)\n",
202
+ " )\n",
203
+ " mask = ~(stabilities_sorted == None)\n",
204
+ "\n",
205
+ " y_true = stabilities_sorted[mask].astype(\"int\")\n",
206
+ " y_pred = sorted_df[\"dyn_stab\"][mask].fillna(-1).astype(\"int\")\n",
207
+ " cm = confusion_matrix(y_true, y_pred, labels=[1, 0, -1])\n",
208
+ "\n",
209
+ " ax = axs[plot_idx]\n",
210
+ " ConfusionMatrixDisplay(\n",
211
+ " cm, display_labels=[\"stable\", \"unstable\", \"missing\"]\n",
212
+ " ).plot(ax=ax, cmap=\"Blues\", colorbar=False)\n",
213
+ "\n",
214
+ " ax.set_title(model.name)\n",
215
+ " ax.set_xlabel(\"Predicted\")\n",
216
+ " ax.set_ylabel(\"True\")\n",
217
+ " ax.set_xticks([0, 1, 2])\n",
218
+ " ax.set_xticklabels([\"stable\", \"unstable\", \"missing\"])\n",
219
+ " ax.set_yticks([0, 1, 2])\n",
220
+ " ax.set_yticklabels([\"stable\", \"unstable\", \"missing\"])\n",
221
+ "\n",
222
+ " plot_idx += 1\n",
223
+ "\n",
224
+ " # Hide unused subplots\n",
225
+ " for i in range(plot_idx, len(axs)):\n",
226
+ " fig.delaxes(axs[i])\n",
227
+ "\n",
228
+ " # plt.tight_layout()\n",
229
+ " plt.savefig(\"c2db-confusion_matrices.pdf\", bbox_inches=\"tight\")\n",
230
+ " plt.show()\n"
231
+ ]
232
+ },
233
+ {
234
+ "cell_type": "code",
235
+ "execution_count": 52,
236
+ "id": "573b3c38",
237
+ "metadata": {},
238
+ "outputs": [],
239
+ "source": [
240
+ "import pandas as pd\n",
241
+ "from sklearn.metrics import confusion_matrix\n",
242
+ "\n",
243
+ "from mlip_arena.models import MLIPEnum\n",
244
+ "\n",
245
+ "thres = -1e-7\n",
246
+ "\n",
247
+ "summary_df = pd.DataFrame(columns=[\"Model\", \"Stable F1\", \"Unstable F1\", \"Weighted F1\"])\n",
248
+ "\n",
249
+ "for model in MLIPEnum:\n",
250
+ " fpath = DATA_DIR / f\"{model.name}.parquet\"\n",
251
+ "\n",
252
+ " if not fpath.exists() or model.name not in select_models:\n",
253
+ " # print(f\"File {fpath} does not exist\")\n",
254
+ " continue\n",
255
+ " df = pd.read_parquet(fpath)\n",
256
+ "\n",
257
+ " df[\"eigval_min\"] = df[\"eigenvalues\"].apply(\n",
258
+ " lambda x: x.min() if np.isreal(x).all() else thres\n",
259
+ " )\n",
260
+ " df[\"freq_min\"] = df[\"frequencies\"].apply(\n",
261
+ " lambda x: x.min() if np.isreal(x).all() else thres\n",
262
+ " )\n",
263
+ " df[\"dyn_stab\"] = ~np.logical_or(df[\"eigval_min\"] < thres, df[\"freq_min\"] < thres)\n",
264
+ "\n",
265
+ " arg = np.argsort(uids)\n",
266
+ " uids = np.array(uids)[arg]\n",
267
+ " stabilities = stabilities[arg]\n",
268
+ "\n",
269
+ " sorted_df = df[df[\"uid\"].isin(uids)].sort_values(by=\"uid\")\n",
270
+ "\n",
271
+ " # sorted_df = sorted_df.reindex(uids).reset_index()\n",
272
+ " sorted_df = sorted_df.set_index(\"uid\").reindex(uids) # .loc[uids].reset_index()\n",
273
+ "\n",
274
+ " sorted_df = sorted_df.loc[uids]\n",
275
+ " # mask = ~np.logical_or(sorted_df['dyn_stab'].isna().values, stabilities == None)\n",
276
+ " mask = ~(stabilities == None)\n",
277
+ "\n",
278
+ " y_true = stabilities[mask].astype(\"int\")\n",
279
+ " y_pred = sorted_df[\"dyn_stab\"][mask].fillna(-1).astype(\"int\")\n",
280
+ " cm = confusion_matrix(y_true, y_pred, labels=[1, 0, -1])\n",
281
+ " # print(model)\n",
282
+ " # print(cm)\n",
283
+ " # print(classification_report(y_true, y_pred, labels=[1, 0], target_names=['stable', 'unstable'], digits=3, output_dict=False))\n",
284
+ "\n",
285
+ " report = classification_report(\n",
286
+ " y_true,\n",
287
+ " y_pred,\n",
288
+ " labels=[1, 0],\n",
289
+ " target_names=[\"stable\", \"unstable\"],\n",
290
+ " digits=3,\n",
291
+ " output_dict=True,\n",
292
+ " )\n",
293
+ "\n",
294
+ " summary_df = pd.concat(\n",
295
+ " [\n",
296
+ " summary_df,\n",
297
+ " pd.DataFrame(\n",
298
+ " [\n",
299
+ " {\n",
300
+ " \"Model\": model.name,\n",
301
+ " \"Stable F1\": report[\"stable\"][\"f1-score\"],\n",
302
+ " \"Unstable F1\": report[\"unstable\"][\"f1-score\"],\n",
303
+ " \"Macro F1\": report[\"macro avg\"][\"f1-score\"],\n",
304
+ " # 'Micro F1': report['micro avg']['f1-score'],\n",
305
+ " \"Weighted F1\": report[\"weighted avg\"][\"f1-score\"],\n",
306
+ " }\n",
307
+ " ]\n",
308
+ " ),\n",
309
+ " ],\n",
310
+ " ignore_index=True,\n",
311
+ " )\n",
312
+ "\n",
313
+ " # break"
314
+ ]
315
+ },
316
+ {
317
+ "cell_type": "code",
318
+ "execution_count": 85,
319
+ "id": "df660870",
320
+ "metadata": {},
321
+ "outputs": [],
322
+ "source": [
323
+ "summary_df = summary_df.sort_values(by=[\"Macro F1\", \"Weighted F1\"], ascending=False)\n",
324
+ "summary_df.to_latex(\"c2db_summary_table.tex\", index=False, float_format=\"%.3f\")"
325
+ ]
326
+ },
327
+ {
328
+ "cell_type": "code",
329
+ "execution_count": 103,
330
+ "id": "18f4a59b",
331
+ "metadata": {},
332
+ "outputs": [],
333
+ "source": [
334
+ "from matplotlib import cm\n",
335
+ "\n",
336
+ "# Metrics and bar settings\n",
337
+ "metrics = [\"Stable F1\", \"Unstable F1\", \"Macro F1\", \"Weighted F1\"]\n",
338
+ "bar_width = 0.2\n",
339
+ "x = np.arange(len(summary_df))\n",
340
+ "\n",
341
+ "# Get Set2 colormap (as RGBA)\n",
342
+ "cmap = plt.get_cmap(\"tab20\")\n",
343
+ "colors = {metric: cmap(i) for i, metric in enumerate(metrics)}\n",
344
+ "\n",
345
+ "with plt.style.context(\"default\"):\n",
346
+ " plt.rcParams.update(\n",
347
+ " {\n",
348
+ " \"font.size\": SMALL_SIZE,\n",
349
+ " \"axes.titlesize\": MEDIUM_SIZE,\n",
350
+ " \"axes.labelsize\": MEDIUM_SIZE,\n",
351
+ " \"xtick.labelsize\": MEDIUM_SIZE,\n",
352
+ " \"ytick.labelsize\": MEDIUM_SIZE,\n",
353
+ " \"legend.fontsize\": SMALL_SIZE,\n",
354
+ " \"figure.titlesize\": BIGGER_SIZE,\n",
355
+ " }\n",
356
+ " )\n",
357
+ "\n",
358
+ " fig, ax = plt.subplots(figsize=(4, 3), layout=\"constrained\")\n",
359
+ "\n",
360
+ " # Bar positions\n",
361
+ " positions = {\n",
362
+ " \"Stable F1\": x - 1.5 * bar_width,\n",
363
+ " \"Unstable F1\": x - 0.5 * bar_width,\n",
364
+ " \"Macro F1\": x + 0.5 * bar_width,\n",
365
+ " \"Weighted F1\": x + 1.5 * bar_width,\n",
366
+ " }\n",
367
+ "\n",
368
+ " # Plot each metric with assigned color\n",
369
+ " for metric, pos in positions.items():\n",
370
+ " ax.bar(\n",
371
+ " pos, summary_df[metric], width=bar_width, label=metric, color=colors[metric]\n",
372
+ " )\n",
373
+ "\n",
374
+ " ax.set_xlabel(\"Model\")\n",
375
+ " ax.set_ylabel(\"F1 Score\")\n",
376
+ " # ax.set_title('F1 Scores by Model and Class')\n",
377
+ " ax.set_xticks(x)\n",
378
+ " ax.set_xticklabels(summary_df[\"Model\"], rotation=45, ha=\"right\")\n",
379
+ " ax.legend(ncols=2, bbox_to_anchor=(0.5, 1), loc=\"upper center\", fontsize=SMALL_SIZE)\n",
380
+ " # ax.legend(ncols=2, fontsize=SMALL_SIZE)\n",
381
+ " ax.spines[[\"top\", \"right\"]].set_visible(False)\n",
382
+ " plt.tight_layout()\n",
383
+ " plt.ylim(0, 0.9)\n",
384
+ " plt.grid(axis=\"y\", linestyle=\"--\", alpha=0.6)\n",
385
+ "\n",
386
+ " plt.savefig(\"c2db_f1_bar.pdf\", bbox_inches=\"tight\")\n",
387
+ " plt.show()"
388
+ ]
389
+ },
390
+ {
391
+ "cell_type": "code",
392
+ "execution_count": null,
393
+ "id": "1c50f705",
394
+ "metadata": {},
395
+ "outputs": [],
396
+ "source": []
397
+ }
398
+ ],
399
+ "metadata": {
400
+ "kernelspec": {
401
+ "display_name": "mlip-arena",
402
+ "language": "python",
403
+ "name": "mlip-arena"
404
+ }
405
+ },
406
+ "nbformat": 4,
407
+ "nbformat_minor": 5
408
+ }
examples/c2db/c2db-confusion_matrices.pdf ADDED
Binary file (21.2 kB). View file
 
examples/c2db/c2db-f1_bar.pdf ADDED
Binary file (17.9 kB). View file
 
examples/c2db/c2db.db ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:caf58205692de480e06149ac43a437385f18e14582e7d9a8dab8b3cb5d4bd678
3
+ size 70762496
examples/c2db/copy.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fdc16667361b10bfb032862d5d0610c242d75cb88f7f3883c43a406b245e991
3
+ size 21349
examples/c2db/run.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from itertools import product
2
+ from pathlib import Path
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+ from dask.distributed import Client
7
+ from dask_jobqueue import SLURMCluster
8
+ from mlip_arena.models import MLIPEnum
9
+ from mlip_arena.tasks import ELASTICITY, OPT, PHONON
10
+ from mlip_arena.tasks.optimize import run as OPT
11
+ from mlip_arena.tasks.utils import get_calculator
12
+ from numpy import linalg as LA
13
+ from prefect import flow, task
14
+ from prefect_dask import DaskTaskRunner
15
+ from tqdm.auto import tqdm
16
+
17
+ from ase.db import connect
18
+
19
+ select_models = [
20
+ "ALIGNN",
21
+ "CHGNet",
22
+ "M3GNet",
23
+ "MACE-MP(M)",
24
+ "MACE-MPA",
25
+ "MatterSim",
26
+ "ORBv2",
27
+ "SevenNet",
28
+ ]
29
+
30
+ def elastic_tensor_to_voigt(C):
31
+ """
32
+ Convert a rank-4 (3x3x3x3) elastic tensor into a rank-2 (6x6) tensor using Voigt notation.
33
+
34
+ Parameters:
35
+ C (numpy.ndarray): A 3x3x3x3 elastic tensor.
36
+
37
+ Returns:
38
+ numpy.ndarray: A 6x6 elastic tensor in Voigt notation.
39
+ """
40
+ # voigt_map = {
41
+ # (0, 0): 0, (1, 1): 1, (2, 2): 2, # Normal components
42
+ # (1, 2): 3, (2, 1): 3, # Shear components
43
+ # (0, 2): 4, (2, 0): 4,
44
+ # (0, 1): 5, (1, 0): 5
45
+ # }
46
+ voigt_map = {
47
+ (0, 0): 0,
48
+ (1, 1): 1,
49
+ (2, 2): -1, # Normal components
50
+ (1, 2): -1,
51
+ (2, 1): -1, # Shear components
52
+ (0, 2): -1,
53
+ (2, 0): -1,
54
+ (0, 1): 2,
55
+ (1, 0): 2,
56
+ }
57
+
58
+ C_voigt = np.zeros((3, 3))
59
+
60
+ for i in range(3):
61
+ for j in range(3):
62
+ for k in range(3):
63
+ for l in range(3):
64
+ alpha = voigt_map[(i, j)]
65
+ beta = voigt_map[(k, l)]
66
+
67
+ if alpha == -1 or beta == -1:
68
+ continue
69
+
70
+ factor = 1
71
+ # if alpha in [3, 4, 5]:
72
+ if alpha == 2:
73
+ factor = factor * (2**0.5)
74
+ if beta == 2:
75
+ factor = factor * (2**0.5)
76
+
77
+ C_voigt[alpha, beta] = C[i, j, k, l] * factor
78
+
79
+ return C_voigt
80
+
81
+
82
+ # -
83
+
84
+
85
+ @task
86
+ def run_one(model, row):
87
+ if Path(f"{model.name}.pkl").exists():
88
+ df = pd.read_pickle(f"{model.name}.pkl")
89
+
90
+ # if row.key_value_pairs.get('uid', None) in df['uid'].unique():
91
+ # pass
92
+ else:
93
+ df = pd.DataFrame(columns=["model", "uid", "eigenvalues", "frequencies"])
94
+
95
+ atoms = row.toatoms()
96
+ # print(data := row.key_value_pairs)
97
+
98
+ calc = get_calculator(model)
99
+
100
+ result_opt = OPT(
101
+ atoms,
102
+ calc,
103
+ optimizer="FIRE",
104
+ criterion=dict(fmax=0.05, steps=500),
105
+ symmetry=True,
106
+ )
107
+
108
+ atoms = result_opt["atoms"]
109
+
110
+ result_elastic = ELASTICITY(
111
+ atoms,
112
+ calc,
113
+ optimizer="FIRE",
114
+ criterion=dict(fmax=0.05, steps=500),
115
+ pre_relax=False,
116
+ )
117
+
118
+ elastic_tensor = elastic_tensor_to_voigt(result_elastic["elastic_tensor"])
119
+ eigenvalues, eigenvectors = LA.eig(elastic_tensor)
120
+
121
+ outdir = Path(f"{model.name}") / row.key_value_pairs.get(
122
+ "uid", atoms.get_chemical_formula()
123
+ )
124
+ outdir.mkdir(parents=True, exist_ok=True)
125
+
126
+ np.savez(outdir / "elastic.npz", tensor=elastic_tensor, eigenvalues=eigenvalues)
127
+
128
+ result_phonon = PHONON(
129
+ atoms,
130
+ calc,
131
+ supercell_matrix=(2, 2, 1),
132
+ outdir=outdir,
133
+ )
134
+
135
+ frequencies = result_phonon["phonon"].get_frequencies(q=(0, 0, 0))
136
+
137
+ new_row = pd.DataFrame(
138
+ [
139
+ {
140
+ "model": model.name,
141
+ "uid": row.key_value_pairs.get("uid", None),
142
+ "eigenvalues": eigenvalues,
143
+ "frequencies": frequencies,
144
+ }
145
+ ]
146
+ )
147
+
148
+ df = pd.concat([df, new_row], ignore_index=True)
149
+ df.drop_duplicates(subset=["model", "uid"], keep="last", inplace=True)
150
+
151
+ df.to_pickle(f"{model.name}.pkl")
152
+
153
+
154
+ @flow
155
+ def run_all():
156
+ import random
157
+
158
+ random.seed(0)
159
+
160
+ futures = []
161
+ with connect("c2db.db") as db:
162
+ random_indices = random.sample(range(1, len(db) + 1), 1000)
163
+ for row, model in tqdm(
164
+ product(db.select(filter=lambda r: r["id"] in random_indices), MLIPEnum)
165
+ ):
166
+ if model.name not in select_models:
167
+ continue
168
+ future = run_one.submit(model, row)
169
+ futures.append(future)
170
+ return [f.result(raise_on_failure=False) for f in futures]
171
+
172
+
173
+ # +
174
+
175
+
176
+ if __name__ == "__main__":
177
+ nodes_per_alloc = 1
178
+ gpus_per_alloc = 1
179
+ ntasks = 1
180
+
181
+ cluster_kwargs = dict(
182
+ cores=1,
183
+ memory="64 GB",
184
+ processes=1,
185
+ shebang="#!/bin/bash",
186
+ account="matgen",
187
+ walltime="00:30:00",
188
+ # job_cpu=128,
189
+ job_mem="0",
190
+ job_script_prologue=[
191
+ "source ~/.bashrc",
192
+ "module load python",
193
+ "source activate /pscratch/sd/c/cyrusyc/.conda/dev",
194
+ ],
195
+ job_directives_skip=["-n", "--cpus-per-task", "-J"],
196
+ job_extra_directives=[
197
+ "-J c2db",
198
+ "-q regular",
199
+ f"-N {nodes_per_alloc}",
200
+ "-C gpu",
201
+ f"-G {gpus_per_alloc}",
202
+ ],
203
+ )
204
+
205
+ cluster = SLURMCluster(**cluster_kwargs)
206
+ print(cluster.job_script())
207
+ cluster.adapt(minimum_jobs=25, maximum_jobs=50)
208
+ client = Client(cluster)
209
+ # -
210
+
211
+ run_all.with_options(
212
+ task_runner=DaskTaskRunner(address=client.scheduler.address), log_prints=True
213
+ )()
examples/eos_bulk/CHGNet_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0416eeed1748994b67e8f6e9768a5f1d2a77c19f9512bc408f9b39ca3c19e3d4
3
- size 358042
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bfde7530e6b0d2df5a30e1b7e3ec124fb2a86f6da8e35d2548d37d10a1eff1b1
3
+ size 387425
examples/eos_bulk/M3GNet_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1a34f8148f771f0b751f01ccc9d260fd5ae48b625b979ec2112e008c82c59a08
3
- size 379982
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eb43a3c74f3340100b1adb21b3f2d075451e1ffe88ac6d6662741bc4a0576eb8
3
+ size 397450
examples/eos_bulk/MACE-MP(M)_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:73e2b8ad6d5e114c1c0fea4697b17810182d0b273185512cb40fa894ea30b4c3
3
- size 371128
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e5507cdc5fe558b5d3fe2ea8f1dd577ac444e82c5347b5fbe738a4f855dffcb
3
+ size 397379
examples/eos_bulk/MACE-MPA_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:819bc0c721e99df8dda0a4c6df565deb96736ecc5ceefefe300e5b72b7d6312f
3
- size 365412
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f3032d5a156febdd9580fa3d86cb1a84236374bcac6ccb22d18a948767db502
3
+ size 394748
examples/eos_bulk/MatterSim_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:c707ffb285f03a5c7d1486a6998c787088f07a97b206585b17839fff4fab49b4
3
- size 321086
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb1f10a60495f5e88ea8cf737fd7b47d1c471fda422374ee519d14f531c732f8
3
+ size 290191
examples/eos_bulk/ORBv2_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:f794da83d1031823577b085c480f7d285520c086bdd0e7e6e7acb7a5a2457329
3
- size 228052
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7eb0a3060b8a2d3541b8fb1083176c88aae0a8be0008e84d5770998b01742216
3
+ size 402554
examples/eos_bulk/SevenNet_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:a9aab95402aa62169ba6f1e12a7774362b3e5cc027f5c556de734783e6d6f29b
3
- size 364969
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9f484928f5086e8d1411a198ac69bfe44313597909b72c8676e9131cce1660f1
3
+ size 398295
examples/eos_bulk/analyze.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ from ase.db import connect
6
+ from scipy import stats
7
+
8
+ from mlip_arena.models import REGISTRY, MLIPEnum
9
+
10
+ DATA_DIR = Path(__file__).parent.absolute()
11
+
12
+
13
+ def load_wbm_structures():
14
+ """
15
+ Load the WBM structures from a ASE DB file.
16
+ """
17
+ with connect(DATA_DIR.parent / "wbm_structures.db") as db:
18
+ for row in db.select():
19
+ yield row.toatoms(add_additional_information=True)
20
+
21
+ def gather_results():
22
+ for model in MLIPEnum:
23
+ if "eos_bulk" not in REGISTRY[model.name].get("gpu-tasks", []):
24
+ continue
25
+
26
+ if (DATA_DIR / f"{model.name}.parquet").exists():
27
+ continue
28
+
29
+ all_data = []
30
+
31
+ for atoms in load_wbm_structures():
32
+ fpath = Path(model.name) / f"{atoms.info['key_value_pairs']['wbm_id']}.pkl"
33
+ if not fpath.exists():
34
+ continue
35
+
36
+ all_data.append(pd.read_pickle(fpath))
37
+
38
+ df = pd.concat(all_data, ignore_index=True)
39
+ df.to_parquet(DATA_DIR / f"{model.name}.parquet")
40
+
41
+
42
+ def summarize():
43
+ summary_table = pd.DataFrame(
44
+ columns=[
45
+ "model",
46
+ "energy-diff-flip-times",
47
+ "tortuosity",
48
+ "spearman-compression-energy",
49
+ "spearman-compression-derivative",
50
+ "spearman-tension-energy",
51
+ "missing",
52
+ ]
53
+ )
54
+
55
+
56
+ for model in MLIPEnum:
57
+ fpath = DATA_DIR / f"{model.name}.parquet"
58
+ if not fpath.exists():
59
+ continue
60
+ df_raw_results = pd.read_parquet(fpath)
61
+
62
+ df_analyzed = pd.DataFrame(
63
+ columns=[
64
+ "model",
65
+ "structure",
66
+ "formula",
67
+ "volume-ratio",
68
+ "energy-delta-per-atom",
69
+ "energy-diff-flip-times",
70
+ "energy-delta-per-volume-b0",
71
+ "tortuosity",
72
+ "spearman-compression-energy",
73
+ "spearman-compression-derivative",
74
+ "spearman-tension-energy",
75
+ "missing",
76
+ ]
77
+ )
78
+
79
+ for wbm_struct in load_wbm_structures():
80
+ structure_id = wbm_struct.info["key_value_pairs"]["wbm_id"]
81
+
82
+ try:
83
+ results = df_raw_results.loc[df_raw_results["id"] == structure_id]
84
+ b0 = results["b0"].values[0]
85
+ # vol0 = results["v0"].values[0]
86
+ results = results["eos"].values[0]
87
+ es = np.array(results["energies"])
88
+ vols = np.array(results["volumes"])
89
+
90
+ indices = np.argsort(vols)
91
+ vols = vols[indices]
92
+ es = es[indices]
93
+
94
+ imine = len(es) // 2
95
+ # min_center_val = np.min(es[imid - 1 : imid + 2])
96
+ # imine = np.where(es == min_center_val)[0][0]
97
+ emin = es[imine]
98
+ vol0 = vols[imine]
99
+
100
+ interpolated_volumes = [
101
+ (vols[i] + vols[i + 1]) / 2 for i in range(len(vols) - 1)
102
+ ]
103
+ ediff = np.diff(es)
104
+ ediff_sign = np.sign(ediff)
105
+ mask = ediff_sign != 0
106
+ ediff = ediff[mask]
107
+ ediff_sign = ediff_sign[mask]
108
+ ediff_flip = np.diff(ediff_sign) != 0
109
+
110
+ etv = np.sum(np.abs(np.diff(es)))
111
+
112
+ data = {
113
+ "model": model.name,
114
+ "structure": structure_id,
115
+ "formula": wbm_struct.get_chemical_formula(),
116
+ "missing": False,
117
+ "volume-ratio": vols / vol0,
118
+ "energy-delta-per-atom": (es - emin) / len(wbm_struct),
119
+ "energy-diff-flip-times": np.sum(ediff_flip).astype(int),
120
+ "energy-delta-per-volume-b0": (es - emin) / (b0*vol0),
121
+ "tortuosity": etv / (abs(es[0] - emin) + abs(es[-1] - emin)),
122
+ "spearman-compression-energy": stats.spearmanr(
123
+ vols[:imine], es[:imine]
124
+ ).statistic,
125
+ "spearman-compression-derivative": stats.spearmanr(
126
+ interpolated_volumes[:imine], ediff[:imine]
127
+ ).statistic,
128
+ "spearman-tension-energy": stats.spearmanr(
129
+ vols[imine:], es[imine:]
130
+ ).statistic,
131
+ }
132
+
133
+ except Exception as e:
134
+ print(e)
135
+ data = {
136
+ "model": model.name,
137
+ "structure": structure_id,
138
+ "formula": wbm_struct.get_chemical_formula(),
139
+ "missing": True,
140
+ "volume-ratio": None,
141
+ "energy-delta-per-atom": None,
142
+ "energy-delta-per-volume-b0": None,
143
+ "energy-diff-flip-times": None,
144
+ "tortuosity": None,
145
+ "spearman-compression-energy": None,
146
+ "spearman-compression-derivative": None,
147
+ "spearman-tension-energy": None,
148
+ }
149
+
150
+ df_analyzed = pd.concat([df_analyzed, pd.DataFrame([data])], ignore_index=True)
151
+
152
+ df_analyzed.to_parquet(DATA_DIR / f"{model.name}_processed.parquet")
153
+ # json_fpath = DATA_DIR / f"EV_scan_analyzed_{model.name}.json"
154
+
155
+ # df_analyzed.to_json(json_fpath, orient="records")
156
+
157
+ valid_results = df_analyzed[df_analyzed["missing"] == False]
158
+
159
+ analysis_summary = {
160
+ "model": model.name,
161
+ "energy-diff-flip-times": valid_results["energy-diff-flip-times"].mean(),
162
+ "energy-diff-flip-times-std": valid_results["energy-diff-flip-times"].std(),
163
+ "tortuosity": valid_results["tortuosity"].mean(),
164
+ "tortuosity-std": valid_results["tortuosity"].std(),
165
+ "spearman-compression-energy": valid_results[
166
+ "spearman-compression-energy"
167
+ ].mean(),
168
+ "spearman-compression-energy-std": valid_results["spearman-compression-energy"].std(),
169
+ "spearman-compression-derivative": valid_results[
170
+ "spearman-compression-derivative"
171
+ ].mean(),
172
+ "spearman-compression-derivative-std": valid_results[
173
+ "spearman-compression-derivative"
174
+ ].std(),
175
+ "spearman-tension-energy": valid_results["spearman-tension-energy"].mean(),
176
+ "spearman-tension-energy-std": valid_results["spearman-tension-energy"].std(),
177
+ "missing": len(df_analyzed[df_analyzed["missing"] == True]),
178
+ }
179
+ summary_table = pd.concat(
180
+ [summary_table, pd.DataFrame([analysis_summary])], ignore_index=True
181
+ )
182
+
183
+
184
+ flip_rank = (
185
+ (summary_table["energy-diff-flip-times"] - 1)
186
+ .abs()
187
+ .rank(ascending=True, method="min")
188
+ )
189
+ tortuosity_rank = summary_table["tortuosity"].rank(ascending=True, method="min")
190
+ spearman_compression_energy_rank = summary_table["spearman-compression-energy"].rank(
191
+ method="min"
192
+ )
193
+ spearman_compression_derivative_rank = summary_table[
194
+ "spearman-compression-derivative"
195
+ ].rank(ascending=False, method="min")
196
+ spearman_tension_energy_rank = summary_table["spearman-tension-energy"].rank(
197
+ ascending=False, method="min"
198
+ )
199
+ missing_rank = summary_table["missing"].rank(ascending=True, method="min")
200
+
201
+ rank_aggr = (
202
+ flip_rank
203
+ + tortuosity_rank
204
+ + spearman_compression_energy_rank
205
+ + spearman_compression_derivative_rank
206
+ + spearman_tension_energy_rank
207
+ + missing_rank
208
+ )
209
+ rank = rank_aggr.rank(method="min")
210
+
211
+ summary_table.insert(1, "rank", rank.astype(int))
212
+ summary_table.insert(2, "rank-aggregation", rank_aggr.astype(int))
213
+ summary_table = summary_table.sort_values(by="rank", ascending=True)
214
+ summary_table = summary_table.reset_index(drop=True)
215
+
216
+ summary_table.to_csv(DATA_DIR / "summary.csv", index=False)
217
+ summary_table.to_latex(DATA_DIR / "summary.tex", index=False, float_format="%.3f")
218
+
219
+ return summary_table
220
+
221
+ if __name__ == "__main__":
222
+ gather_results()
223
+ summarize()
examples/eos_bulk/eSEN_processed.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:3d12b36a2bd465e16ada4363e31756d5de5d41dd890d0e88e8ca86b76dd66336
3
- size 313235
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d7f754d8e18f645c1608e86286245c11611d5af34f3bd0bbc4a5b63b851a0dee
3
+ size 393790
examples/eos_bulk/plot.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import matplotlib.pyplot as plt
4
+ import numpy as np
5
+ import pandas as pd
6
+ from ase.db import connect
7
+
8
+ from mlip_arena.models import REGISTRY as MODELS
9
+
10
+ DATA_DIR = Path(__file__).parent.absolute()
11
+
12
+ # Use a qualitative color palette from matplotlib
13
+ palette_name = "tab10" # Better for distinguishing multiple lines
14
+ color_sequence = plt.get_cmap(palette_name).colors
15
+
16
+ valid_models = [
17
+ model
18
+ for model, metadata in MODELS.items()
19
+ if "eos_bulk" in metadata.get("gpu-tasks", [])
20
+ ]
21
+
22
+ def load_wbm_structures():
23
+ """
24
+ Load the WBM structures from a ASE DB file.
25
+ """
26
+ with connect(DATA_DIR.parent / "wbm_structures.db") as db:
27
+ for row in db.select():
28
+ yield row.toatoms(add_additional_information=True)
29
+
30
+ # # Collect valid models first
31
+ # valid_models = []
32
+ # for model_name in valid_models:
33
+ # fpath = DATA_DIR / f"{model_name}_processed.parquet"
34
+ # if fpath.exists():
35
+ # df = pd.read_parquet(fpath)
36
+ # if len(df) > 0:
37
+ # valid_models.append(model)
38
+
39
+ # # Ensure we're showing all 8 models
40
+ # if len(valid_models) < 8:
41
+ # print(f"Warning: Only found {len(valid_models)} valid models instead of 8")
42
+
43
+ # Set up the grid layout
44
+ n_models = len(valid_models)
45
+ n_cols = 4 # Use 4 columns
46
+ n_rows = (n_models + n_cols - 1) // n_cols # Ceiling division to get required rows
47
+
48
+ # Create figure with enough space for all subplots
49
+ fig = plt.figure(
50
+ figsize=(6, 1.25 * n_rows), # Wider for better readability
51
+ constrained_layout=True, # Better than tight_layout for this case
52
+ )
53
+
54
+ # Create grid of subplots
55
+ axes = []
56
+ for i in range(n_models):
57
+ ax = plt.subplot(n_rows, n_cols, i+1)
58
+ axes.append(ax)
59
+
60
+ SMALL_SIZE = 6
61
+ MEDIUM_SIZE = 8
62
+ LARGE_SIZE = 10
63
+
64
+ # Fill in the subplots with data
65
+ for i, model_name in enumerate(valid_models):
66
+ fpath = DATA_DIR / f"{model_name}_processed.parquet"
67
+ df = pd.read_parquet(fpath)
68
+
69
+ ax = axes[i]
70
+ valid_structures = []
71
+
72
+ for j, (_, row) in enumerate(df.iterrows()):
73
+ structure_id = row["structure"]
74
+ formula = row.get("formula", "")
75
+ if isinstance(row["volume-ratio"], (list, np.ndarray)) and isinstance(
76
+ row["energy-delta-per-volume-b0"], (list, np.ndarray)
77
+ ):
78
+ vol_strain = row["volume-ratio"]
79
+ energy_delta = row["energy-delta-per-volume-b0"]
80
+ color = color_sequence[j % len(color_sequence)]
81
+ ax.plot(
82
+ vol_strain,
83
+ energy_delta,
84
+ color=color,
85
+ linewidth=1,
86
+ alpha=0.9,
87
+ )
88
+ valid_structures.append(structure_id)
89
+
90
+ # Set subplot title
91
+ ax.set_title(f"{model_name} ({len(valid_structures)})", fontsize=MEDIUM_SIZE)
92
+
93
+ # Only add y-label to leftmost plots (those with index divisible by n_cols)
94
+ if i % n_cols == 0:
95
+ ax.set_ylabel("$\\frac{\\Delta E}{B V_0}$", fontsize=MEDIUM_SIZE)
96
+ else:
97
+ ax.set_ylabel("")
98
+
99
+ # Only add x-label to bottom row plots
100
+ # Check if this plot is in the bottom row
101
+ is_bottom_row = (i // n_cols) == (n_rows - 1) or (i >= n_models - n_cols)
102
+ if is_bottom_row:
103
+ ax.set_xlabel("$V/V_0$", fontsize=MEDIUM_SIZE)
104
+ else:
105
+ ax.set_xlabel("")
106
+
107
+ ax.set_ylim(-0.02, 0.1) # Consistent y-limits
108
+ ax.axvline(x=1, linestyle="--", color="gray", alpha=0.7)
109
+ ax.tick_params(axis="both", which="major", labelsize=MEDIUM_SIZE)
110
+
111
+ # Make sure all subplots share the x and y limits
112
+ for ax in axes:
113
+ ax.set_xlim(0.8, 1.2) # Adjust these as needed
114
+ ax.set_ylim(-0.02, 0.1)
115
+
116
+ # Save the figure with all plots
117
+ plt.savefig(DATA_DIR / "eos-bulk-grid.png", dpi=300, bbox_inches="tight")
118
+ plt.savefig(DATA_DIR / "eos-bulk-grid.pdf", bbox_inches="tight")
119
+ # plt.show()
examples/eos_bulk/summary.csv CHANGED
@@ -1,9 +1,9 @@
1
- model,rank,rank-aggregation,energy-diff-flip-times,tortuosity,spearman-compression-energy,spearman-compression-derivative,spearman-tension-energy,missing
2
- MACE-MPA,1,7,1.0370741482965933,1.005455197941088,-0.9993684338373716,0.9963320580555048,0.993186372745491,2
3
- eSEN,2,15,1.042211055276382,1.0082267858369258,-0.9993299832495811,0.9968570123343992,0.9920968478757424,5
4
- MACE-MP(M),3,20,1.042211055276382,1.008986842539345,-0.999329983249581,0.9941160347190496,0.9915857612939804,5
5
- MatterSim,4,22,1.045135406218656,1.0060900449752808,-0.99734962463147,0.9927904926901917,0.9880977115916667,3
6
- CHGNet,5,27,1.1053159478435306,1.014753469076796,-0.9964985866690981,0.9929971733381963,0.9866417434120545,3
7
- SevenNet,6,32,1.1093279839518555,1.0186969977862483,-0.9981277164827815,0.9889121911188109,0.9859580417030127,3
8
- M3GNet,7,38,1.1748743718592964,1.0175007963267957,-0.9963209989340641,0.9897426526572255,0.9801690217498693,5
9
- ORBv2,8,48,1.3162134944612287,1.0374718753890275,-0.9918459519667977,0.9701425127407,0.9637462235649547,7
 
1
+ model,rank,rank-aggregation,energy-diff-flip-times,tortuosity,spearman-compression-energy,spearman-compression-derivative,spearman-tension-energy,missing,energy-diff-flip-times-std,tortuosity-std,spearman-compression-energy-std,spearman-compression-derivative-std,spearman-tension-energy-std
2
+ MACE-MPA,1,7,1.0370741482965933,1.005455197941088,-0.9993684338373716,0.9963320580555048,0.993186372745491,2,0.28260902337559207,0.05365793240575371,0.01247051827833709,0.03852356148675327,0.07744103059608153
3
+ eSEN,2,15,1.042211055276382,1.0082267858369258,-0.9993299832495811,0.9968570123343992,0.9920968478757424,5,0.31435657463218236,0.09009343693321628,0.012254373724862471,0.03683033142639347,0.07346152527758068
4
+ MACE-MP(M),3,20,1.042211055276382,1.008986842539345,-0.999329983249581,0.9941160347190496,0.9915857612939804,5,0.3448779209525529,0.1291612188691875,0.011378760248143813,0.059100297945675236,0.0879944289437058
5
+ MatterSim,4,22,1.045135406218656,1.0060900449752808,-0.99734962463147,0.9927904926901917,0.9880977115916667,3,0.376211439097473,0.055231139063835144,0.03888149868978045,0.07797796889169765,0.11523169167576831
6
+ CHGNet,5,27,1.1053159478435306,1.014753469076796,-0.9964985866690981,0.9929971733381963,0.9866417434120545,3,0.5395426308257233,0.12255069852201543,0.051058628207987275,0.05245296840977506,0.11650035215147045
7
+ SevenNet,6,32,1.1093279839518555,1.0186969977862483,-0.9981277164827815,0.9889121911188109,0.9859580417030127,3,0.5552625647497746,0.2749956370938698,0.025627387238441334,0.07657439969351316,0.11715556163493943
8
+ M3GNet,7,38,1.1748743718592964,1.0175007963267957,-0.9963209989340641,0.9897426526572255,0.9801690217498693,5,0.6755070078112404,0.1488462321310986,0.05166730302469224,0.06468954475570607,0.1332400556108672
9
+ ORBv2,8,48,1.3162134944612287,1.0374718753890275,-0.9918459519667977,0.9701425127407,0.9637462235649547,7,0.8699212994733451,0.2149179445701606,0.08208261674781654,0.1315974423719716,0.19758814985102582
examples/eos_bulk/summary.tex CHANGED
@@ -1,14 +1,14 @@
1
- \begin{tabular}{lrrrrrrrl}
2
  \toprule
3
- model & rank & rank-aggregation & energy-diff-flip-times & tortuosity & spearman-compression-energy & spearman-compression-derivative & spearman-tension-energy & missing \\
4
  \midrule
5
- MACE-MPA & 1 & 7 & 1.037074 & 1.005455 & -0.999368 & 0.996332 & 0.993186 & 2 \\
6
- eSEN & 2 & 15 & 1.042211 & 1.008227 & -0.999330 & 0.996857 & 0.992097 & 5 \\
7
- MACE-MP(M) & 3 & 20 & 1.042211 & 1.008987 & -0.999330 & 0.994116 & 0.991586 & 5 \\
8
- MatterSim & 4 & 22 & 1.045135 & 1.006090 & -0.997350 & 0.992790 & 0.988098 & 3 \\
9
- CHGNet & 5 & 27 & 1.105316 & 1.014753 & -0.996499 & 0.992997 & 0.986642 & 3 \\
10
- SevenNet & 6 & 32 & 1.109328 & 1.018697 & -0.998128 & 0.988912 & 0.985958 & 3 \\
11
- M3GNet & 7 & 38 & 1.174874 & 1.017501 & -0.996321 & 0.989743 & 0.980169 & 5 \\
12
- ORBv2 & 8 & 48 & 1.316213 & 1.037472 & -0.991846 & 0.970143 & 0.963746 & 7 \\
13
  \bottomrule
14
  \end{tabular}
 
1
+ \begin{tabular}{lrrrrrrrlrrrrr}
2
  \toprule
3
+ model & rank & rank-aggregation & energy-diff-flip-times & tortuosity & spearman-compression-energy & spearman-compression-derivative & spearman-tension-energy & missing & energy-diff-flip-times-std & tortuosity-std & spearman-compression-energy-std & spearman-compression-derivative-std & spearman-tension-energy-std \\
4
  \midrule
5
+ MACE-MPA & 1 & 7 & 1.037 & 1.005 & -0.999 & 0.996 & 0.993 & 2 & 0.283 & 0.054 & 0.012 & 0.039 & 0.077 \\
6
+ eSEN & 2 & 15 & 1.042 & 1.008 & -0.999 & 0.997 & 0.992 & 5 & 0.314 & 0.090 & 0.012 & 0.037 & 0.073 \\
7
+ MACE-MP(M) & 3 & 20 & 1.042 & 1.009 & -0.999 & 0.994 & 0.992 & 5 & 0.345 & 0.129 & 0.011 & 0.059 & 0.088 \\
8
+ MatterSim & 4 & 22 & 1.045 & 1.006 & -0.997 & 0.993 & 0.988 & 3 & 0.376 & 0.055 & 0.039 & 0.078 & 0.115 \\
9
+ CHGNet & 5 & 27 & 1.105 & 1.015 & -0.996 & 0.993 & 0.987 & 3 & 0.540 & 0.123 & 0.051 & 0.052 & 0.117 \\
10
+ SevenNet & 6 & 32 & 1.109 & 1.019 & -0.998 & 0.989 & 0.986 & 3 & 0.555 & 0.275 & 0.026 & 0.077 & 0.117 \\
11
+ M3GNet & 7 & 38 & 1.175 & 1.018 & -0.996 & 0.990 & 0.980 & 5 & 0.676 & 0.149 & 0.052 & 0.065 & 0.133 \\
12
+ ORBv2 & 8 & 48 & 1.316 & 1.037 & -0.992 & 0.970 & 0.964 & 7 & 0.870 & 0.215 & 0.082 & 0.132 & 0.198 \\
13
  \bottomrule
14
  \end{tabular}
examples/mof/CHGNet.pkl CHANGED
Binary files a/examples/mof/CHGNet.pkl and b/examples/mof/CHGNet.pkl differ
 
examples/mof/M3GNet.pkl CHANGED
Binary files a/examples/mof/M3GNet.pkl and b/examples/mof/M3GNet.pkl differ
 
examples/mof/MACE-MP(M).pkl CHANGED
Binary files a/examples/mof/MACE-MP(M).pkl and b/examples/mof/MACE-MP(M).pkl differ
 
examples/mof/MACE-MPA.pkl CHANGED
Binary files a/examples/mof/MACE-MPA.pkl and b/examples/mof/MACE-MPA.pkl differ
 
examples/mof/MatterSim.pkl CHANGED
Binary files a/examples/mof/MatterSim.pkl and b/examples/mof/MatterSim.pkl differ
 
examples/mof/ORBv2.pkl CHANGED
Binary files a/examples/mof/ORBv2.pkl and b/examples/mof/ORBv2.pkl differ
 
examples/mof/structures/dac/SGU-29.cif ADDED
@@ -0,0 +1,995 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data_sgu-29b_1\(2)
2
+ _audit_creation_date 2025-02-06
3
+ _audit_creation_method 'Materials Studio'
4
+ _symmetry_space_group_name_H-M 'P1'
5
+ _symmetry_Int_Tables_number 1
6
+ _symmetry_cell_setting triclinic
7
+ loop_
8
+ _symmetry_equiv_pos_as_xyz
9
+ x,y,z
10
+ _cell_length_a 20.8200
11
+ _cell_length_b 20.8190
12
+ _cell_length_c 14.6970
13
+ _cell_angle_alpha 90.0000
14
+ _cell_angle_beta 110.7300
15
+ _cell_angle_gamma 90.0000
16
+ loop_
17
+ _atom_site_label
18
+ _atom_site_type_symbol
19
+ _atom_site_fract_x
20
+ _atom_site_fract_y
21
+ _atom_site_fract_z
22
+ _atom_site_U_iso_or_equiv
23
+ _atom_site_adp_type
24
+ _atom_site_occupancy
25
+ Si1 Si 0.24909 0.06259 0.24949 0.00000 Uiso 1.00
26
+ O2 O 0.37297 0.87246 0.00024 0.00000 Uiso 1.00
27
+ O3 O 0.31082 0.10699 0.31523 0.00000 Uiso 1.00
28
+ O4 O 0.43778 0.35840 0.18606 0.00000 Uiso 1.00
29
+ O5 O 0.53049 0.76657 0.18649 0.00000 Uiso 1.00
30
+ O6 O 0.43915 0.85680 0.18418 0.00000 Uiso 1.00
31
+ O7 O 0.18809 0.10887 0.18562 0.00000 Uiso 1.00
32
+ O8 O 0.21990 0.01612 0.31305 0.00000 Uiso 1.00
33
+ O9 O 0.27771 0.01820 0.18331 0.00000 Uiso 1.00
34
+ O10 O 0.47221 0.26806 0.31627 0.00000 Uiso 1.00
35
+ O11 O 0.24662 0.99791 0.99886 0.00000 Uiso 1.00
36
+ O12 O 0.49794 0.25289 0.50055 0.00000 Uiso 1.00
37
+ O13 O 0.12201 0.12220 0.99919 0.00000 Uiso 1.00
38
+ Cu14 Cu 0.37361 0.37328 0.50133 0.00000 Uiso 1.00
39
+ Si15 Si 0.25762 0.96125 0.10339 0.00000 Uiso 1.00
40
+ Si16 Si 0.36206 0.85698 0.10386 0.00000 Uiso 1.00
41
+ Si17 Si 0.18420 0.01989 0.39513 0.00000 Uiso 1.00
42
+ Si18 Si 0.43514 0.26839 0.39631 0.00000 Uiso 1.00
43
+ Si19 Si 0.50622 0.71051 0.10427 0.00000 Uiso 1.00
44
+ Si20 Si 0.42111 0.41440 0.10420 0.00000 Uiso 1.00
45
+ Si21 Si 0.11160 0.10500 0.10374 0.00000 Uiso 1.00
46
+ Si22 Si 0.33078 0.16403 0.39571 0.00000 Uiso 1.00
47
+ O23 O 0.39390 0.33193 0.39620 0.00000 Uiso 1.00
48
+ O24 O 0.32810 0.92030 0.13270 0.00000 Uiso 1.00
49
+ O25 O 0.48780 0.45070 0.10450 0.00000 Uiso 1.00
50
+ O26 O 0.38650 0.20540 0.36660 0.00000 Uiso 1.00
51
+ O27 O 0.19360 0.92010 0.10310 0.00000 Uiso 1.00
52
+ O28 O 0.07510 0.03850 0.10390 0.00000 Uiso 1.00
53
+ O29 O 0.13050 0.96040 0.36510 0.00000 Uiso 1.00
54
+ O30 O 0.32090 0.79310 0.10440 0.00000 Uiso 1.00
55
+ O31 O 0.26670 0.20480 0.39540 0.00000 Uiso 1.00
56
+ O32 O 0.14760 0.08654 0.39450 0.00000 Uiso 1.00
57
+ O33 O 0.44000 0.67410 0.10510 0.00000 Uiso 1.00
58
+ O34 O 0.57300 0.66390 0.13370 0.00000 Uiso 1.00
59
+ Na35 Na 0.76421 0.81238 0.30670 0.00000 Uiso 1.00
60
+ Na36 Na 0.61250 0.43394 0.18653 0.00000 Uiso 1.00
61
+ Na37 Na 0.64365 0.69124 0.31112 0.00000 Uiso 1.00
62
+ Si38 Si 0.74909 0.56259 0.24949 0.00000 Uiso 1.00
63
+ O39 O 0.87297 0.37246 0.00024 0.00000 Uiso 1.00
64
+ O40 O 0.81082 0.60699 0.31523 0.00000 Uiso 1.00
65
+ O41 O 0.93778 0.85840 0.18606 0.00000 Uiso 1.00
66
+ O42 O 0.03049 0.26657 0.18649 0.00000 Uiso 1.00
67
+ O43 O 0.93915 0.35680 0.18418 0.00000 Uiso 1.00
68
+ O44 O 0.68809 0.60887 0.18562 0.00000 Uiso 1.00
69
+ O45 O 0.71990 0.51612 0.31305 0.00000 Uiso 1.00
70
+ O46 O 0.77771 0.51820 0.18331 0.00000 Uiso 1.00
71
+ O47 O 0.97221 0.76806 0.31627 0.00000 Uiso 1.00
72
+ O48 O 0.74662 0.49791 0.99886 0.00000 Uiso 1.00
73
+ O49 O 0.99794 0.75289 0.50055 0.00000 Uiso 1.00
74
+ O50 O 0.62201 0.62220 0.99919 0.00000 Uiso 1.00
75
+ Cu51 Cu 0.87361 0.87328 0.50133 0.00000 Uiso 1.00
76
+ Si52 Si 0.75762 0.46125 0.10339 0.00000 Uiso 1.00
77
+ Si53 Si 0.86206 0.35698 0.10386 0.00000 Uiso 1.00
78
+ Si54 Si 0.68420 0.51989 0.39513 0.00000 Uiso 1.00
79
+ Si55 Si 0.93514 0.76839 0.39631 0.00000 Uiso 1.00
80
+ Si56 Si 0.00622 0.21051 0.10427 0.00000 Uiso 1.00
81
+ Si57 Si 0.92111 0.91440 0.10420 0.00000 Uiso 1.00
82
+ Si58 Si 0.61160 0.60500 0.10374 0.00000 Uiso 1.00
83
+ Si59 Si 0.83078 0.66403 0.39571 0.00000 Uiso 1.00
84
+ O60 O 0.89390 0.83193 0.39620 0.00000 Uiso 1.00
85
+ O61 O 0.82810 0.42030 0.13270 0.00000 Uiso 1.00
86
+ O62 O 0.98780 0.95070 0.10450 0.00000 Uiso 1.00
87
+ O63 O 0.88650 0.70540 0.36660 0.00000 Uiso 1.00
88
+ O64 O 0.69360 0.42010 0.10310 0.00000 Uiso 1.00
89
+ O65 O 0.57510 0.53850 0.10390 0.00000 Uiso 1.00
90
+ O66 O 0.63050 0.46040 0.36510 0.00000 Uiso 1.00
91
+ O67 O 0.82090 0.29310 0.10440 0.00000 Uiso 1.00
92
+ O68 O 0.76670 0.70480 0.39540 0.00000 Uiso 1.00
93
+ O69 O 0.64760 0.58654 0.39450 0.00000 Uiso 1.00
94
+ O70 O 0.94000 0.17410 0.10510 0.00000 Uiso 1.00
95
+ O71 O 0.07300 0.16390 0.13370 0.00000 Uiso 1.00
96
+ Na72 Na 0.26421 0.31238 0.30670 0.00000 Uiso 1.00
97
+ Na73 Na 0.11250 0.93394 0.18653 0.00000 Uiso 1.00
98
+ Na74 Na 0.14365 0.19124 0.31112 0.00000 Uiso 1.00
99
+ Na75 Na 0.98990 0.56290 0.20950 0.00000 Uiso 1.00
100
+ Si76 Si 0.75091 0.06259 0.25051 0.00000 Uiso 1.00
101
+ O77 O 0.62703 0.87246 0.49976 0.00000 Uiso 1.00
102
+ O78 O 0.68918 0.10699 0.18477 0.00000 Uiso 1.00
103
+ O79 O 0.56222 0.35840 0.31394 0.00000 Uiso 1.00
104
+ O80 O 0.46951 0.76657 0.31351 0.00000 Uiso 1.00
105
+ O81 O 0.56085 0.85680 0.31582 0.00000 Uiso 1.00
106
+ O82 O 0.81191 0.10887 0.31438 0.00000 Uiso 1.00
107
+ O83 O 0.78010 0.01612 0.18695 0.00000 Uiso 1.00
108
+ O84 O 0.72229 0.01820 0.31669 0.00000 Uiso 1.00
109
+ O85 O 0.52779 0.26806 0.18373 0.00000 Uiso 1.00
110
+ O86 O 0.75338 0.99791 0.50114 0.00000 Uiso 1.00
111
+ O87 O 0.50206 0.25289 0.99945 0.00000 Uiso 1.00
112
+ O88 O 0.87799 0.12220 0.50081 0.00000 Uiso 1.00
113
+ Cu89 Cu 0.62639 0.37328 0.99867 0.00000 Uiso 1.00
114
+ Si90 Si 0.74238 0.96125 0.39661 0.00000 Uiso 1.00
115
+ Si91 Si 0.63794 0.85698 0.39614 0.00000 Uiso 1.00
116
+ Si92 Si 0.81580 0.01989 0.10487 0.00000 Uiso 1.00
117
+ Si93 Si 0.56486 0.26839 0.10369 0.00000 Uiso 1.00
118
+ Si94 Si 0.49378 0.71051 0.39573 0.00000 Uiso 1.00
119
+ Si95 Si 0.57889 0.41440 0.39580 0.00000 Uiso 1.00
120
+ Si96 Si 0.88840 0.10500 0.39626 0.00000 Uiso 1.00
121
+ Si97 Si 0.66922 0.16403 0.10429 0.00000 Uiso 1.00
122
+ O98 O 0.60610 0.33193 0.10380 0.00000 Uiso 1.00
123
+ O99 O 0.67190 0.92030 0.36730 0.00000 Uiso 1.00
124
+ O100 O 0.51220 0.45070 0.39550 0.00000 Uiso 1.00
125
+ O101 O 0.61350 0.20540 0.13340 0.00000 Uiso 1.00
126
+ O102 O 0.80640 0.92010 0.39690 0.00000 Uiso 1.00
127
+ O103 O 0.92490 0.03850 0.39610 0.00000 Uiso 1.00
128
+ O104 O 0.86950 0.96040 0.13490 0.00000 Uiso 1.00
129
+ O105 O 0.67910 0.79310 0.39560 0.00000 Uiso 1.00
130
+ O106 O 0.73330 0.20480 0.10460 0.00000 Uiso 1.00
131
+ O107 O 0.85240 0.08654 0.10550 0.00000 Uiso 1.00
132
+ O108 O 0.56000 0.67410 0.39490 0.00000 Uiso 1.00
133
+ O109 O 0.42700 0.66390 0.36630 0.00000 Uiso 1.00
134
+ Na110 Na 0.23579 0.81238 0.19330 0.00000 Uiso 1.00
135
+ Na111 Na 0.38750 0.43394 0.31347 0.00000 Uiso 1.00
136
+ Na112 Na 0.35635 0.69124 0.18888 0.00000 Uiso 1.00
137
+ Na113 Na 0.51010 0.06290 0.29050 0.00000 Uiso 1.00
138
+ Si114 Si 0.25091 0.56259 0.25051 0.00000 Uiso 1.00
139
+ O115 O 0.12703 0.37246 0.49976 0.00000 Uiso 1.00
140
+ O116 O 0.18918 0.60699 0.18477 0.00000 Uiso 1.00
141
+ O117 O 0.06222 0.85840 0.31394 0.00000 Uiso 1.00
142
+ O118 O 0.96951 0.26657 0.31351 0.00000 Uiso 1.00
143
+ O119 O 0.06085 0.35680 0.31582 0.00000 Uiso 1.00
144
+ O120 O 0.31191 0.60887 0.31438 0.00000 Uiso 1.00
145
+ O121 O 0.28010 0.51612 0.18695 0.00000 Uiso 1.00
146
+ O122 O 0.22229 0.51820 0.31669 0.00000 Uiso 1.00
147
+ O123 O 0.02779 0.76806 0.18373 0.00000 Uiso 1.00
148
+ O124 O 0.25338 0.49791 0.50114 0.00000 Uiso 1.00
149
+ O125 O 0.00206 0.75289 0.99945 0.00000 Uiso 1.00
150
+ O126 O 0.37799 0.62220 0.50081 0.00000 Uiso 1.00
151
+ Cu127 Cu 0.12639 0.87328 0.99867 0.00000 Uiso 1.00
152
+ Si128 Si 0.24238 0.46125 0.39661 0.00000 Uiso 1.00
153
+ Si129 Si 0.13794 0.35698 0.39614 0.00000 Uiso 1.00
154
+ Si130 Si 0.31580 0.51989 0.10487 0.00000 Uiso 1.00
155
+ Si131 Si 0.06486 0.76839 0.10369 0.00000 Uiso 1.00
156
+ Si132 Si 0.99378 0.21051 0.39573 0.00000 Uiso 1.00
157
+ Si133 Si 0.07889 0.91440 0.39580 0.00000 Uiso 1.00
158
+ Si134 Si 0.38840 0.60500 0.39626 0.00000 Uiso 1.00
159
+ Si135 Si 0.16922 0.66403 0.10429 0.00000 Uiso 1.00
160
+ O136 O 0.10610 0.83193 0.10380 0.00000 Uiso 1.00
161
+ O137 O 0.17190 0.42030 0.36730 0.00000 Uiso 1.00
162
+ O138 O 0.01220 0.95070 0.39550 0.00000 Uiso 1.00
163
+ O139 O 0.11350 0.70540 0.13340 0.00000 Uiso 1.00
164
+ O140 O 0.30640 0.42010 0.39690 0.00000 Uiso 1.00
165
+ O141 O 0.42490 0.53850 0.39610 0.00000 Uiso 1.00
166
+ O142 O 0.36950 0.46040 0.13490 0.00000 Uiso 1.00
167
+ O143 O 0.17910 0.29310 0.39560 0.00000 Uiso 1.00
168
+ O144 O 0.23330 0.70480 0.10460 0.00000 Uiso 1.00
169
+ O145 O 0.35240 0.58654 0.10550 0.00000 Uiso 1.00
170
+ O146 O 0.06000 0.17410 0.39490 0.00000 Uiso 1.00
171
+ O147 O 0.92700 0.16390 0.36630 0.00000 Uiso 1.00
172
+ Na148 Na 0.73579 0.31238 0.19330 0.00000 Uiso 1.00
173
+ Na149 Na 0.88750 0.93394 0.31347 0.00000 Uiso 1.00
174
+ Na150 Na 0.85635 0.19124 0.18888 0.00000 Uiso 1.00
175
+ Si151 Si 0.75091 0.93741 0.75051 0.00000 Uiso 1.00
176
+ O152 O 0.62703 0.12754 0.99976 0.00000 Uiso 1.00
177
+ O153 O 0.68918 0.89301 0.68477 0.00000 Uiso 1.00
178
+ O154 O 0.56222 0.64160 0.81394 0.00000 Uiso 1.00
179
+ O155 O 0.46951 0.23343 0.81351 0.00000 Uiso 1.00
180
+ O156 O 0.56085 0.14320 0.81582 0.00000 Uiso 1.00
181
+ O157 O 0.81191 0.89113 0.81438 0.00000 Uiso 1.00
182
+ O158 O 0.78010 0.98388 0.68695 0.00000 Uiso 1.00
183
+ O159 O 0.72229 0.98180 0.81669 0.00000 Uiso 1.00
184
+ O160 O 0.52779 0.73194 0.68373 0.00000 Uiso 1.00
185
+ O161 O 0.75338 0.00209 0.00114 0.00000 Uiso 1.00
186
+ O162 O 0.50206 0.74711 0.49945 0.00000 Uiso 1.00
187
+ O163 O 0.87799 0.87780 0.00081 0.00000 Uiso 1.00
188
+ Cu164 Cu 0.62639 0.62672 0.49867 0.00000 Uiso 1.00
189
+ Si165 Si 0.74238 0.03875 0.89661 0.00000 Uiso 1.00
190
+ Si166 Si 0.63794 0.14302 0.89614 0.00000 Uiso 1.00
191
+ Si167 Si 0.81580 0.98011 0.60487 0.00000 Uiso 1.00
192
+ Si168 Si 0.56486 0.73161 0.60369 0.00000 Uiso 1.00
193
+ Si169 Si 0.49378 0.28949 0.89573 0.00000 Uiso 1.00
194
+ Si170 Si 0.57889 0.58560 0.89580 0.00000 Uiso 1.00
195
+ Si171 Si 0.88840 0.89500 0.89626 0.00000 Uiso 1.00
196
+ Si172 Si 0.66922 0.83597 0.60429 0.00000 Uiso 1.00
197
+ O173 O 0.60610 0.66807 0.60380 0.00000 Uiso 1.00
198
+ O174 O 0.67190 0.07970 0.86730 0.00000 Uiso 1.00
199
+ O175 O 0.51220 0.54930 0.89550 0.00000 Uiso 1.00
200
+ O176 O 0.61350 0.79460 0.63340 0.00000 Uiso 1.00
201
+ O177 O 0.80640 0.07990 0.89690 0.00000 Uiso 1.00
202
+ O178 O 0.92490 0.96150 0.89610 0.00000 Uiso 1.00
203
+ O179 O 0.86950 0.03960 0.63490 0.00000 Uiso 1.00
204
+ O180 O 0.67910 0.20690 0.89560 0.00000 Uiso 1.00
205
+ O181 O 0.73330 0.79520 0.60460 0.00000 Uiso 1.00
206
+ O182 O 0.85240 0.91346 0.60550 0.00000 Uiso 1.00
207
+ O183 O 0.56000 0.32590 0.89490 0.00000 Uiso 1.00
208
+ O184 O 0.42700 0.33610 0.86630 0.00000 Uiso 1.00
209
+ Na185 Na 0.23579 0.18762 0.69330 0.00000 Uiso 1.00
210
+ Na186 Na 0.38750 0.56606 0.81347 0.00000 Uiso 1.00
211
+ Na187 Na 0.35635 0.30876 0.68888 0.00000 Uiso 1.00
212
+ Si188 Si 0.25091 0.43741 0.75051 0.00000 Uiso 1.00
213
+ O189 O 0.12703 0.62754 0.99976 0.00000 Uiso 1.00
214
+ O190 O 0.18918 0.39301 0.68477 0.00000 Uiso 1.00
215
+ O191 O 0.06222 0.14160 0.81394 0.00000 Uiso 1.00
216
+ O192 O 0.96951 0.73343 0.81351 0.00000 Uiso 1.00
217
+ O193 O 0.06085 0.64320 0.81582 0.00000 Uiso 1.00
218
+ O194 O 0.31191 0.39113 0.81438 0.00000 Uiso 1.00
219
+ O195 O 0.28010 0.48388 0.68695 0.00000 Uiso 1.00
220
+ O196 O 0.22229 0.48180 0.81669 0.00000 Uiso 1.00
221
+ O197 O 0.02779 0.23194 0.68373 0.00000 Uiso 1.00
222
+ O198 O 0.25338 0.50209 0.00114 0.00000 Uiso 1.00
223
+ O199 O 0.00206 0.24711 0.49945 0.00000 Uiso 1.00
224
+ O200 O 0.37799 0.37780 0.00081 0.00000 Uiso 1.00
225
+ Cu201 Cu 0.12639 0.12672 0.49867 0.00000 Uiso 1.00
226
+ Si202 Si 0.24238 0.53875 0.89661 0.00000 Uiso 1.00
227
+ Si203 Si 0.13794 0.64302 0.89614 0.00000 Uiso 1.00
228
+ Si204 Si 0.31580 0.48011 0.60487 0.00000 Uiso 1.00
229
+ Si205 Si 0.06486 0.23161 0.60369 0.00000 Uiso 1.00
230
+ Si206 Si 0.99378 0.78949 0.89573 0.00000 Uiso 1.00
231
+ Si207 Si 0.07889 0.08560 0.89580 0.00000 Uiso 1.00
232
+ Si208 Si 0.38840 0.39500 0.89626 0.00000 Uiso 1.00
233
+ Si209 Si 0.16922 0.33597 0.60429 0.00000 Uiso 1.00
234
+ O210 O 0.10610 0.16807 0.60380 0.00000 Uiso 1.00
235
+ O211 O 0.17190 0.57970 0.86730 0.00000 Uiso 1.00
236
+ O212 O 0.01220 0.04930 0.89550 0.00000 Uiso 1.00
237
+ O213 O 0.11350 0.29460 0.63340 0.00000 Uiso 1.00
238
+ O214 O 0.30640 0.57990 0.89690 0.00000 Uiso 1.00
239
+ O215 O 0.42490 0.46150 0.89610 0.00000 Uiso 1.00
240
+ O216 O 0.36950 0.53960 0.63490 0.00000 Uiso 1.00
241
+ O217 O 0.17910 0.70690 0.89560 0.00000 Uiso 1.00
242
+ O218 O 0.23330 0.29520 0.60460 0.00000 Uiso 1.00
243
+ O219 O 0.35240 0.41346 0.60550 0.00000 Uiso 1.00
244
+ O220 O 0.06000 0.82590 0.89490 0.00000 Uiso 1.00
245
+ O221 O 0.92700 0.83610 0.86630 0.00000 Uiso 1.00
246
+ Na222 Na 0.73579 0.68762 0.69330 0.00000 Uiso 1.00
247
+ Na223 Na 0.88750 0.06606 0.81347 0.00000 Uiso 1.00
248
+ Na224 Na 0.85635 0.80876 0.68888 0.00000 Uiso 1.00
249
+ Na225 Na 0.01010 0.43710 0.79050 0.00000 Uiso 1.00
250
+ Si226 Si 0.24909 0.93741 0.74949 0.00000 Uiso 1.00
251
+ O227 O 0.37297 0.12754 0.50024 0.00000 Uiso 1.00
252
+ O228 O 0.31082 0.89301 0.81523 0.00000 Uiso 1.00
253
+ O229 O 0.43778 0.64160 0.68606 0.00000 Uiso 1.00
254
+ O230 O 0.53049 0.23343 0.68649 0.00000 Uiso 1.00
255
+ O231 O 0.43915 0.14320 0.68418 0.00000 Uiso 1.00
256
+ O232 O 0.18809 0.89113 0.68562 0.00000 Uiso 1.00
257
+ O233 O 0.21990 0.98388 0.81305 0.00000 Uiso 1.00
258
+ O234 O 0.27771 0.98180 0.68331 0.00000 Uiso 1.00
259
+ O235 O 0.47221 0.73194 0.81627 0.00000 Uiso 1.00
260
+ O236 O 0.24662 0.00209 0.49886 0.00000 Uiso 1.00
261
+ O237 O 0.49794 0.74711 0.00055 0.00000 Uiso 1.00
262
+ O238 O 0.12201 0.87780 0.49919 0.00000 Uiso 1.00
263
+ Cu239 Cu 0.37361 0.62672 0.00133 0.00000 Uiso 1.00
264
+ Si240 Si 0.25762 0.03875 0.60339 0.00000 Uiso 1.00
265
+ Si241 Si 0.36206 0.14302 0.60386 0.00000 Uiso 1.00
266
+ Si242 Si 0.18420 0.98011 0.89513 0.00000 Uiso 1.00
267
+ Si243 Si 0.43514 0.73161 0.89631 0.00000 Uiso 1.00
268
+ Si244 Si 0.50622 0.28949 0.60427 0.00000 Uiso 1.00
269
+ Si245 Si 0.42111 0.58560 0.60420 0.00000 Uiso 1.00
270
+ Si246 Si 0.11160 0.89500 0.60374 0.00000 Uiso 1.00
271
+ Si247 Si 0.33078 0.83597 0.89571 0.00000 Uiso 1.00
272
+ O248 O 0.39390 0.66807 0.89620 0.00000 Uiso 1.00
273
+ O249 O 0.32810 0.07970 0.63270 0.00000 Uiso 1.00
274
+ O250 O 0.48780 0.54930 0.60450 0.00000 Uiso 1.00
275
+ O251 O 0.38650 0.79460 0.86660 0.00000 Uiso 1.00
276
+ O252 O 0.19360 0.07990 0.60310 0.00000 Uiso 1.00
277
+ O253 O 0.07510 0.96150 0.60390 0.00000 Uiso 1.00
278
+ O254 O 0.13050 0.03960 0.86510 0.00000 Uiso 1.00
279
+ O255 O 0.32090 0.20690 0.60440 0.00000 Uiso 1.00
280
+ O256 O 0.26670 0.79520 0.89540 0.00000 Uiso 1.00
281
+ O257 O 0.14760 0.91346 0.89450 0.00000 Uiso 1.00
282
+ O258 O 0.44000 0.32590 0.60510 0.00000 Uiso 1.00
283
+ O259 O 0.57300 0.33610 0.63370 0.00000 Uiso 1.00
284
+ Na260 Na 0.76421 0.18762 0.80670 0.00000 Uiso 1.00
285
+ Na261 Na 0.61250 0.56606 0.68653 0.00000 Uiso 1.00
286
+ Na262 Na 0.64365 0.30876 0.81112 0.00000 Uiso 1.00
287
+ Na263 Na 0.48990 0.93710 0.70950 0.00000 Uiso 1.00
288
+ Si264 Si 0.74909 0.43741 0.74949 0.00000 Uiso 1.00
289
+ O265 O 0.87297 0.62754 0.50024 0.00000 Uiso 1.00
290
+ O266 O 0.81082 0.39301 0.81523 0.00000 Uiso 1.00
291
+ O267 O 0.93778 0.14160 0.68606 0.00000 Uiso 1.00
292
+ O268 O 0.03049 0.73343 0.68649 0.00000 Uiso 1.00
293
+ O269 O 0.93915 0.64320 0.68418 0.00000 Uiso 1.00
294
+ O270 O 0.68809 0.39113 0.68562 0.00000 Uiso 1.00
295
+ O271 O 0.71990 0.48388 0.81305 0.00000 Uiso 1.00
296
+ O272 O 0.77771 0.48180 0.68331 0.00000 Uiso 1.00
297
+ O273 O 0.97221 0.23194 0.81627 0.00000 Uiso 1.00
298
+ O274 O 0.74662 0.50209 0.49886 0.00000 Uiso 1.00
299
+ O275 O 0.99794 0.24711 0.00055 0.00000 Uiso 1.00
300
+ O276 O 0.62201 0.37780 0.49919 0.00000 Uiso 1.00
301
+ Cu277 Cu 0.87361 0.12672 0.00133 0.00000 Uiso 1.00
302
+ Si278 Si 0.75762 0.53875 0.60339 0.00000 Uiso 1.00
303
+ Si279 Si 0.86206 0.64302 0.60386 0.00000 Uiso 1.00
304
+ Si280 Si 0.68420 0.48011 0.89513 0.00000 Uiso 1.00
305
+ Si281 Si 0.93514 0.23161 0.89631 0.00000 Uiso 1.00
306
+ Si282 Si 0.00622 0.78949 0.60427 0.00000 Uiso 1.00
307
+ Si283 Si 0.92111 0.08560 0.60420 0.00000 Uiso 1.00
308
+ Si284 Si 0.61160 0.39500 0.60374 0.00000 Uiso 1.00
309
+ Si285 Si 0.83078 0.33597 0.89571 0.00000 Uiso 1.00
310
+ O286 O 0.89390 0.16807 0.89620 0.00000 Uiso 1.00
311
+ O287 O 0.82810 0.57970 0.63270 0.00000 Uiso 1.00
312
+ O288 O 0.98780 0.04930 0.60450 0.00000 Uiso 1.00
313
+ O289 O 0.88650 0.29460 0.86660 0.00000 Uiso 1.00
314
+ O290 O 0.69360 0.57990 0.60310 0.00000 Uiso 1.00
315
+ O291 O 0.57510 0.46150 0.60390 0.00000 Uiso 1.00
316
+ O292 O 0.63050 0.53960 0.86510 0.00000 Uiso 1.00
317
+ O293 O 0.82090 0.70690 0.60440 0.00000 Uiso 1.00
318
+ O294 O 0.76670 0.29520 0.89540 0.00000 Uiso 1.00
319
+ O295 O 0.64760 0.41346 0.89450 0.00000 Uiso 1.00
320
+ O296 O 0.94000 0.82590 0.60510 0.00000 Uiso 1.00
321
+ O297 O 0.07300 0.83610 0.63370 0.00000 Uiso 1.00
322
+ Na298 Na 0.26421 0.68762 0.80670 0.00000 Uiso 1.00
323
+ Na299 Na 0.11250 0.06606 0.68653 0.00000 Uiso 1.00
324
+ Na300 Na 0.14365 0.80876 0.81112 0.00000 Uiso 1.00
325
+ Si301 Si 0.50000 0.31328 0.25000 0.00000 Uiso 1.00
326
+ Si302 Si 0.50000 0.81163 0.25000 0.00000 Uiso 1.00
327
+ Na303 Na 0.50000 0.56280 0.25000 0.00000 Uiso 1.00
328
+ Si304 Si 0.00000 0.81328 0.25000 0.00000 Uiso 1.00
329
+ Si305 Si 0.00000 0.31163 0.25000 0.00000 Uiso 1.00
330
+ Na306 Na 0.00000 0.06280 0.25000 0.00000 Uiso 1.00
331
+ Si307 Si 0.50000 0.68672 0.75000 0.00000 Uiso 1.00
332
+ Si308 Si 0.50000 0.18837 0.75000 0.00000 Uiso 1.00
333
+ Na309 Na 0.50000 0.43720 0.75000 0.00000 Uiso 1.00
334
+ Si310 Si -0.00000 0.18672 0.75000 0.00000 Uiso 1.00
335
+ Si311 Si -0.00000 0.68837 0.75000 0.00000 Uiso 1.00
336
+ Na312 Na -0.00000 0.93720 0.75000 0.00000 Uiso 1.00
337
+ Cu313 Cu 0.25000 0.75000 -0.00000 0.00000 Uiso 1.00
338
+ Cu314 Cu 0.75000 0.75000 0.50000 0.00000 Uiso 1.00
339
+ Cu315 Cu 0.25000 0.25000 0.50000 0.00000 Uiso 1.00
340
+ Cu316 Cu 0.75000 0.25000 0.00000 0.00000 Uiso 1.00
341
+ Cu317 Cu 0.50000 0.50000 -0.00000 0.00000 Uiso 1.00
342
+ Cu318 Cu 0.00000 0.00000 0.00000 0.00000 Uiso 1.00
343
+ Cu319 Cu 0.50000 0.50000 0.50000 0.00000 Uiso 1.00
344
+ Cu320 Cu 0.00000 0.00000 0.50000 0.00000 Uiso 1.00
345
+ loop_
346
+ _geom_bond_atom_site_label_1
347
+ _geom_bond_atom_site_label_2
348
+ _geom_bond_distance
349
+ _geom_bond_site_symmetry_2
350
+ _ccdc_geom_bond_type
351
+ Si1 O3 1.600 . S
352
+ Si1 O7 1.606 . S
353
+ Si1 O8 1.606 . S
354
+ Si1 O9 1.602 . S
355
+ O2 Si16 1.649 . S
356
+ O2 Si247 1.659 1_554 S
357
+ O3 Si22 1.623 . S
358
+ O4 Si20 1.622 . S
359
+ O4 Si301 1.607 . S
360
+ O5 Si19 1.626 . S
361
+ O5 Si302 1.604 . S
362
+ O6 Si16 1.621 . S
363
+ O6 Si302 1.599 . S
364
+ O7 Si21 1.623 . S
365
+ O8 Si17 1.627 . S
366
+ O9 Si15 1.616 1_545 S
367
+ O10 Si18 1.619 . S
368
+ O10 Si301 1.603 . S
369
+ O11 Si15 1.657 1_556 S
370
+ O11 Si242 1.658 . S
371
+ O12 Si18 1.656 . S
372
+ O12 Si244 1.658 . S
373
+ O13 Si21 1.665 1_556 S
374
+ O13 Si207 1.652 . S
375
+ Cu14 O23 1.941 . S
376
+ Cu14 O219 1.928 . S
377
+ Cu14 Na187 3.199 . S
378
+ Cu14 O258 1.928 . S
379
+ Cu14 Na111 3.141 . S
380
+ Cu14 O140 1.935 . S
381
+ Cu14 Na72 3.220 . S
382
+ Si15 O11 1.657 1_554 S
383
+ Si15 O9 1.616 1_565 S
384
+ Si15 O24 1.618 . S
385
+ Si15 O27 1.583 . S
386
+ Si16 O24 1.622 . S
387
+ Si16 O30 1.584 . S
388
+ Si17 O29 1.622 1_545 S
389
+ Si17 O32 1.582 . S
390
+ Si17 O236 1.658 . S
391
+ Si18 O23 1.577 . S
392
+ Si18 O26 1.620 . S
393
+ Si19 O33 1.577 . S
394
+ Si19 O34 1.624 . S
395
+ Si19 O237 1.658 . S
396
+ Si20 O25 1.579 . S
397
+ Si20 O200 1.652 . S
398
+ Si20 O142 1.618 . S
399
+ Si21 O13 1.665 1_554 S
400
+ Si21 O28 1.580 . S
401
+ Si21 O71 1.611 . S
402
+ Si22 O26 1.619 . S
403
+ Si22 O31 1.580 . S
404
+ Si22 O227 1.659 . S
405
+ O23 Na72 2.583 . S
406
+ O23 Na111 2.427 . S
407
+ O25 Na36 2.470 . S
408
+ O25 Cu317 1.937 . S
409
+ O27 Cu127 1.935 1_554 S
410
+ O27 Na73 2.430 . S
411
+ O27 Na110 2.595 . S
412
+ O28 Cu318 1.931 . S
413
+ O28 Na73 2.480 1_545 S
414
+ O29 Si17 1.622 1_565 S
415
+ O29 Si133 1.618 . S
416
+ O29 Na73 2.576 . S
417
+ O30 Cu313 1.933 . S
418
+ O30 Na110 2.578 . S
419
+ O30 Na112 2.436 . S
420
+ O31 Cu315 1.936 . S
421
+ O31 Na72 2.583 . S
422
+ O31 Na74 2.435 . S
423
+ O32 Cu201 1.928 . S
424
+ O32 Na74 2.488 . S
425
+ O33 Cu239 1.928 . S
426
+ O33 Na112 2.489 . S
427
+ O34 Na37 2.564 . S
428
+ O34 Si58 1.611 . S
429
+ Na35 Na37 3.575 . S
430
+ Na35 Cu51 3.220 . S
431
+ Na35 O60 2.583 . S
432
+ Na35 O102 2.595 . S
433
+ Na35 O105 2.578 . S
434
+ Na35 O68 2.583 . S
435
+ Na35 Na149 3.581 . S
436
+ Na35 Cu314 3.231 . S
437
+ Na36 Cu317 3.217 . S
438
+ Na36 Cu89 3.141 1_554 S
439
+ Na36 O98 2.427 . S
440
+ Na36 O64 2.430 . S
441
+ Na36 O65 2.480 . S
442
+ Na36 O66 2.576 . S
443
+ Na36 Na148 3.581 . S
444
+ Na37 Cu164 3.199 . S
445
+ Na37 O105 2.436 . S
446
+ Na37 O68 2.435 . S
447
+ Na37 O69 2.488 . S
448
+ Na37 O108 2.489 . S
449
+ Na37 Cu314 3.123 . S
450
+ Si38 O40 1.600 . S
451
+ Si38 O44 1.606 . S
452
+ Si38 O45 1.606 . S
453
+ Si38 O46 1.602 . S
454
+ O39 Si53 1.649 . S
455
+ O39 Si285 1.659 1_554 S
456
+ O40 Si59 1.623 . S
457
+ O41 Si57 1.622 . S
458
+ O41 Si304 1.607 1_655 S
459
+ O42 Si56 1.626 . S
460
+ O42 Si305 1.604 . S
461
+ O43 Si53 1.621 . S
462
+ O43 Si305 1.599 1_655 S
463
+ O44 Si58 1.623 . S
464
+ O45 Si54 1.627 . S
465
+ O46 Si52 1.616 . S
466
+ O47 Si55 1.619 . S
467
+ O47 Si304 1.603 1_655 S
468
+ O48 Si52 1.657 1_556 S
469
+ O48 Si280 1.658 . S
470
+ O49 Si55 1.656 . S
471
+ O49 Si282 1.658 1_655 S
472
+ O50 Si58 1.665 1_556 S
473
+ O50 Si170 1.652 . S
474
+ Cu51 O60 1.941 . S
475
+ Cu51 O182 1.928 . S
476
+ Cu51 Na224 3.199 . S
477
+ Cu51 O296 1.928 . S
478
+ Cu51 Na149 3.141 . S
479
+ Cu51 O102 1.935 . S
480
+ Si52 O48 1.657 1_554 S
481
+ Si52 O61 1.618 . S
482
+ Si52 O64 1.583 . S
483
+ Si53 O61 1.622 . S
484
+ Si53 O67 1.584 . S
485
+ Si54 O66 1.622 . S
486
+ Si54 O69 1.582 . S
487
+ Si54 O274 1.658 . S
488
+ Si55 O60 1.577 . S
489
+ Si55 O63 1.620 . S
490
+ Si56 O70 1.577 1_455 S
491
+ Si56 O71 1.624 . S
492
+ Si56 O275 1.658 1_455 S
493
+ Si57 O62 1.579 . S
494
+ Si57 O163 1.652 . S
495
+ Si57 O104 1.618 . S
496
+ Si58 O50 1.665 1_554 S
497
+ Si58 O65 1.580 . S
498
+ Si59 O63 1.619 . S
499
+ Si59 O68 1.580 . S
500
+ Si59 O265 1.659 . S
501
+ O60 Na149 2.427 . S
502
+ O62 Na73 2.470 1_655 S
503
+ O62 Cu318 1.937 1_665 S
504
+ O64 Cu89 1.935 1_554 S
505
+ O64 Na148 2.595 . S
506
+ O65 Cu317 1.931 . S
507
+ O66 Si95 1.618 . S
508
+ O67 Cu316 1.933 . S
509
+ O67 Na148 2.578 . S
510
+ O67 Na150 2.436 . S
511
+ O68 Cu314 1.936 . S
512
+ O69 Cu164 1.928 . S
513
+ O70 Si56 1.577 1_655 S
514
+ O70 Cu277 1.928 . S
515
+ O70 Na150 2.489 . S
516
+ O71 Na74 2.564 . S
517
+ Na72 Na74 3.575 . S
518
+ Na72 O140 2.595 . S
519
+ Na72 O143 2.578 . S
520
+ Na72 Na111 3.581 . S
521
+ Na72 Cu315 3.231 . S
522
+ Na73 O62 2.470 1_455 S
523
+ Na73 Cu318 3.217 1_565 S
524
+ Na73 Cu127 3.141 1_554 S
525
+ Na73 O136 2.427 . S
526
+ Na73 O28 2.480 1_565 S
527
+ Na73 Na110 3.581 . S
528
+ Na74 Cu201 3.199 . S
529
+ Na74 O143 2.436 . S
530
+ Na74 O146 2.489 . S
531
+ Na74 Cu315 3.123 . S
532
+ Si76 O78 1.600 . S
533
+ Si76 O82 1.606 . S
534
+ Si76 O83 1.606 . S
535
+ Si76 O84 1.602 . S
536
+ O77 Si91 1.649 . S
537
+ O77 Si172 1.659 . S
538
+ O78 Si97 1.623 . S
539
+ O79 Si95 1.622 . S
540
+ O79 Si301 1.607 . S
541
+ O80 Si94 1.626 . S
542
+ O80 Si302 1.604 . S
543
+ O81 Si91 1.621 . S
544
+ O81 Si302 1.599 . S
545
+ O82 Si96 1.623 . S
546
+ O83 Si92 1.627 . S
547
+ O84 Si90 1.616 1_545 S
548
+ O85 Si93 1.619 . S
549
+ O85 Si301 1.603 . S
550
+ O86 Si90 1.657 . S
551
+ O86 Si167 1.658 . S
552
+ O87 Si93 1.656 1_556 S
553
+ O87 Si169 1.658 . S
554
+ O88 Si96 1.665 . S
555
+ O88 Si283 1.652 . S
556
+ Cu89 O98 1.941 1_556 S
557
+ Cu89 O295 1.928 . S
558
+ Cu89 Na262 3.199 . S
559
+ Cu89 O183 1.928 . S
560
+ Cu89 Na36 3.141 1_556 S
561
+ Cu89 O64 1.935 1_556 S
562
+ Cu89 Na148 3.220 1_556 S
563
+ Si90 O84 1.616 1_565 S
564
+ Si90 O99 1.618 . S
565
+ Si90 O102 1.583 . S
566
+ Si91 O99 1.622 . S
567
+ Si91 O105 1.584 . S
568
+ Si92 O104 1.622 1_545 S
569
+ Si92 O107 1.582 . S
570
+ Si92 O161 1.658 . S
571
+ Si93 O87 1.656 1_554 S
572
+ Si93 O98 1.577 . S
573
+ Si93 O101 1.620 . S
574
+ Si94 O108 1.577 . S
575
+ Si94 O109 1.624 . S
576
+ Si94 O162 1.658 . S
577
+ Si95 O100 1.579 . S
578
+ Si95 O276 1.652 . S
579
+ Si96 O103 1.580 . S
580
+ Si96 O147 1.611 . S
581
+ Si97 O101 1.619 . S
582
+ Si97 O106 1.580 . S
583
+ Si97 O152 1.659 1_554 S
584
+ O98 Cu89 1.941 1_554 S
585
+ O98 Na148 2.583 . S
586
+ O100 Na111 2.470 . S
587
+ O100 Cu319 1.937 . S
588
+ O102 Na149 2.430 . S
589
+ O103 Cu320 1.931 1_655 S
590
+ O103 Na149 2.480 1_545 S
591
+ O104 Si92 1.622 1_565 S
592
+ O104 Na149 2.576 . S
593
+ O105 Cu314 1.933 . S
594
+ O106 Cu316 1.936 . S
595
+ O106 Na148 2.583 . S
596
+ O106 Na150 2.435 . S
597
+ O107 Cu277 1.928 . S
598
+ O107 Na150 2.488 . S
599
+ O108 Cu164 1.928 . S
600
+ O109 Na112 2.564 . S
601
+ O109 Si134 1.611 . S
602
+ Na110 Na112 3.575 . S
603
+ Na110 Cu127 3.220 1_554 S
604
+ Na110 O136 2.583 . S
605
+ Na110 O144 2.583 . S
606
+ Na110 Cu313 3.231 . S
607
+ Na111 Cu319 3.217 . S
608
+ Na111 O140 2.430 . S
609
+ Na111 O141 2.480 . S
610
+ Na111 O142 2.576 . S
611
+ Na112 Cu239 3.199 . S
612
+ Na112 O144 2.435 . S
613
+ Na112 O145 2.488 . S
614
+ Na112 Cu313 3.123 . S
615
+ Si114 O116 1.600 . S
616
+ Si114 O120 1.606 . S
617
+ Si114 O121 1.606 . S
618
+ Si114 O122 1.602 . S
619
+ O115 Si129 1.649 . S
620
+ O115 Si209 1.659 . S
621
+ O116 Si135 1.623 . S
622
+ O117 Si133 1.622 . S
623
+ O117 Si304 1.607 . S
624
+ O118 Si132 1.626 . S
625
+ O118 Si305 1.604 1_655 S
626
+ O119 Si129 1.621 . S
627
+ O119 Si305 1.599 . S
628
+ O120 Si134 1.623 . S
629
+ O121 Si130 1.627 . S
630
+ O122 Si128 1.616 . S
631
+ O123 Si131 1.619 . S
632
+ O123 Si304 1.603 . S
633
+ O124 Si128 1.657 . S
634
+ O124 Si204 1.658 . S
635
+ O125 Si131 1.656 1_556 S
636
+ O125 Si206 1.658 1_455 S
637
+ O126 Si134 1.665 . S
638
+ O126 Si245 1.652 . S
639
+ Cu127 O136 1.941 1_556 S
640
+ Cu127 O257 1.928 . S
641
+ Cu127 Na300 3.199 . S
642
+ Cu127 O220 1.928 . S
643
+ Cu127 Na73 3.141 1_556 S
644
+ Cu127 O27 1.935 1_556 S
645
+ Cu127 Na110 3.220 1_556 S
646
+ Si128 O137 1.618 . S
647
+ Si128 O140 1.583 . S
648
+ Si129 O137 1.622 . S
649
+ Si129 O143 1.584 . S
650
+ Si130 O142 1.622 . S
651
+ Si130 O145 1.582 . S
652
+ Si130 O198 1.658 . S
653
+ Si131 O125 1.656 1_554 S
654
+ Si131 O136 1.577 . S
655
+ Si131 O139 1.620 . S
656
+ Si132 O146 1.577 1_655 S
657
+ Si132 O147 1.624 . S
658
+ Si132 O199 1.658 1_655 S
659
+ Si133 O138 1.579 . S
660
+ Si133 O238 1.652 . S
661
+ Si134 O141 1.580 . S
662
+ Si135 O139 1.619 . S
663
+ Si135 O144 1.580 . S
664
+ Si135 O189 1.659 1_554 S
665
+ O136 Cu127 1.941 1_554 S
666
+ O138 Na149 2.470 1_455 S
667
+ O138 Cu320 1.937 1_565 S
668
+ O141 Cu319 1.931 . S
669
+ O143 Cu315 1.933 . S
670
+ O144 Cu313 1.936 . S
671
+ O145 Cu239 1.928 . S
672
+ O146 Si132 1.577 1_455 S
673
+ O146 Cu201 1.928 . S
674
+ O147 Na150 2.564 . S
675
+ Na148 Na150 3.575 . S
676
+ Na148 Cu89 3.220 1_554 S
677
+ Na148 Cu316 3.231 . S
678
+ Na149 O138 2.470 1_655 S
679
+ Na149 Cu320 3.217 1_665 S
680
+ Na149 O103 2.480 1_565 S
681
+ Na150 Cu277 3.199 . S
682
+ Na150 Cu316 3.123 . S
683
+ Si151 O153 1.600 . S
684
+ Si151 O157 1.606 . S
685
+ Si151 O158 1.606 . S
686
+ Si151 O159 1.602 . S
687
+ O152 Si166 1.649 . S
688
+ O152 Si97 1.659 1_556 S
689
+ O153 Si172 1.623 . S
690
+ O154 Si170 1.622 . S
691
+ O154 Si307 1.607 . S
692
+ O155 Si169 1.626 . S
693
+ O155 Si308 1.604 . S
694
+ O156 Si166 1.621 . S
695
+ O156 Si308 1.599 . S
696
+ O157 Si171 1.623 . S
697
+ O158 Si167 1.627 . S
698
+ O159 Si165 1.616 1_565 S
699
+ O160 Si168 1.619 . S
700
+ O160 Si307 1.603 . S
701
+ O161 Si165 1.657 1_554 S
702
+ O162 Si168 1.656 . S
703
+ O163 Si171 1.665 1_554 S
704
+ Cu164 O173 1.941 . S
705
+ Cu164 Na261 3.141 . S
706
+ Cu164 O290 1.935 . S
707
+ Cu164 Na222 3.220 . S
708
+ Si165 O161 1.657 1_556 S
709
+ Si165 O159 1.616 1_545 S
710
+ Si165 O174 1.618 . S
711
+ Si165 O177 1.583 . S
712
+ Si166 O174 1.622 . S
713
+ Si166 O180 1.584 . S
714
+ Si167 O179 1.622 1_565 S
715
+ Si167 O182 1.582 . S
716
+ Si168 O173 1.577 . S
717
+ Si168 O176 1.620 . S
718
+ Si169 O183 1.577 . S
719
+ Si169 O184 1.624 . S
720
+ Si170 O175 1.579 . S
721
+ Si170 O292 1.618 . S
722
+ Si171 O163 1.665 1_556 S
723
+ Si171 O178 1.580 . S
724
+ Si171 O221 1.611 . S
725
+ Si172 O176 1.619 . S
726
+ Si172 O181 1.580 . S
727
+ O173 Na222 2.583 . S
728
+ O173 Na261 2.427 . S
729
+ O175 Na186 2.470 . S
730
+ O175 Cu317 1.937 1_556 S
731
+ O177 Cu277 1.935 1_556 S
732
+ O177 Na223 2.430 . S
733
+ O177 Na260 2.595 . S
734
+ O178 Cu318 1.931 1_666 S
735
+ O178 Na223 2.480 1_565 S
736
+ O179 Si167 1.622 1_545 S
737
+ O179 Si283 1.618 . S
738
+ O179 Na223 2.576 . S
739
+ O180 Cu316 1.933 1_556 S
740
+ O180 Na260 2.578 . S
741
+ O180 Na262 2.436 . S
742
+ O181 Cu314 1.936 . S
743
+ O181 Na222 2.583 . S
744
+ O181 Na224 2.435 . S
745
+ O182 Na224 2.488 . S
746
+ O183 Na262 2.489 . S
747
+ O184 Na187 2.564 . S
748
+ O184 Si208 1.611 . S
749
+ Na185 Na187 3.575 . S
750
+ Na185 Cu201 3.220 . S
751
+ Na185 O210 2.583 . S
752
+ Na185 O252 2.595 . S
753
+ Na185 O255 2.578 . S
754
+ Na185 O218 2.583 . S
755
+ Na185 Na299 3.581 . S
756
+ Na185 Cu315 3.231 . S
757
+ Na186 Cu317 3.217 1_556 S
758
+ Na186 Cu239 3.141 1_556 S
759
+ Na186 O248 2.427 . S
760
+ Na186 O214 2.430 . S
761
+ Na186 O215 2.480 . S
762
+ Na186 O216 2.576 . S
763
+ Na186 Na298 3.581 . S
764
+ Na187 O255 2.436 . S
765
+ Na187 O218 2.435 . S
766
+ Na187 O219 2.488 . S
767
+ Na187 O258 2.489 . S
768
+ Na187 Cu315 3.123 . S
769
+ Si188 O190 1.600 . S
770
+ Si188 O194 1.606 . S
771
+ Si188 O195 1.606 . S
772
+ Si188 O196 1.602 . S
773
+ O189 Si203 1.649 . S
774
+ O189 Si135 1.659 1_556 S
775
+ O190 Si209 1.623 . S
776
+ O191 Si207 1.622 . S
777
+ O191 Si310 1.607 . S
778
+ O192 Si206 1.626 . S
779
+ O192 Si311 1.604 1_655 S
780
+ O193 Si203 1.621 . S
781
+ O193 Si311 1.599 . S
782
+ O194 Si208 1.623 . S
783
+ O195 Si204 1.627 . S
784
+ O196 Si202 1.616 . S
785
+ O197 Si205 1.619 . S
786
+ O197 Si310 1.603 . S
787
+ O198 Si202 1.657 1_554 S
788
+ O199 Si205 1.656 . S
789
+ O199 Si132 1.658 1_455 S
790
+ O200 Si208 1.665 1_554 S
791
+ Cu201 O210 1.941 . S
792
+ Cu201 Na299 3.141 . S
793
+ Cu201 O252 1.935 . S
794
+ Si202 O198 1.657 1_556 S
795
+ Si202 O211 1.618 . S
796
+ Si202 O214 1.583 . S
797
+ Si203 O211 1.622 . S
798
+ Si203 O217 1.584 . S
799
+ Si204 O216 1.622 . S
800
+ Si204 O219 1.582 . S
801
+ Si205 O210 1.577 . S
802
+ Si205 O213 1.620 . S
803
+ Si206 O220 1.577 1_655 S
804
+ Si206 O221 1.624 . S
805
+ Si206 O125 1.658 1_655 S
806
+ Si207 O212 1.579 . S
807
+ Si207 O254 1.618 . S
808
+ Si208 O200 1.665 1_556 S
809
+ Si208 O215 1.580 . S
810
+ Si209 O213 1.619 . S
811
+ Si209 O218 1.580 . S
812
+ O210 Na299 2.427 . S
813
+ O212 Na223 2.470 1_455 S
814
+ O212 Cu318 1.937 1_556 S
815
+ O214 Cu239 1.935 1_556 S
816
+ O214 Na298 2.595 . S
817
+ O215 Cu317 1.931 1_556 S
818
+ O216 Si245 1.618 . S
819
+ O217 Cu313 1.933 1_556 S
820
+ O217 Na298 2.578 . S
821
+ O217 Na300 2.436 . S
822
+ O218 Cu315 1.936 . S
823
+ O220 Si206 1.577 1_455 S
824
+ O220 Na300 2.489 . S
825
+ O221 Na224 2.564 . S
826
+ Na222 Na224 3.575 . S
827
+ Na222 O290 2.595 . S
828
+ Na222 O293 2.578 . S
829
+ Na222 Na261 3.581 . S
830
+ Na222 Cu314 3.231 . S
831
+ Na223 O212 2.470 1_655 S
832
+ Na223 Cu318 3.217 1_656 S
833
+ Na223 Cu277 3.141 1_556 S
834
+ Na223 O286 2.427 . S
835
+ Na223 O178 2.480 1_545 S
836
+ Na223 Na260 3.581 . S
837
+ Na224 O293 2.436 . S
838
+ Na224 O296 2.489 . S
839
+ Na224 Cu314 3.123 . S
840
+ Si226 O228 1.600 . S
841
+ Si226 O232 1.606 . S
842
+ Si226 O233 1.606 . S
843
+ Si226 O234 1.602 . S
844
+ O227 Si241 1.649 . S
845
+ O228 Si247 1.623 . S
846
+ O229 Si245 1.622 . S
847
+ O229 Si307 1.607 . S
848
+ O230 Si244 1.626 . S
849
+ O230 Si308 1.604 . S
850
+ O231 Si241 1.621 . S
851
+ O231 Si308 1.599 . S
852
+ O232 Si246 1.623 . S
853
+ O233 Si242 1.627 . S
854
+ O234 Si240 1.616 1_565 S
855
+ O235 Si243 1.619 . S
856
+ O235 Si307 1.603 . S
857
+ O236 Si240 1.657 . S
858
+ O237 Si243 1.656 1_554 S
859
+ O238 Si246 1.665 . S
860
+ Cu239 O248 1.941 1_554 S
861
+ Cu239 Na186 3.141 1_554 S
862
+ Cu239 O214 1.935 1_554 S
863
+ Cu239 Na298 3.220 1_554 S
864
+ Si240 O234 1.616 1_545 S
865
+ Si240 O249 1.618 . S
866
+ Si240 O252 1.583 . S
867
+ Si241 O249 1.622 . S
868
+ Si241 O255 1.584 . S
869
+ Si242 O254 1.622 1_565 S
870
+ Si242 O257 1.582 . S
871
+ Si243 O237 1.656 1_556 S
872
+ Si243 O248 1.577 . S
873
+ Si243 O251 1.620 . S
874
+ Si244 O258 1.577 . S
875
+ Si244 O259 1.624 . S
876
+ Si245 O250 1.579 . S
877
+ Si246 O253 1.580 . S
878
+ Si246 O297 1.611 . S
879
+ Si247 O251 1.619 . S
880
+ Si247 O256 1.580 . S
881
+ Si247 O2 1.659 1_556 S
882
+ O248 Cu239 1.941 1_556 S
883
+ O248 Na298 2.583 . S
884
+ O250 Na261 2.470 . S
885
+ O250 Cu319 1.937 . S
886
+ O252 Na299 2.430 . S
887
+ O253 Cu320 1.931 1_565 S
888
+ O253 Na299 2.480 1_565 S
889
+ O254 Si242 1.622 1_545 S
890
+ O254 Na299 2.576 . S
891
+ O255 Cu315 1.933 . S
892
+ O256 Cu313 1.936 1_556 S
893
+ O256 Na298 2.583 . S
894
+ O256 Na300 2.435 . S
895
+ O257 Na300 2.488 . S
896
+ O259 Na262 2.564 . S
897
+ O259 Si284 1.611 . S
898
+ Na260 Na262 3.575 . S
899
+ Na260 Cu277 3.220 1_556 S
900
+ Na260 O286 2.583 . S
901
+ Na260 O294 2.583 . S
902
+ Na260 Cu316 3.231 1_556 S
903
+ Na261 Cu319 3.217 . S
904
+ Na261 O290 2.430 . S
905
+ Na261 O291 2.480 . S
906
+ Na261 O292 2.576 . S
907
+ Na262 O294 2.435 . S
908
+ Na262 O295 2.488 . S
909
+ Na262 Cu316 3.123 1_556 S
910
+ Si264 O266 1.600 . S
911
+ Si264 O270 1.606 . S
912
+ Si264 O271 1.606 . S
913
+ Si264 O272 1.602 . S
914
+ O265 Si279 1.649 . S
915
+ O266 Si285 1.623 . S
916
+ O267 Si283 1.622 . S
917
+ O267 Si310 1.607 1_655 S
918
+ O268 Si282 1.626 . S
919
+ O268 Si311 1.604 . S
920
+ O269 Si279 1.621 . S
921
+ O269 Si311 1.599 1_655 S
922
+ O270 Si284 1.623 . S
923
+ O271 Si280 1.627 . S
924
+ O272 Si278 1.616 . S
925
+ O273 Si281 1.619 . S
926
+ O273 Si310 1.603 1_655 S
927
+ O274 Si278 1.657 . S
928
+ O275 Si281 1.656 1_554 S
929
+ O275 Si56 1.658 1_655 S
930
+ O276 Si284 1.665 . S
931
+ Cu277 O286 1.941 1_554 S
932
+ Cu277 Na223 3.141 1_554 S
933
+ Cu277 O177 1.935 1_554 S
934
+ Cu277 Na260 3.220 1_554 S
935
+ Si278 O287 1.618 . S
936
+ Si278 O290 1.583 . S
937
+ Si279 O287 1.622 . S
938
+ Si279 O293 1.584 . S
939
+ Si280 O292 1.622 . S
940
+ Si280 O295 1.582 . S
941
+ Si281 O275 1.656 1_556 S
942
+ Si281 O286 1.577 . S
943
+ Si281 O289 1.620 . S
944
+ Si282 O296 1.577 1_455 S
945
+ Si282 O297 1.624 . S
946
+ Si282 O49 1.658 1_455 S
947
+ Si283 O288 1.579 . S
948
+ Si284 O291 1.580 . S
949
+ Si285 O289 1.619 . S
950
+ Si285 O294 1.580 . S
951
+ Si285 O39 1.659 1_556 S
952
+ O286 Cu277 1.941 1_556 S
953
+ O288 Na299 2.470 1_655 S
954
+ O288 Cu320 1.937 1_655 S
955
+ O291 Cu319 1.931 . S
956
+ O293 Cu314 1.933 . S
957
+ O294 Cu316 1.936 1_556 S
958
+ O296 Si282 1.577 1_655 S
959
+ O297 Na300 2.564 . S
960
+ Na298 Na300 3.575 . S
961
+ Na298 Cu239 3.220 1_556 S
962
+ Na298 Cu313 3.231 1_556 S
963
+ Na299 O288 2.470 1_455 S
964
+ Na299 Cu320 3.217 . S
965
+ Na299 O253 2.480 1_545 S
966
+ Na300 Cu313 3.123 1_556 S
967
+ Si304 O41 1.607 1_455 S
968
+ Si304 O47 1.603 1_455 S
969
+ Si305 O118 1.604 1_455 S
970
+ Si305 O43 1.599 1_455 S
971
+ Si310 O267 1.607 1_455 S
972
+ Si310 O273 1.603 1_455 S
973
+ Si311 O192 1.604 1_455 S
974
+ Si311 O269 1.599 1_455 S
975
+ Cu313 O217 1.933 1_554 S
976
+ Cu313 O256 1.936 1_554 S
977
+ Cu313 Na298 3.231 1_554 S
978
+ Cu313 Na300 3.123 1_554 S
979
+ Cu316 O180 1.933 1_554 S
980
+ Cu316 O294 1.936 1_554 S
981
+ Cu316 Na260 3.231 1_554 S
982
+ Cu316 Na262 3.123 1_554 S
983
+ Cu317 O175 1.937 1_554 S
984
+ Cu317 Na186 3.217 1_554 S
985
+ Cu317 O215 1.931 1_554 S
986
+ Cu318 O62 1.937 1_445 S
987
+ Cu318 O212 1.937 1_554 S
988
+ Cu318 Na73 3.217 1_545 S
989
+ Cu318 Na223 3.217 1_454 S
990
+ Cu318 O178 1.931 1_444 S
991
+ Cu320 O138 1.937 1_545 S
992
+ Cu320 O288 1.937 1_455 S
993
+ Cu320 Na149 3.217 1_445 S
994
+ Cu320 O103 1.931 1_455 S
995
+ Cu320 O253 1.931 1_545 S
examples/stability/plot.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
examples/stability/pressure.ipynb ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "\n",
11
+ "from ase import units\n",
12
+ "from dask.distributed import Client\n",
13
+ "from dask_jobqueue import SLURMCluster\n",
14
+ "from dotenv import load_dotenv\n",
15
+ "from prefect import flow, task\n",
16
+ "from prefect_dask import DaskTaskRunner\n",
17
+ "\n",
18
+ "from mlip_arena.models import REGISTRY, MLIPEnum\n",
19
+ "from mlip_arena.tasks.md import run as MD\n",
20
+ "from mlip_arena.tasks.stability.input import get_atoms_from_db\n",
21
+ "\n",
22
+ "load_dotenv()\n",
23
+ "\n",
24
+ "HF_TOKEN = os.environ.get(\"HF_TOKEN\", None)\n",
25
+ "MP_API_KEY = os.environ.get(\"MP_API_KEY\", None)"
26
+ ]
27
+ },
28
+ {
29
+ "cell_type": "code",
30
+ "execution_count": null,
31
+ "metadata": {
32
+ "scrolled": true
33
+ },
34
+ "outputs": [],
35
+ "source": [
36
+ "nodes_per_alloc = 1\n",
37
+ "gpus_per_alloc = 4\n",
38
+ "ntasks = 1\n",
39
+ "\n",
40
+ "cluster_kwargs = dict(\n",
41
+ " cores=1,\n",
42
+ " memory=\"64 GB\",\n",
43
+ " processes=1,\n",
44
+ " shebang=\"#!/bin/bash\",\n",
45
+ " account=\"matgen\",\n",
46
+ " walltime=\"03:00:00\",\n",
47
+ " # job_cpu=128,\n",
48
+ " job_mem=\"0\",\n",
49
+ " job_script_prologue=[\n",
50
+ " \"source ~/.bashrc\",\n",
51
+ " \"module load python\",\n",
52
+ " \"source activate /pscratch/sd/c/cyrusyc/.conda/mlip-arena\",\n",
53
+ " ],\n",
54
+ " job_directives_skip=[\"-n\", \"--cpus-per-task\", \"-J\"],\n",
55
+ " job_extra_directives=[\n",
56
+ " \"-J stability-npt\",\n",
57
+ " \"-q preempt\",\n",
58
+ " \"--time-min=00:30:00\",\n",
59
+ " \"--comment=12:00:00\",\n",
60
+ " f\"-N {nodes_per_alloc}\",\n",
61
+ " \"-C gpu\",\n",
62
+ " f\"-G {gpus_per_alloc}\",\n",
63
+ " ],\n",
64
+ ")\n",
65
+ "\n",
66
+ "cluster = SLURMCluster(**cluster_kwargs)\n",
67
+ "print(cluster.job_script())\n",
68
+ "cluster.adapt(minimum_jobs=5, maximum_jobs=10)\n",
69
+ "client = Client(cluster)"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": null,
75
+ "metadata": {},
76
+ "outputs": [],
77
+ "source": [
78
+ "from mlip_arena.tasks.utils import get_calculator\n",
79
+ "\n",
80
+ "selected_models = [\n",
81
+ " \"MACE-MP(M)\",\n",
82
+ " \"CHGNet\",\n",
83
+ " \"M3GNet\",\n",
84
+ " \"MatterSim\",\n",
85
+ " \"eqV2(OMat)\",\n",
86
+ " \"MACE-MPA\",\n",
87
+ " \"ORBv2\",\n",
88
+ " \"SevenNet\",\n",
89
+ " \"ALIGNN\",\n",
90
+ "]\n",
91
+ "\n",
92
+ "\n",
93
+ "@task\n",
94
+ "def run_one(\n",
95
+ " atoms,\n",
96
+ " model,\n",
97
+ "):\n",
98
+ " result = MD.with_options(\n",
99
+ " timeout_seconds=600,\n",
100
+ " retries=2,\n",
101
+ " refresh_cache=True\n",
102
+ " )(\n",
103
+ " atoms=atoms,\n",
104
+ " calculator=get_calculator(\n",
105
+ " model.name,\n",
106
+ " calculator_kwargs=None,\n",
107
+ " ),\n",
108
+ " ensemble=\"npt\",\n",
109
+ " dynamics=\"nose-hoover\",\n",
110
+ " time_step=None,\n",
111
+ " dynamics_kwargs=dict(\n",
112
+ " ttime=25 * units.fs, pfactor=((75 * units.fs) ** 2) * 1e2 * units.GPa\n",
113
+ " ),\n",
114
+ " total_time=1e4, # 5e4, # fs\n",
115
+ " temperature=[300, 3000],\n",
116
+ " pressure=[0, 5e2 * units.GPa], # 500 GPa / 10 ps = 50 GPa / 1 ps\n",
117
+ " traj_file=f\"{REGISTRY[model.name]['family']}/{model.name}_{atoms.info.get('material_id', 'random')}_{atoms.get_chemical_formula()}_npt.traj\",\n",
118
+ " traj_interval=10,\n",
119
+ " )\n",
120
+ "\n",
121
+ " return result\n",
122
+ "\n",
123
+ "\n",
124
+ "@flow\n",
125
+ "def compress():\n",
126
+ " futures = []\n",
127
+ " # To download the database automatically, `huggingface_hub login` or provide HF_TOKEN\n",
128
+ " for atoms in get_atoms_from_db(\"random-mixture.db\", force_download=False):\n",
129
+ " for model in MLIPEnum:\n",
130
+ " if model.name not in selected_models:\n",
131
+ " continue\n",
132
+ "\n",
133
+ " if \"stability\" not in REGISTRY[model.name][\"gpu-tasks\"]:\n",
134
+ " continue\n",
135
+ "\n",
136
+ " try:\n",
137
+ " future = run_one.with_options(\n",
138
+ " timeout_seconds=600, retries=2, refresh_cache=False\n",
139
+ " ).submit(atoms.copy(), model)\n",
140
+ " futures.append(future)\n",
141
+ " except:\n",
142
+ " continue\n",
143
+ "\n",
144
+ " return [future.result(raise_on_failure=False) for future in futures]"
145
+ ]
146
+ },
147
+ {
148
+ "cell_type": "code",
149
+ "execution_count": null,
150
+ "metadata": {},
151
+ "outputs": [],
152
+ "source": [
153
+ "compress.with_options(\n",
154
+ " task_runner=DaskTaskRunner(address=client.scheduler.address), log_prints=True\n",
155
+ ")()"
156
+ ]
157
+ },
158
+ {
159
+ "cell_type": "code",
160
+ "execution_count": null,
161
+ "metadata": {},
162
+ "outputs": [],
163
+ "source": []
164
+ }
165
+ ],
166
+ "metadata": {
167
+ "kernelspec": {
168
+ "display_name": "NERSC Python",
169
+ "language": "python",
170
+ "name": "python3"
171
+ },
172
+ "language_info": {
173
+ "codemirror_mode": {
174
+ "name": "ipython",
175
+ "version": 3
176
+ },
177
+ "file_extension": ".py",
178
+ "mimetype": "text/x-python",
179
+ "name": "python",
180
+ "nbconvert_exporter": "python",
181
+ "pygments_lexer": "ipython3",
182
+ "version": "3.11.7"
183
+ },
184
+ "widgets": {
185
+ "application/vnd.jupyter.widget-state+json": {
186
+ "state": {},
187
+ "version_major": 2,
188
+ "version_minor": 0
189
+ }
190
+ }
191
+ },
192
+ "nbformat": 4,
193
+ "nbformat_minor": 4
194
+ }
examples/stability/temperature.ipynb ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "\n",
11
+ "from ase import units\n",
12
+ "from dask.distributed import Client\n",
13
+ "from dask_jobqueue import SLURMCluster\n",
14
+ "from dotenv import load_dotenv\n",
15
+ "from prefect import flow, task\n",
16
+ "from prefect_dask import DaskTaskRunner\n",
17
+ "\n",
18
+ "from mlip_arena.models import REGISTRY, MLIPEnum\n",
19
+ "from mlip_arena.tasks.md import run as MD\n",
20
+ "from mlip_arena.tasks.stability.input import get_atoms_from_db\n",
21
+ "\n",
22
+ "load_dotenv()\n",
23
+ "\n",
24
+ "HF_TOKEN = os.environ.get(\"HF_TOKEN\", None)\n",
25
+ "MP_API_KEY = os.environ.get(\"MP_API_KEY\", None)"
26
+ ]
27
+ },
28
+ {
29
+ "cell_type": "code",
30
+ "execution_count": null,
31
+ "metadata": {
32
+ "scrolled": true
33
+ },
34
+ "outputs": [],
35
+ "source": [
36
+ "nodes_per_alloc = 1\n",
37
+ "gpus_per_alloc = 4\n",
38
+ "ntasks = 1\n",
39
+ "\n",
40
+ "cluster_kwargs = dict(\n",
41
+ " cores=1,\n",
42
+ " memory=\"64 GB\",\n",
43
+ " processes=1,\n",
44
+ " shebang=\"#!/bin/bash\",\n",
45
+ " account=\"matgen\",\n",
46
+ " walltime=\"04:00:00\",\n",
47
+ " # job_cpu=128,\n",
48
+ " job_mem=\"0\",\n",
49
+ " job_script_prologue=[\n",
50
+ " \"source ~/.bashrc\",\n",
51
+ " \"module load python\",\n",
52
+ " \"source activate /pscratch/sd/c/cyrusyc/.conda/mlip-arena\",\n",
53
+ " ],\n",
54
+ " job_directives_skip=[\"-n\", \"--cpus-per-task\", \"-J\"],\n",
55
+ " job_extra_directives=[\n",
56
+ " \"-J stability-nvt\",\n",
57
+ " \"-q preempt\",\n",
58
+ " \"--time-min=00:30:00\",\n",
59
+ " \"--comment=12:00:00\",\n",
60
+ " f\"-N {nodes_per_alloc}\",\n",
61
+ " \"-C gpu\",\n",
62
+ " f\"-G {gpus_per_alloc}\",\n",
63
+ " ],\n",
64
+ ")\n",
65
+ "\n",
66
+ "cluster = SLURMCluster(**cluster_kwargs)\n",
67
+ "print(cluster.job_script())\n",
68
+ "cluster.adapt(minimum_jobs=10, maximum_jobs=50)\n",
69
+ "client = Client(cluster)"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": null,
75
+ "metadata": {},
76
+ "outputs": [],
77
+ "source": [
78
+ "from prefect.cache_policies import INPUTS, TASK_SOURCE\n",
79
+ "from prefect.futures import wait\n",
80
+ "\n",
81
+ "from mlip_arena.tasks.utils import get_calculator\n",
82
+ "\n",
83
+ "selected_models = [\n",
84
+ " \"MACE-MP(M)\",\n",
85
+ " \"CHGNet\",\n",
86
+ " \"M3GNet\",\n",
87
+ " \"MatterSim\",\n",
88
+ " \"eqV2(OMat)\",\n",
89
+ " \"MACE-MPA\",\n",
90
+ " \"ORBv2\",\n",
91
+ " \"SevenNet\",\n",
92
+ " \"ALIGNN\",\n",
93
+ "]\n",
94
+ "\n",
95
+ "\n",
96
+ "@task(cache_policy=TASK_SOURCE + INPUTS)\n",
97
+ "def run_one(\n",
98
+ " atoms,\n",
99
+ " model,\n",
100
+ "):\n",
101
+ " try:\n",
102
+ " result = MD.with_options(\n",
103
+ " # timeout_seconds=600,\n",
104
+ " # retries=1,\n",
105
+ " refresh_cache=True\n",
106
+ " )(\n",
107
+ " atoms=atoms,\n",
108
+ " calculator=get_calculator(\n",
109
+ " model.name,\n",
110
+ " calculator_kwargs=None,\n",
111
+ " ),\n",
112
+ " ensemble=\"nvt\",\n",
113
+ " dynamics=\"nose-hoover\",\n",
114
+ " time_step=None,\n",
115
+ " dynamics_kwargs=dict(\n",
116
+ " ttime=25 * units.fs,\n",
117
+ " # pfactor=((75 * units.fs) ** 2) * 1e2 * units.GPa\n",
118
+ " ),\n",
119
+ " total_time=1e4, # 5e4, # fs\n",
120
+ " temperature=[300, 3000],\n",
121
+ " pressure=None,\n",
122
+ " traj_file=f\"{REGISTRY[model.name]['family']}/{model.name}_{atoms.info.get('material_id', 'random')}_{atoms.get_chemical_formula()}_nvt.traj\",\n",
123
+ " traj_interval=10,\n",
124
+ " )\n",
125
+ " except Exception as e:\n",
126
+ " print(e)\n",
127
+ " return e\n",
128
+ "\n",
129
+ " return result\n",
130
+ "\n",
131
+ "\n",
132
+ "@flow\n",
133
+ "def heat():\n",
134
+ " futures = []\n",
135
+ " # To download the database automatically, `huggingface_hub login` or provide HF_TOKEN\n",
136
+ " for atoms in get_atoms_from_db(\"random-mixture.db\", force_download=False):\n",
137
+ " for model in MLIPEnum:\n",
138
+ " if model.name not in selected_models:\n",
139
+ " continue\n",
140
+ "\n",
141
+ " future = run_one.with_options(\n",
142
+ " timeout_seconds=600, retries=2, refresh_cache=False\n",
143
+ " ).submit(atoms.copy(), model)\n",
144
+ " futures.append(future)\n",
145
+ "\n",
146
+ " wait(futures)\n",
147
+ "\n",
148
+ " return [\n",
149
+ " f.result(timeout=None, raise_on_failure=False)\n",
150
+ " for f in futures\n",
151
+ " if f.state.is_completed()\n",
152
+ " ]\n"
153
+ ]
154
+ },
155
+ {
156
+ "cell_type": "code",
157
+ "execution_count": null,
158
+ "metadata": {},
159
+ "outputs": [],
160
+ "source": [
161
+ "heat.with_options(\n",
162
+ " task_runner=DaskTaskRunner(address=client.scheduler.address), log_prints=True\n",
163
+ ")()"
164
+ ]
165
+ },
166
+ {
167
+ "cell_type": "code",
168
+ "execution_count": null,
169
+ "metadata": {},
170
+ "outputs": [],
171
+ "source": []
172
+ }
173
+ ],
174
+ "metadata": {
175
+ "kernelspec": {
176
+ "display_name": "mlip-arena",
177
+ "language": "python",
178
+ "name": "mlip-arena"
179
+ },
180
+ "language_info": {
181
+ "codemirror_mode": {
182
+ "name": "ipython",
183
+ "version": 3
184
+ },
185
+ "file_extension": ".py",
186
+ "mimetype": "text/x-python",
187
+ "name": "python",
188
+ "nbconvert_exporter": "python",
189
+ "pygments_lexer": "ipython3",
190
+ "version": "3.11.8"
191
+ },
192
+ "widgets": {
193
+ "application/vnd.jupyter.widget-state+json": {
194
+ "state": {},
195
+ "version_major": 2,
196
+ "version_minor": 0
197
+ }
198
+ }
199
+ },
200
+ "nbformat": 4,
201
+ "nbformat_minor": 4
202
+ }
examples/vacancy_migration/Table-A1-fcc.csv ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ symbol,cohesive_energy,K,K',volume_per_atom,e_vacform,e_vacmig
2
+ Ac,3.70,21.63,2.03,45.37,1.26,0.45
3
+ Ag,2.49,84.11,5.15,17.87,0.68,0.70
4
+ Al,3.43,76.90,4.23,16.47,0.61,0.58
5
+ Ar,0.02,1.60,3.45,45.00,0.01,0.06
6
+ Au,2.99,136.19,7.45,18.07,0.40,0.53
7
+ Ba,1.87,8.01,2.81,64.13,1.09,0.36
8
+ Be,3.64,116.96,3.90,7.88,-0.06,0.75
9
+ Ca,1.91,16.82,1.70,42.17,1.13,0.47
10
+ Cd,0.74,41.66,5.71,22.60,0.30,0.23
11
+ Ce,4.58,37.65,4.10,26.10,1.30,0.54
12
+ Co,4.92,251.54,5.17,10.30,1.84,1.45
13
+ Co_mag,5.11,209.89,5.07,10.90,1.79,1.01
14
+ Cs,0.70,2.40,2.36,116.46,0.34,0.13
15
+ Cu,3.48,136.99,5.86,11.97,1.07,0.72
16
+ Dy,4.23,,,31.37,1.72,
17
+ Er,1.55,16.02,2.66,40.96,1.02,0.47
18
+ Fe,4.69,283.59,4.89,10.22,2.32,1.38
19
+ Ga,2.61,29.64,6.02,18.91,-0.04,0.18
20
+ Ge,3.40,,,19.51,0.10,
21
+ He,0.01,1.60,3.36,16.54,0.00,0.02
22
+ Hf,6.41,107.35,3.59,22.26,2.09,0.81
23
+ Ho,4.20,40.86,4.04,30.88,1.74,0.73
24
+ In,2.31,33.65,4.53,27.33,0.28,0.23
25
+ Ir,7.23,345.27,5.44,14.53,1.55,2.54
26
+ K,0.86,3.20,6.19,73.60,0.34,0.16
27
+ Kr,0.02,0.80,7.90,57.44,0.00,0.07
28
+ La,4.22,24.83,3.36,37.10,1.44,0.21
29
+ Li,1.61,13.62,3.75,20.22,0.60,0.13
30
+ Mg,1.49,36.05,4.04,23.03,0.82,0.41
31
+ Mn,3.76,276.38,5.42,10.73,2.38,0.65
32
+ Mn_mag,3.76,275.57,5.58,10.72,2.36,0.69
33
+ Na,1.11,9.61,3.08,35.08,0.38,0.14
34
+ Ni,4.77,197.87,5.29,10.85,1.39,0.94
35
+ Ni_mag,4.83,193.06,5.45,10.90,1.43,1.08
36
+ Os,8.17,398.14,4.99,14.29,2.75,2.73
37
+ Pa,6.86,96.13,4.16,25.21,1.54,0.77
38
+ Pb,2.94,39.25,4.07,31.69,0.45,0.54
39
+ Pd,3.71,165.83,6.62,15.37,1.16,0.95
40
+ Pr,3.58,,,23.79,0.76,
41
+ Pt,5.45,246.74,6.10,15.67,0.61,1.24
42
+ Rb,0.76,2.40,7.13,90.81,0.30,0.14
43
+ Re,7.73,366.10,4.73,14.94,2.94,1.81
44
+ Rh,5.63,250.74,5.86,14.13,1.57,1.79
45
+ Ru,6.56,314.03,4.81,13.88,2.51,1.85
46
+ Sc,4.09,54.47,4.07,24.43,2.07,0.60
47
+ Sn,3.11,46.46,6.10,27.82,0.26,0.38
48
+ Sr,1.61,11.22,3.72,54.74,0.95,0.45
49
+ Ta,8.09,198.67,3.86,18.63,2.23,
50
+ Tb,4.26,38.45,4.55,31.88,1.75,0.71
51
+ Tc,6.84,298.81,4.91,14.50,2.62,1.17
52
+ Th,6.34,55.28,3.50,32.07,1.92,1.25
53
+ Ti,5.43,102.54,2.89,17.25,1.95,0.45
54
+ Tl,1.99,27.24,5.55,30.50,0.37,0.10
55
+ W,7.98,,,16.25,1.67,
56
+ Xe,0.03,0.80,2.22,80.21,0.01,0.09
57
+ Y,4.14,38.45,4.10,32.35,1.72,0.67
58
+ Zr,6.21,90.52,4.42,23.26,2.02,0.50
examples/vacancy_migration/Table-A2-hcp.csv ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ symbol,cohesive_energy,K,K',volume_per_atom,e_vacform,e_vacmig_v,e_vacmig
2
+ Ag,2.49,82.51,5.15,17.93,0.76,0.50,0.60
3
+ Al,3.40,74.50,4.70,16.63,0.62,0.41,0.46
4
+ Ar,0.02,0.88,7.43,46.11,0.01,0.06,
5
+ Au,2.98,130.58,7.58,18.10,0.40,0.49,0.57
6
+ Ba,1.87,8.01,3.38,63.55,1.11,0.34,0.37
7
+ Be,3.72,122.57,3.57,7.92,1.04,0.74,0.87
8
+ Bi,2.38,,,31.44,0.00,,
9
+ Ca,1.91,17.62,3.44,42.39,1.06,0.38,0.42
10
+ Cd,0.74,43.26,6.04,22.60,0.25,0.23,0.16
11
+ Ce,4.49,,,26.43,1.23,,
12
+ Co,4.90,248.34,3.29,10.33,1.67,1.02,1.19
13
+ Co_mag,5.12,214.69,4.91,10.85,1.93,0.81,0.78
14
+ Cr,3.63,,,11.77,1.77,,
15
+ Cs,0.70,1.60,7.60,116.42,0.31,0.12,0.13
16
+ Cu,3.47,134.58,5.61,12.00,1.04,0.57,0.69
17
+ Fe,4.77,288.39,5.60,10.16,2.43,1.52,1.51
18
+ Ga,2.60,44.06,4.37,18.92,0.21,0.12,0.16
19
+ Ge,3.40,,,19.25,0.26,,
20
+ He,0.01,1.60,3.46,16.54,0.00,0.02,0.01
21
+ Hf,6.48,112.95,3.59,22.26,2.26,0.89,1.00
22
+ In,2.31,32.84,4.68,27.40,0.31,0.20,0.21
23
+ Ir,7.16,339.66,3.32,14.60,1.25,1.57,1.95
24
+ K,0.86,3.20,5.95,73.72,0.35,0.12,0.14
25
+ Kr,0.02,0.80,6.73,58.10,0.00,0.07,0.07
26
+ La,4.20,,,37.42,1.45,,
27
+ Li,1.61,13.62,3.82,20.24,0.63,0.10,0.12
28
+ Mg,1.50,36.05,4.31,22.85,0.78,0.40,0.42
29
+ Mn,3.82,190.66,11.04,10.63,2.51,0.43,0.11
30
+ Mo,5.91,,,15.95,1.96,,
31
+ Nb,6.71,,,18.61,2.08,,
32
+ Ne,0.01,6.41,1.65,19.15,-0.01,0.04,0.04
33
+ Ni,4.74,134.58,12.07,10.87,1.35,0.69,0.79
34
+ Ni_mag,4.81,192.26,5.34,10.94,1.37,0.77,0.89
35
+ Os,8.31,406.15,5.04,14.23,3.03,3.03,3.22
36
+ Pa,3.09,90.52,3.96,15.12,0.28,0.38,
37
+ Pb,2.92,37.65,4.49,31.51,0.41,0.44,0.41
38
+ Pd,3.67,163.42,6.50,15.45,1.10,0.68,0.73
39
+ Pt,5.39,241.13,6.22,15.77,0.70,0.70,
40
+ Rb,0.76,2.40,6.45,91.19,0.32,0.13,0.12
41
+ Re,7.79,370.10,4.67,14.89,3.42,1.79,1.17
42
+ Rh,5.59,250.74,5.76,14.18,1.53,1.25,1.47
43
+ Ru,6.68,311.62,5.16,13.81,2.68,2.17,2.18
44
+ Sc,4.14,52.87,4.82,24.48,1.87,0.74,0.69
45
+ Si,4.04,85.72,4.88,14.35,0.08,0.04,0.26
46
+ Sn,3.11,47.26,5.92,27.55,0.40,0.31,0.33
47
+ Sr,1.61,11.22,3.77,55.16,0.98,0.36,0.40
48
+ Ta,8.05,,,18.55,2.35,,
49
+ Tc,6.91,302.01,4.90,14.44,2.85,1.21,0.63
50
+ Te,2.23,48.87,5.03,31.47,0.25,,
51
+ Ti,5.49,109.75,5.07,17.29,2.06,0.49,0.59
52
+ Tl,2.01,25.63,5.47,30.97,0.40,0.23,0.16
53
+ V,5.15,,,13.75,1.84,,
54
+ W,7.96,,,16.32,2.44,,
55
+ Xe,0.03,0.80,2.32,79.60,0.01,0.07,0.08
56
+ Y,4.16,40.05,3.72,32.82,1.87,0.69,0.67
57
+ Zn,1.10,73.70,6.02,15.23,0.47,0.34,0.20
58
+ Zr,6.25,93.73,4.34,23.44,2.03,0.57,0.70
examples/vacancy_migration/analysis.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import glob
2
+ import pickle
3
+ from pathlib import Path
4
+
5
+ import numpy as np
6
+ import pandas as pd
7
+ from matplotlib import pyplot as plt
8
+ from pymatgen.core import Element
9
+
10
+ from mlip_arena.models import REGISTRY
11
+
12
+ DATA_DIR = Path(__file__).parent
13
+
14
+ mlip_models = ["MACE-MP(M)", "MatterSim", "ORBv2", "M3GNet", "CHGNet", "SevenNet"]
15
+
16
+ fcc_pbe = pd.read_csv(DATA_DIR / "Table-A1-fcc.csv")
17
+ hcp_pbe = pd.read_csv(DATA_DIR / "Table-A2-hcp.csv")
18
+
19
+ # fcc
20
+
21
+ # Initialize an empty DataFrame
22
+ results_df = pd.DataFrame(columns=["symbol", "model", "fit_path", "fit_energies"])
23
+
24
+ for model in mlip_models:
25
+ out_dir = Path(REGISTRY[model]["family"])
26
+
27
+ for index, row in fcc_pbe.iterrows():
28
+ symbol = row["symbol"]
29
+
30
+ if Element(symbol.split("_")[0]).is_noble_gas:
31
+ continue
32
+
33
+ files = glob.glob(str(out_dir / f"{model}-fcc-{symbol.split('_')[0]}108.pkl"))
34
+ if len(files) == 0:
35
+ print("skip", model, symbol)
36
+ # Add missing data to the DataFrame
37
+ # if symbol not in results_df['symbol'].values:
38
+ # Create a new row if the symbol is not yet in the DataFrame
39
+ new_row = {
40
+ "symbol": symbol,
41
+ "model": model,
42
+ "pbe_e_vacmig": row["e_vacmig"],
43
+ "fit_path": [],
44
+ "fit_energies": [],
45
+ }
46
+ results_df = pd.concat(
47
+ [results_df, pd.DataFrame([new_row])], ignore_index=True
48
+ )
49
+ continue
50
+ file = files[0]
51
+ with open(file, "rb") as f:
52
+ result = pickle.load(f)
53
+
54
+ # Add data to the DataFrame
55
+ # if symbol not in results_df['symbol'].values:
56
+ # Create a new row if the symbol is not yet in the DataFrame
57
+ forcefit = result["neb"]["forcefit"]
58
+ new_row = {
59
+ "symbol": symbol,
60
+ "model": model,
61
+ "pbe_e_vacmig": row["e_vacmig"],
62
+ "fit_path": forcefit.fit_path,
63
+ "fit_energies": forcefit.fit_energies,
64
+ }
65
+ results_df = pd.concat([results_df, pd.DataFrame([new_row])], ignore_index=True)
66
+
67
+
68
+ nrows = 2
69
+ ncols = len(mlip_models) // nrows
70
+
71
+ fig, axes = plt.subplots(
72
+ nrows=nrows,
73
+ ncols=ncols,
74
+ figsize=(6, 4),
75
+ sharex=True,
76
+ sharey=True,
77
+ constrained_layout=True,
78
+ dpi=300,
79
+ )
80
+
81
+ for i, (ax, model) in enumerate(zip(axes.ravel(), mlip_models, strict=False)):
82
+ filtered_df = results_df[results_df["model"] == model]
83
+
84
+ asymmetries = []
85
+ middle_deviations = []
86
+
87
+ for index, row in filtered_df.iterrows():
88
+ if len(row["fit_path"]) == 0 or pd.isna(row["pbe_e_vacmig"]):
89
+ continue
90
+
91
+ x = row["fit_path"] / max(row["fit_path"])
92
+ y = row["fit_energies"] / row["pbe_e_vacmig"]
93
+
94
+ # middle_idx = np.argmin(np.abs(x - 0.5))
95
+
96
+ left_side = y[x <= 0.5]
97
+ right_side = y[x >= 0.5][::-1]
98
+ min_len = min(len(left_side), len(right_side))
99
+ left_side = left_side[:min_len]
100
+ right_side = right_side[:min_len]
101
+
102
+ asymmetry = np.abs(left_side - right_side).mean()
103
+ # middle = (left_side[-1] + right_side[-1]) / 2
104
+ middle = max(y)
105
+
106
+ if np.abs(np.array(y)).max() > 10:
107
+ continue
108
+
109
+ asymmetries.append(asymmetry)
110
+ middle_deviations.append(middle - 1)
111
+
112
+ ax.plot(
113
+ x,
114
+ y,
115
+ alpha=0.5,
116
+ color=method_color_mapping[model],
117
+ label=model,
118
+ )
119
+
120
+ asymmetries = np.array(asymmetries)
121
+ middle_deviations = np.array(middle_deviations)
122
+
123
+ ax.text(
124
+ 0.05,
125
+ 0.95,
126
+ "\n".join(
127
+ [
128
+ f"Miss: {len(filtered_df) - len(asymmetries) - filtered_df['pbe_e_vacmig'].isna().sum()}",
129
+ f"Asym: {asymmetries.mean():.3f}",
130
+ f"MAPE@max: {np.abs(middle_deviations).mean() * 100:.1f}",
131
+ ]
132
+ ),
133
+ transform=ax.transAxes,
134
+ ha="left",
135
+ va="top",
136
+ fontsize="small",
137
+ # fontsize=6,
138
+ )
139
+
140
+ ax.set(
141
+ title=model,
142
+ xlabel="Normalized path" if i >= len(models) - ncols else None,
143
+ ylabel="Normalized energy" if i % ncols == 0 else None,
144
+ ylim=(-0.1, 2),
145
+ )
146
+
147
+ with open(DATA_DIR / "fcc.pkl", "wb") as f:
148
+ pickle.dump(fig, f)
149
+
150
+ # hcp
151
+
152
+ # Initialize an empty DataFrame
153
+ results_df = pd.DataFrame(columns=["symbol", "model", "fit_path", "fit_energies"])
154
+
155
+ for model in mlip_models:
156
+ out_dir = Path(REGISTRY[model]["family"])
157
+
158
+ for index, row in hcp_pbe.iterrows():
159
+ symbol = row["symbol"]
160
+
161
+ if Element(symbol.split("_")[0]).is_noble_gas:
162
+ continue
163
+
164
+ files = glob.glob(str(out_dir / f"{model}-hcp-{symbol.split('_')[0]}36.pkl"))
165
+ if len(files) == 0:
166
+ print("skip", model, symbol)
167
+ # Add missing data to the DataFrame
168
+ # if symbol not in results_df['symbol'].values:
169
+ # Create a new row if the symbol is not yet in the DataFrame
170
+ new_row = {
171
+ "symbol": symbol,
172
+ "model": model,
173
+ "pbe_e_vacmig": row["e_vacmig"],
174
+ "fit_path": [],
175
+ "fit_energies": [],
176
+ }
177
+ results_df = pd.concat(
178
+ [results_df, pd.DataFrame([new_row])], ignore_index=True
179
+ )
180
+ # else:
181
+ # # Update the existing row with the model's prediction
182
+ # results_df.loc[results_df['symbol'] == symbol, model] = pd.NA
183
+ continue
184
+ file = files[0]
185
+ with open(file, "rb") as f:
186
+ result = pickle.load(f)
187
+
188
+ # Add data to the DataFrame
189
+ # if symbol not in results_df['symbol'].values:
190
+ # Create a new row if the symbol is not yet in the DataFrame
191
+ forcefit = result["neb"]["forcefit"]
192
+ new_row = {
193
+ "symbol": symbol,
194
+ "model": model,
195
+ "pbe_e_vacmig": row["e_vacmig"],
196
+ "fit_path": forcefit.fit_path,
197
+ "fit_energies": forcefit.fit_energies,
198
+ }
199
+ results_df = pd.concat([results_df, pd.DataFrame([new_row])], ignore_index=True)
200
+
201
+
202
+
203
+ nrows = 2
204
+ ncols = len(mlip_models) // nrows
205
+
206
+ threshold = 0.10
207
+
208
+ fig, axes = plt.subplots(
209
+ nrows=nrows,
210
+ ncols=ncols,
211
+ figsize=(6, 4),
212
+ sharex=True,
213
+ sharey=True,
214
+ constrained_layout=True,
215
+ dpi=300,
216
+ )
217
+
218
+ for i, (ax, model) in enumerate(zip(axes.ravel(), mlip_models, strict=False)):
219
+ filtered_df = results_df[results_df["model"] == model]
220
+
221
+ asymmetries = []
222
+ middle_deviations = []
223
+
224
+ for index, row in filtered_df.iterrows():
225
+ if len(row["fit_path"]) == 0 or pd.isna(row["pbe_e_vacmig"]):
226
+ continue
227
+
228
+ x = row["fit_path"] / max(row["fit_path"])
229
+ y = row["fit_energies"] / row["pbe_e_vacmig"]
230
+
231
+ # middle_idx = np.argmin(np.abs(x - 0.5))
232
+
233
+ left_side = y[x <= 0.5]
234
+ right_side = y[x >= 0.5][::-1]
235
+ min_len = min(len(left_side), len(right_side))
236
+ left_side = left_side[:min_len]
237
+ right_side = right_side[:min_len]
238
+
239
+ asymmetry = np.abs(left_side - right_side).mean()
240
+ # middle = (left_side[-1] + right_side[-1]) / 2
241
+ middle = max(y)
242
+
243
+ if np.abs(np.array(y)).max() > 10:
244
+ continue
245
+
246
+ asymmetries.append(asymmetry)
247
+ middle_deviations.append(middle - 1)
248
+
249
+ ax.plot(
250
+ x,
251
+ y,
252
+ alpha=0.5,
253
+ color=method_color_mapping[model],
254
+ label=model,
255
+ )
256
+
257
+ asymmetries = np.array(asymmetries)
258
+ middle_deviations = np.array(middle_deviations)
259
+
260
+ ax.text(
261
+ 0.05,
262
+ 0.95,
263
+ "\n".join(
264
+ [
265
+ f"Miss: {len(filtered_df) - len(asymmetries) - filtered_df['pbe_e_vacmig'].isna().sum()}",
266
+ f"Asym: {asymmetries.mean():.3f}",
267
+ f"MAPE@max: {np.abs(middle_deviations).mean() * 100:.1f}",
268
+ ]
269
+ ),
270
+ transform=ax.transAxes,
271
+ ha="left",
272
+ va="top",
273
+ fontsize="small",
274
+ )
275
+
276
+ ax.set(
277
+ title=model,
278
+ xlabel="Normalized path" if i >= len(mlip_models) - ncols else None,
279
+ ylabel="Normalized energy" if i % ncols == 0 else None,
280
+ ylim=(-0.1, 2),
281
+ )
282
+
283
+ with open(DATA_DIR / "hcp.pkl", "wb") as f:
284
+ pickle.dump(fig, f)
examples/wbm_ev/analyze.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ from ase.db import connect
6
+ from scipy import stats
7
+
8
+ from mlip_arena.models import REGISTRY, MLIPEnum
9
+
10
+ DATA_DIR = Path(__file__).parent.absolute()
11
+
12
+
13
+ def load_wbm_structures():
14
+ """
15
+ Load the WBM structures from a ASE DB file.
16
+ """
17
+ with connect(DATA_DIR.parent / "wbm_structures.db") as db:
18
+ for row in db.select():
19
+ yield row.toatoms(add_additional_information=True)
20
+
21
+ def gather_results():
22
+ for model in MLIPEnum:
23
+ if "wbm_ev" not in REGISTRY[model.name].get("gpu-tasks", []):
24
+ continue
25
+
26
+ if (DATA_DIR / f"{model.name}.parquet").exists():
27
+ continue
28
+
29
+ all_data = []
30
+
31
+ for atoms in load_wbm_structures():
32
+ fpath = Path(model.name) / f"{atoms.info['key_value_pairs']['wbm_id']}.json"
33
+ if not fpath.exists():
34
+ continue
35
+
36
+ all_data.append(pd.read_json(fpath))
37
+
38
+ df = pd.concat(all_data, ignore_index=True)
39
+ df.to_parquet(DATA_DIR / f"{model.name}.parquet")
40
+
41
+
42
+ def summarize():
43
+ summary_table = pd.DataFrame(
44
+ columns=[
45
+ "model",
46
+ "energy-diff-flip-times",
47
+ "tortuosity",
48
+ "spearman-compression-energy",
49
+ "spearman-compression-derivative",
50
+ "spearman-tension-energy",
51
+ "missing",
52
+ ]
53
+ )
54
+
55
+
56
+ for model in MLIPEnum:
57
+ fpath = DATA_DIR / f"{model.name}.parquet"
58
+ if not fpath.exists():
59
+ continue
60
+ df_raw_results = pd.read_parquet(fpath)
61
+
62
+ df_analyzed = pd.DataFrame(
63
+ columns=[
64
+ "model",
65
+ "structure",
66
+ "formula",
67
+ "volume-ratio",
68
+ "energy-delta-per-atom",
69
+ "energy-diff-flip-times",
70
+ "tortuosity",
71
+ "spearman-compression-energy",
72
+ "spearman-compression-derivative",
73
+ "spearman-tension-energy",
74
+ "missing",
75
+ ]
76
+ )
77
+
78
+ for wbm_struct in load_wbm_structures():
79
+ structure_id = wbm_struct.info["key_value_pairs"]["wbm_id"]
80
+
81
+ try:
82
+ results = df_raw_results.loc[df_raw_results["id"] == structure_id]
83
+ results = results["eos"].values[0]
84
+ es = np.array(results["energies"])
85
+ vols = np.array(results["volumes"])
86
+ vol0 = wbm_struct.get_volume()
87
+
88
+ indices = np.argsort(vols)
89
+ vols = vols[indices]
90
+ es = es[indices]
91
+
92
+ imine = len(es) // 2
93
+ # min_center_val = np.min(es[imid - 1 : imid + 2])
94
+ # imine = np.where(es == min_center_val)[0][0]
95
+ emin = es[imine]
96
+
97
+ interpolated_volumes = [
98
+ (vols[i] + vols[i + 1]) / 2 for i in range(len(vols) - 1)
99
+ ]
100
+ ediff = np.diff(es)
101
+ ediff_sign = np.sign(ediff)
102
+ mask = ediff_sign != 0
103
+ ediff = ediff[mask]
104
+ ediff_sign = ediff_sign[mask]
105
+ ediff_flip = np.diff(ediff_sign) != 0
106
+
107
+ etv = np.sum(np.abs(np.diff(es)))
108
+
109
+ data = {
110
+ "model": model.name,
111
+ "structure": structure_id,
112
+ "formula": wbm_struct.get_chemical_formula(),
113
+ "missing": False,
114
+ "volume-ratio": vols / vol0,
115
+ "energy-delta-per-atom": (es - emin) / len(wbm_struct),
116
+ "energy-diff-flip-times": np.sum(ediff_flip).astype(int),
117
+ "tortuosity": etv / (abs(es[0] - emin) + abs(es[-1] - emin)),
118
+ "spearman-compression-energy": stats.spearmanr(
119
+ vols[:imine], es[:imine]
120
+ ).statistic,
121
+ "spearman-compression-derivative": stats.spearmanr(
122
+ interpolated_volumes[:imine], ediff[:imine]
123
+ ).statistic,
124
+ "spearman-tension-energy": stats.spearmanr(
125
+ vols[imine:], es[imine:]
126
+ ).statistic,
127
+ }
128
+
129
+ except Exception:
130
+ data = {
131
+ "model": model.name,
132
+ "structure": structure_id,
133
+ "formula": wbm_struct.get_chemical_formula(),
134
+ "missing": True,
135
+ "volume-ratio": None,
136
+ "energy-delta-per-atom": None,
137
+ "energy-diff-flip-times": None,
138
+ "tortuosity": None,
139
+ "spearman-compression-energy": None,
140
+ "spearman-compression-derivative": None,
141
+ "spearman-tension-energy": None,
142
+ }
143
+
144
+ df_analyzed = pd.concat([df_analyzed, pd.DataFrame([data])], ignore_index=True)
145
+
146
+ df_analyzed.to_parquet(DATA_DIR / f"{model.name}_processed.parquet")
147
+ # json_fpath = DATA_DIR / f"EV_scan_analyzed_{model.name}.json"
148
+
149
+ # df_analyzed.to_json(json_fpath, orient="records")
150
+
151
+ valid_results = df_analyzed[df_analyzed["missing"] == False]
152
+
153
+ analysis_summary = {
154
+ "model": model.name,
155
+ "energy-diff-flip-times": valid_results["energy-diff-flip-times"].mean(),
156
+ "tortuosity": valid_results["tortuosity"].mean(),
157
+ "spearman-compression-energy": valid_results[
158
+ "spearman-compression-energy"
159
+ ].mean(),
160
+ "spearman-compression-derivative": valid_results[
161
+ "spearman-compression-derivative"
162
+ ].mean(),
163
+ "spearman-tension-energy": valid_results["spearman-tension-energy"].mean(),
164
+ "missing": len(df_analyzed[df_analyzed["missing"] == True]),
165
+ }
166
+ summary_table = pd.concat(
167
+ [summary_table, pd.DataFrame([analysis_summary])], ignore_index=True
168
+ )
169
+
170
+
171
+ flip_rank = (
172
+ (summary_table["energy-diff-flip-times"] - 1)
173
+ .abs()
174
+ .rank(ascending=True, method="min")
175
+ )
176
+ tortuosity_rank = summary_table["tortuosity"].rank(ascending=True, method="min")
177
+ spearman_compression_energy_rank = summary_table["spearman-compression-energy"].rank(
178
+ method="min"
179
+ )
180
+ spearman_compression_derivative_rank = summary_table[
181
+ "spearman-compression-derivative"
182
+ ].rank(ascending=False, method="min")
183
+ spearman_tension_energy_rank = summary_table["spearman-tension-energy"].rank(
184
+ ascending=False, method="min"
185
+ )
186
+ missing_rank = summary_table["missing"].rank(ascending=True, method="min")
187
+
188
+ rank_aggr = (
189
+ flip_rank
190
+ + tortuosity_rank
191
+ + spearman_compression_energy_rank
192
+ + spearman_compression_derivative_rank
193
+ + spearman_tension_energy_rank
194
+ + missing_rank
195
+ )
196
+ rank = rank_aggr.rank(method="min")
197
+
198
+ summary_table.insert(1, "rank", rank.astype(int))
199
+ summary_table.insert(2, "rank-aggregation", rank_aggr.astype(int))
200
+ summary_table = summary_table.sort_values(by="rank", ascending=True)
201
+ summary_table = summary_table.reset_index(drop=True)
202
+
203
+ summary_table.to_csv(DATA_DIR / "summary.csv", index=False)
204
+ summary_table.to_latex(DATA_DIR / "summary.tex", index=False)
205
+
206
+ return summary_table
207
+
208
+ if __name__ == "__main__":
209
+ gather_results()
210
+ summarize()
mlip_arena/models/externals/fairchem.py CHANGED
@@ -87,7 +87,7 @@ class EquiformerV2(OCPCalculator):
87
  self,
88
  checkpoint=REGISTRY["EquiformerV2(OC22)"]["checkpoint"],
89
  # TODO: cannot assign device
90
- local_cache="/tmp/ocp/",
91
  cpu=False,
92
  seed=0,
93
  **kwargs,
@@ -114,7 +114,7 @@ class EquiformerV2OC20(OCPCalculator):
114
  self,
115
  checkpoint=REGISTRY["EquiformerV2(OC22)"]["checkpoint"],
116
  # TODO: cannot assign device
117
- local_cache="/tmp/ocp/",
118
  cpu=False,
119
  seed=0,
120
  **kwargs,
@@ -133,7 +133,7 @@ class eSCN(OCPCalculator):
133
  self,
134
  checkpoint="eSCN-L6-M3-Lay20-S2EF-OC20-All+MD", # TODO: import from registry
135
  # TODO: cannot assign device
136
- local_cache="/tmp/ocp/",
137
  cpu=False,
138
  seed=0,
139
  **kwargs,
 
87
  self,
88
  checkpoint=REGISTRY["EquiformerV2(OC22)"]["checkpoint"],
89
  # TODO: cannot assign device
90
+ local_cache="~/.cache/ocp/",
91
  cpu=False,
92
  seed=0,
93
  **kwargs,
 
114
  self,
115
  checkpoint=REGISTRY["EquiformerV2(OC22)"]["checkpoint"],
116
  # TODO: cannot assign device
117
+ local_cache="~/.cache/ocp/",
118
  cpu=False,
119
  seed=0,
120
  **kwargs,
 
133
  self,
134
  checkpoint="eSCN-L6-M3-Lay20-S2EF-OC20-All+MD", # TODO: import from registry
135
  # TODO: cannot assign device
136
+ local_cache="~/.cache/ocp/",
137
  cpu=False,
138
  seed=0,
139
  **kwargs,
mlip_arena/tasks/diatomics/homonuclear-diatomics.tex ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ \begin{tabular}{lrrrrrrrrrrr}
2
+ \toprule
3
+ & Rank & Rank aggr. & Conservation deviation [eV/Å] & Spearman's coeff. (E: repulsion) & Spearman's coeff. (F: descending) & Energy jump [eV] & Force flips & Tortuosity \\
4
+ Model & & & & & & & & \\
5
+ \midrule
6
+ MACE-MPA & 1 & 13 & 0.077 & -0.997 & -0.975 & 0.010 & 1.371 & 1.006 \\
7
+ MACE-MP(M) & 2 & 15 & 0.070 & -0.997 & -0.980 & 0.038 & 1.449 & 1.161 \\
8
+ MatterSim & 3 & 20 & 0.013 & -0.980 & -0.972 & 0.008 & 2.766 & 1.021 \\
9
+ M3GNet & 4 & 24 & 0.026 & -0.991 & -0.947 & 0.029 & 3.528 & 1.016 \\
10
+ ORBv2 & 5 & 30 & 9.751 & -0.883 & -0.988 & 0.991 & 0.991 & 1.287 \\
11
+ eSCN(OC20) & 6 & 32 & 2.045 & -0.939 & -0.984 & 0.806 & 0.640 & 5.335 \\
12
+ CHGNet & 7 & 35 & 1.066 & -0.992 & -0.925 & 0.291 & 2.255 & 2.279 \\
13
+ ORB & 8 & 39 & 10.220 & -0.881 & -0.954 & 1.019 & 1.026 & 1.798 \\
14
+ SevenNet & 9 & 41 & 34.005 & -0.986 & -0.928 & 0.392 & 2.112 & 1.292 \\
15
+ eqV2(OMat) & 10 & 51 & 15.477 & -0.880 & -0.976 & 4.118 & 3.126 & 2.515 \\
16
+ eSEN & 11 & 55 & 1.170 & -0.692 & -0.919 & 5.562 & 4.000 & 1.838 \\
17
+ ALIGNN & 12 & 59 & 5.164 & -0.913 & -0.310 & 9.876 & 30.669 & 1.818 \\
18
+ EquiformerV2(OC20) & 13 & 71 & 21.385 & -0.680 & -0.891 & 38.282 & 22.775 & 8.669 \\
19
+ EquiformerV2(OC22) & 14 & 75 & 27.687 & -0.415 & -0.855 & 64.837 & 21.674 & 15.880 \\
20
+ MACE-OFF(M) & 15 & 85 & NaN & NaN & NaN & NaN & NaN & NaN \\
21
+ ANI2x & 16 & 91 & NaN & NaN & NaN & NaN & NaN & NaN \\
22
+ \bottomrule
23
+ \end{tabular}
mlip_arena/tasks/registry.yaml CHANGED
@@ -31,3 +31,8 @@ Lattice thermal conductivity:
31
  task-page: thermal-conductivity
32
  task-layout: centered
33
  rank-page: thermal-conductivity
 
 
 
 
 
 
31
  task-page: thermal-conductivity
32
  task-layout: centered
33
  rank-page: thermal-conductivity
34
+ # 2D materials:
35
+ # category: Properties and Physical Behaviors
36
+ # task-page: c2db
37
+ # task-layout: centered
38
+ # rank-page:
serve/ranks/homonuclear-diatomics.py CHANGED
@@ -20,6 +20,24 @@ dfs = [
20
  ]
21
  df = pd.concat(dfs, ignore_index=True)
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  table = pd.DataFrame()
24
 
25
  for model in valid_models:
@@ -29,21 +47,13 @@ for model in valid_models:
29
  new_row = {
30
  "Model": model,
31
  "Conservation deviation [eV/Å]": rows["conservation-deviation"].mean(),
32
- "Spearman's coeff. (E: repulsion)": rows[
33
- "spearman-repulsion-energy"
34
- ].mean(),
35
- "Spearman's coeff. (F: descending)": rows[
36
- "spearman-descending-force"
37
- ].mean(),
38
  "Tortuosity": rows["tortuosity"].mean(),
39
  "Energy jump [eV]": rows["energy-jump"].mean(),
40
  "Force flips": rows["force-flip-times"].mean(),
41
- "Spearman's coeff. (E: attraction)": rows[
42
- "spearman-attraction-energy"
43
- ].mean(),
44
- "Spearman's coeff. (F: ascending)": rows[
45
- "spearman-ascending-force"
46
- ].mean(),
47
  "PBE energy MAE [eV]": rows["pbe-energy-mae"].mean(),
48
  "PBE force MAE [eV/Å]": rows["pbe-force-mae"].mean(),
49
  }
@@ -55,14 +65,10 @@ table.set_index("Model", inplace=True)
55
  table.sort_values("Conservation deviation [eV/Å]", ascending=True, inplace=True)
56
  table["Rank"] = np.argsort(table["Conservation deviation [eV/Å]"].to_numpy())
57
 
58
- table.sort_values(
59
- "Spearman's coeff. (E: repulsion)", ascending=True, inplace=True
60
- )
61
  table["Rank"] += np.argsort(table["Spearman's coeff. (E: repulsion)"].to_numpy())
62
 
63
- table.sort_values(
64
- "Spearman's coeff. (F: descending)", ascending=True, inplace=True
65
- )
66
  table["Rank"] += np.argsort(table["Spearman's coeff. (F: descending)"].to_numpy())
67
 
68
  # NOTE: it's not fair to models trained on different level of theory
@@ -83,28 +89,45 @@ table["Rank"] += np.argsort(np.abs(table["Force flips"].to_numpy() - 1))
83
 
84
  table["Rank"] += 1
85
 
86
- table.sort_values(["Rank", "Conservation deviation [eV/Å]"], ascending=True, inplace=True)
 
 
87
 
88
  table["Rank aggr."] = table["Rank"]
89
- table["Rank"] = table["Rank aggr."].rank(method='min').astype(int)
90
 
91
  table = table.reindex(
92
  columns=[
93
  "Rank",
94
  "Rank aggr.",
95
  "Conservation deviation [eV/Å]",
96
- "PBE energy MAE [eV]",
97
- "PBE force MAE [eV/Å]",
98
  "Spearman's coeff. (E: repulsion)",
99
  "Spearman's coeff. (F: descending)",
100
  "Energy jump [eV]",
101
  "Force flips",
102
  "Tortuosity",
 
 
103
  "Spearman's coeff. (E: attraction)",
104
  "Spearman's coeff. (F: ascending)",
105
  ]
106
  )
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  s = (
109
  table.style.background_gradient(
110
  cmap="viridis_r",
@@ -135,7 +158,7 @@ s = (
135
  subset=["Rank", "Rank aggr."],
136
  )
137
  .format(
138
- "{:.3f}",
139
  subset=[
140
  "Conservation deviation [eV/Å]",
141
  "Spearman's coeff. (E: repulsion)",
@@ -147,7 +170,7 @@ s = (
147
  "Spearman's coeff. (F: ascending)",
148
  "PBE energy MAE [eV]",
149
  "PBE force MAE [eV/Å]",
150
- ]
151
  )
152
  )
153
 
@@ -177,4 +200,7 @@ def render():
177
  - **Force flips**: The number of force direction changes.
178
  """
179
  )
180
- st.info('PBE energies and forces are provided __only__ for reference. Due to the known convergence issue of plane-wave DFT with diatomic molecules and different dataset the models might be trained on, comparing models with PBE is not rigorous and thus these metrics are excluded from rank aggregation.', icon=":material/warning:")
 
 
 
 
20
  ]
21
  df = pd.concat(dfs, ignore_index=True)
22
 
23
+ # df = df[df["method"].isin([
24
+ # "SevenNet",
25
+ # "ORBv2",
26
+ # "ORB",
27
+ # "MatterSim",
28
+ # "MACE-MPA",
29
+ # "MACE-MP(M)",
30
+ # "M3GNet",
31
+ # "eSEN",
32
+ # "eSCN(OC20)",
33
+ # "eqV2(OMat)",
34
+ # "EquiformerV2(OC22)",
35
+ # "EquiformerV2(OC20)",
36
+ # "CHGNet",
37
+ # "ALIGNN"
38
+ # ]
39
+ # )]
40
+
41
  table = pd.DataFrame()
42
 
43
  for model in valid_models:
 
47
  new_row = {
48
  "Model": model,
49
  "Conservation deviation [eV/Å]": rows["conservation-deviation"].mean(),
50
+ "Spearman's coeff. (E: repulsion)": rows["spearman-repulsion-energy"].mean(),
51
+ "Spearman's coeff. (F: descending)": rows["spearman-descending-force"].mean(),
 
 
 
 
52
  "Tortuosity": rows["tortuosity"].mean(),
53
  "Energy jump [eV]": rows["energy-jump"].mean(),
54
  "Force flips": rows["force-flip-times"].mean(),
55
+ "Spearman's coeff. (E: attraction)": rows["spearman-attraction-energy"].mean(),
56
+ "Spearman's coeff. (F: ascending)": rows["spearman-ascending-force"].mean(),
 
 
 
 
57
  "PBE energy MAE [eV]": rows["pbe-energy-mae"].mean(),
58
  "PBE force MAE [eV/Å]": rows["pbe-force-mae"].mean(),
59
  }
 
65
  table.sort_values("Conservation deviation [eV/Å]", ascending=True, inplace=True)
66
  table["Rank"] = np.argsort(table["Conservation deviation [eV/Å]"].to_numpy())
67
 
68
+ table.sort_values("Spearman's coeff. (E: repulsion)", ascending=True, inplace=True)
 
 
69
  table["Rank"] += np.argsort(table["Spearman's coeff. (E: repulsion)"].to_numpy())
70
 
71
+ table.sort_values("Spearman's coeff. (F: descending)", ascending=True, inplace=True)
 
 
72
  table["Rank"] += np.argsort(table["Spearman's coeff. (F: descending)"].to_numpy())
73
 
74
  # NOTE: it's not fair to models trained on different level of theory
 
89
 
90
  table["Rank"] += 1
91
 
92
+ table.sort_values(
93
+ ["Rank", "Conservation deviation [eV/Å]"], ascending=True, inplace=True
94
+ )
95
 
96
  table["Rank aggr."] = table["Rank"]
97
+ table["Rank"] = table["Rank aggr."].rank(method="min").astype(int)
98
 
99
  table = table.reindex(
100
  columns=[
101
  "Rank",
102
  "Rank aggr.",
103
  "Conservation deviation [eV/Å]",
 
 
104
  "Spearman's coeff. (E: repulsion)",
105
  "Spearman's coeff. (F: descending)",
106
  "Energy jump [eV]",
107
  "Force flips",
108
  "Tortuosity",
109
+ "PBE energy MAE [eV]",
110
+ "PBE force MAE [eV/Å]",
111
  "Spearman's coeff. (E: attraction)",
112
  "Spearman's coeff. (F: ascending)",
113
  ]
114
  )
115
 
116
+ # cloned = table.copy()
117
+ # cloned.drop(columns=[
118
+ # "PBE energy MAE [eV]",
119
+ # "PBE force MAE [eV/Å]",
120
+ # "Spearman's coeff. (E: attraction)",
121
+ # "Spearman's coeff. (F: ascending)",],
122
+ # inplace=True
123
+ # )
124
+ # cloned.to_latex(
125
+ # DATA_DIR / "homonuclear-diatomics.tex",
126
+ # float_format="%.3f",
127
+ # index=True,
128
+ # column_format="l" + "r" * (len(table.columns) - 1),
129
+ # )
130
+
131
  s = (
132
  table.style.background_gradient(
133
  cmap="viridis_r",
 
158
  subset=["Rank", "Rank aggr."],
159
  )
160
  .format(
161
+ "{:.3f}",
162
  subset=[
163
  "Conservation deviation [eV/Å]",
164
  "Spearman's coeff. (E: repulsion)",
 
170
  "Spearman's coeff. (F: ascending)",
171
  "PBE energy MAE [eV]",
172
  "PBE force MAE [eV/Å]",
173
+ ],
174
  )
175
  )
176
 
 
200
  - **Force flips**: The number of force direction changes.
201
  """
202
  )
203
+ st.info(
204
+ "PBE energies and forces are provided __only__ for reference. Due to the known convergence issue of plane-wave DFT with diatomic molecules and different dataset the models might be trained on, comparing models with PBE is not rigorous and thus these metrics are excluded from rank aggregation.",
205
+ icon=":material/warning:",
206
+ )
serve/tasks/eos_bulk.py CHANGED
@@ -34,7 +34,7 @@ selected_models = methods_container.multiselect(
34
  )
35
 
36
  # Visualization settings
37
- st.markdown("### Visualization Settings")
38
  vis = st.container(border=True)
39
 
40
  # Column settings
@@ -83,6 +83,7 @@ def generate_dataframe(model_name):
83
  "formula",
84
  "volume-ratio",
85
  "energy-delta-per-atom",
 
86
  "energy-diff-flip-times",
87
  "tortuosity",
88
  "spearman-compression-energy",
@@ -97,10 +98,12 @@ def generate_dataframe(model_name):
97
 
98
  try:
99
  results = df_raw_results.loc[df_raw_results["id"] == structure_id]
 
 
100
  results = results["eos"].values[0]
101
  es = np.array(results["energies"])
102
  vols = np.array(results["volumes"])
103
- vol0 = wbm_struct.get_volume()
104
 
105
  indices = np.argsort(vols)
106
  vols = vols[indices]
@@ -110,6 +113,7 @@ def generate_dataframe(model_name):
110
  # min_center_val = np.min(es[imid - 1 : imid + 2])
111
  # imine = np.where(es == min_center_val)[0][0]
112
  emin = es[imine]
 
113
 
114
  interpolated_volumes = [
115
  (vols[i] + vols[i + 1]) / 2 for i in range(len(vols) - 1)
@@ -131,6 +135,7 @@ def generate_dataframe(model_name):
131
  "volume-ratio": vols / vol0,
132
  "energy-delta-per-atom": (es - emin) / len(wbm_struct),
133
  "energy-diff-flip-times": np.sum(ediff_flip).astype(int),
 
134
  "tortuosity": etv / (abs(es[0] - emin) + abs(es[-1] - emin)),
135
  "spearman-compression-energy": stats.spearmanr(
136
  vols[:imine], es[:imine]
@@ -151,6 +156,7 @@ def generate_dataframe(model_name):
151
  "missing": True,
152
  "volume-ratio": None,
153
  "energy-delta-per-atom": None,
 
154
  "energy-diff-flip-times": None,
155
  "tortuosity": None,
156
  "spearman-compression-energy": None,
@@ -185,10 +191,10 @@ def get_plots(selected_models):
185
  structure_id = row["structure"]
186
  formula = row.get("formula", "")
187
  if isinstance(row["volume-ratio"], list | np.ndarray) and isinstance(
188
- row["energy-delta-per-atom"], list | np.ndarray
189
  ):
190
  vol_strain = row["volume-ratio"]
191
- energy_delta = row["energy-delta-per-atom"]
192
  color = color_sequence[i % len(color_sequence)]
193
  fig.add_trace(
194
  go.Scatter(
@@ -203,7 +209,7 @@ def get_plots(selected_models):
203
  structure_id + "<br>"
204
  "Formula: " + str(formula) + "<br>"
205
  "Volume ratio V/V₀: %{x:.3f}<br>"
206
- Energy: %{y:.3f} eV/atom<br>"
207
  "<extra></extra>"
208
  ),
209
 
@@ -215,10 +221,10 @@ def get_plots(selected_models):
215
  fig.update_layout(
216
  title=f"{model_name} ({len(valid_structures)} / {len(df)} structures)",
217
  xaxis_title="Volume ratio V/V₀",
218
- yaxis_title="Relative energy ΔE (eV/atom)",
219
  height=500,
220
  showlegend=False, # Disable legend for the whole plot
221
- yaxis=dict(range=[-0.1, 1]), # Set y-axis limits
222
  )
223
  fig.add_vline(x=1, line_dash="dash", line_color="gray", opacity=0.7)
224
  figs.append((model_name, fig, valid_structures))
 
34
  )
35
 
36
  # Visualization settings
37
+ st.markdown("### Visualization settings")
38
  vis = st.container(border=True)
39
 
40
  # Column settings
 
83
  "formula",
84
  "volume-ratio",
85
  "energy-delta-per-atom",
86
+ "energy-delta-per-volume-b0",
87
  "energy-diff-flip-times",
88
  "tortuosity",
89
  "spearman-compression-energy",
 
98
 
99
  try:
100
  results = df_raw_results.loc[df_raw_results["id"] == structure_id]
101
+ b0 = results["b0"].values[0]
102
+ # vol0 = results["v0"].values[0]
103
  results = results["eos"].values[0]
104
  es = np.array(results["energies"])
105
  vols = np.array(results["volumes"])
106
+
107
 
108
  indices = np.argsort(vols)
109
  vols = vols[indices]
 
113
  # min_center_val = np.min(es[imid - 1 : imid + 2])
114
  # imine = np.where(es == min_center_val)[0][0]
115
  emin = es[imine]
116
+ vol0 = vols[imine]
117
 
118
  interpolated_volumes = [
119
  (vols[i] + vols[i + 1]) / 2 for i in range(len(vols) - 1)
 
135
  "volume-ratio": vols / vol0,
136
  "energy-delta-per-atom": (es - emin) / len(wbm_struct),
137
  "energy-diff-flip-times": np.sum(ediff_flip).astype(int),
138
+ "energy-delta-per-volume-b0": (es - emin) / (vol0 * b0),
139
  "tortuosity": etv / (abs(es[0] - emin) + abs(es[-1] - emin)),
140
  "spearman-compression-energy": stats.spearmanr(
141
  vols[:imine], es[:imine]
 
156
  "missing": True,
157
  "volume-ratio": None,
158
  "energy-delta-per-atom": None,
159
+ "energy-delta-per-volume-b0": None,
160
  "energy-diff-flip-times": None,
161
  "tortuosity": None,
162
  "spearman-compression-energy": None,
 
191
  structure_id = row["structure"]
192
  formula = row.get("formula", "")
193
  if isinstance(row["volume-ratio"], list | np.ndarray) and isinstance(
194
+ row["energy-delta-per-volume-b0"], list | np.ndarray
195
  ):
196
  vol_strain = row["volume-ratio"]
197
+ energy_delta = row["energy-delta-per-volume-b0"]
198
  color = color_sequence[i % len(color_sequence)]
199
  fig.add_trace(
200
  go.Scatter(
 
209
  structure_id + "<br>"
210
  "Formula: " + str(formula) + "<br>"
211
  "Volume ratio V/V₀: %{x:.3f}<br>"
212
+ E/(BV₀): %{y:.3f} eV/atom<br>"
213
  "<extra></extra>"
214
  ),
215
 
 
221
  fig.update_layout(
222
  title=f"{model_name} ({len(valid_structures)} / {len(df)} structures)",
223
  xaxis_title="Volume ratio V/V₀",
224
+ yaxis_title="Relative energy ΔE/(BV₀)",
225
  height=500,
226
  showlegend=False, # Disable legend for the whole plot
227
+ yaxis=dict(range=[-0.02, 0.1]), # Set y-axis limits
228
  )
229
  fig.add_vline(x=1, line_dash="dash", line_color="gray", opacity=0.7)
230
  figs.append((model_name, fig, valid_structures))