netsunhinged 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netsunhinged-0.1.0/CITATION.cff +36 -0
- netsunhinged-0.1.0/LICENSE +30 -0
- netsunhinged-0.1.0/MANIFEST.in +3 -0
- netsunhinged-0.1.0/PKG-INFO +152 -0
- netsunhinged-0.1.0/README.md +125 -0
- netsunhinged-0.1.0/netsunhinged/__init__.py +18 -0
- netsunhinged-0.1.0/netsunhinged/__main__.py +83 -0
- netsunhinged-0.1.0/netsunhinged/cif.py +530 -0
- netsunhinged-0.1.0/netsunhinged/deform.py +367 -0
- netsunhinged-0.1.0/netsunhinged/elements.py +47 -0
- netsunhinged-0.1.0/netsunhinged/examples/DMOF-1_COD-7038645.cif +353 -0
- netsunhinged-0.1.0/netsunhinged/examples/HKUST-1_COD-4128729.cif +458 -0
- netsunhinged-0.1.0/netsunhinged/examples/MIL-53-Ga_COD-7000776.cif +102 -0
- netsunhinged-0.1.0/netsunhinged/examples/MOF-5_COD-7240544.cif +429 -0
- netsunhinged-0.1.0/netsunhinged/examples/Natrolite_COD-9013163.cif +99 -0
- netsunhinged-0.1.0/netsunhinged/examples/README.md +34 -0
- netsunhinged-0.1.0/netsunhinged/examples/ZIF-7_COD-4121899.cif +465 -0
- netsunhinged-0.1.0/netsunhinged/examples/ZIF-8_COD-7111971.cif +416 -0
- netsunhinged-0.1.0/netsunhinged/examples/Zeolite-A_COD-1532589.cif +166 -0
- netsunhinged-0.1.0/netsunhinged/examples/Zeolite-Rho_COD-1530545.cif +113 -0
- netsunhinged-0.1.0/netsunhinged/examples/catalog.json +90 -0
- netsunhinged-0.1.0/netsunhinged/examples/rho-ZnIm2_COD-4132678.cif +390 -0
- netsunhinged-0.1.0/netsunhinged/geometry.py +151 -0
- netsunhinged-0.1.0/netsunhinged/model.py +454 -0
- netsunhinged-0.1.0/netsunhinged/rigidity.py +234 -0
- netsunhinged-0.1.0/netsunhinged/server.py +661 -0
- netsunhinged-0.1.0/netsunhinged/static/app.js +1257 -0
- netsunhinged-0.1.0/netsunhinged/static/index.html +168 -0
- netsunhinged-0.1.0/netsunhinged/static/style.css +162 -0
- netsunhinged-0.1.0/netsunhinged/static/vendor/three/LICENSE +21 -0
- netsunhinged-0.1.0/netsunhinged/static/vendor/three/addons/controls/OrbitControls.js +1417 -0
- netsunhinged-0.1.0/netsunhinged/static/vendor/three/three.module.min.js +6 -0
- netsunhinged-0.1.0/netsunhinged/structure.py +532 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/PKG-INFO +152 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/SOURCES.txt +41 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/dependency_links.txt +1 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/entry_points.txt +2 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/requires.txt +8 -0
- netsunhinged-0.1.0/netsunhinged.egg-info/top_level.txt +1 -0
- netsunhinged-0.1.0/pyproject.toml +48 -0
- netsunhinged-0.1.0/setup.cfg +4 -0
- netsunhinged-0.1.0/tests/reference_structures.py +188 -0
- netsunhinged-0.1.0/tests/test_netsunhinged.py +289 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use NetsUnhinged, please cite it as below, together with the method paper by Sarkisov et al."
|
|
3
|
+
title: "NetsUnhinged: rigid-body / hinge flexibility analysis of framework materials"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: "Weiss"
|
|
7
|
+
given-names: "Jan-Benedikt"
|
|
8
|
+
affiliation: "TU Dortmund University"
|
|
9
|
+
# orcid: "https://orcid.org/0000-0000-0000-0000"
|
|
10
|
+
license: MIT
|
|
11
|
+
version: 0.1.0
|
|
12
|
+
date-released: "2026-10-23"
|
|
13
|
+
repository-code: "https://github.com/JBWeiss-chem/netsunhinged"
|
|
14
|
+
keywords:
|
|
15
|
+
- metal-organic frameworks
|
|
16
|
+
- zeolites
|
|
17
|
+
- flexibility
|
|
18
|
+
- rigidity
|
|
19
|
+
- crystallography
|
|
20
|
+
references:
|
|
21
|
+
- type: article
|
|
22
|
+
title: "On the Flexibility of Metal–Organic Frameworks"
|
|
23
|
+
authors:
|
|
24
|
+
- family-names: "Sarkisov"
|
|
25
|
+
given-names: "Lev"
|
|
26
|
+
- family-names: "Martin"
|
|
27
|
+
given-names: "Richard L."
|
|
28
|
+
- family-names: "Haranczyk"
|
|
29
|
+
given-names: "Maciej"
|
|
30
|
+
- family-names: "Smit"
|
|
31
|
+
given-names: "Berend"
|
|
32
|
+
journal: "Journal of the American Chemical Society"
|
|
33
|
+
year: 2014
|
|
34
|
+
volume: 136
|
|
35
|
+
start: 2228
|
|
36
|
+
doi: "10.1021/ja411673b"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jan-Benedikt Weiss
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---------------------------------------------------------------------------------
|
|
24
|
+
Third-party components
|
|
25
|
+
|
|
26
|
+
* three.js (netsunhinged/static/vendor/three/): MIT License, Copyright 2010-2023
|
|
27
|
+
three.js authors. See netsunhinged/static/vendor/three/LICENSE.
|
|
28
|
+
* Example structures (netsunhinged/examples/): from the Crystallography Open
|
|
29
|
+
Database, dedicated to the public domain (CC0). See
|
|
30
|
+
netsunhinged/examples/README.md for the original publications.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: netsunhinged
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Is your net unhinged? Rigid-body / hinge flexibility analysis of framework materials (MOFs, ZIFs, zeolites)
|
|
5
|
+
Author: Jan-Benedikt Weiss
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/JBWeiss-chem/netsunhinged
|
|
8
|
+
Project-URL: Issues, https://github.com/JBWeiss-chem/netsunhinged/issues
|
|
9
|
+
Keywords: metal-organic frameworks,MOF,zeolites,flexibility,rigidity,crystallography,CIF
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
License-File: netsunhinged/static/vendor/three/LICENSE
|
|
20
|
+
Requires-Dist: numpy>=1.22
|
|
21
|
+
Requires-Dist: scipy>=1.8
|
|
22
|
+
Provides-Extra: server
|
|
23
|
+
Requires-Dist: gunicorn>=22; extra == "server"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# NetsUnhinged
|
|
29
|
+
|
|
30
|
+
A vibe-coded web app that predicts whether a framework material (MOFs, ZIFs, zeolites and other nets)
|
|
31
|
+
is **potentially flexible** by treating it as a periodic network of rigid bodies joined by hinges
|
|
32
|
+
and pivots. It implements and generalises
|
|
33
|
+
|
|
34
|
+
> L. Sarkisov, R. L. Martin, M. Haranczyk, B. Smit, *On the Flexibility of Metal–Organic
|
|
35
|
+
> Frameworks*, J. Am. Chem. Soc. **2014**, 136, 2228, [doi:10.1021/ja411673b](https://doi.org/10.1021/ja411673b).
|
|
36
|
+
|
|
37
|
+
What it does:
|
|
38
|
+
|
|
39
|
+
* reads a CIF (symmetry expansion, removal of guests, H and other dangling atoms),
|
|
40
|
+
* shows the structure in 3D, coloured by element, rigid body, or degrees of freedom,
|
|
41
|
+
* lets you **click atoms and bonds to choose what is flexible**,
|
|
42
|
+
* analyses the resulting mechanism twice: once infinitesimally (exact linear algebra) and once with the
|
|
43
|
+
paper's finite deformation test (13 cell-perturbation regimes).
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
NetsUnhinged needs Python ≥ 3.10 and installs `numpy` and `scipy`. three.js (0.160.0, MIT licence)
|
|
48
|
+
is bundled, so the viewer works offline and makes no third-party requests.
|
|
49
|
+
|
|
50
|
+
NetsUnhinged is on [PyPI](https://pypi.org/project/netsunhinged/).
|
|
51
|
+
|
|
52
|
+
**Without Python, with uv (simplest).** [uv](https://docs.astral.sh/uv/) downloads Python by
|
|
53
|
+
itself. Install uv once (macOS / Linux):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
or on Windows (PowerShell):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then start the app at any time with:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uvx netsunhinged
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
or install the `netsunhinged` command permanently with `uv tool install netsunhinged`. If the
|
|
72
|
+
command is not found afterwards, run `uv tool update-shell` and open a new terminal.
|
|
73
|
+
|
|
74
|
+
**With pipx.** [pipx](https://pipx.pypa.io) installs the app in its own environment and puts the
|
|
75
|
+
`netsunhinged` command on your PATH:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pipx install netsunhinged
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**With pip**, ideally inside a virtual environment or conda environment:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install netsunhinged
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**With Docker** (then open http://localhost:8765):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
docker run --rm -p 8765:8765 ghcr.io/jbweiss-chem/netsunhinged
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**The latest development version** from GitHub:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pipx install git+https://github.com/JBWeiss-chem/netsunhinged
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
To update: `uv tool upgrade netsunhinged`, `pipx upgrade netsunhinged`, `pip install --upgrade
|
|
100
|
+
netsunhinged` or `docker pull` the image. `uvx` reuses the version it downloaded first; run
|
|
101
|
+
`uvx netsunhinged@latest` to get the newest release.
|
|
102
|
+
|
|
103
|
+
## Usage
|
|
104
|
+
|
|
105
|
+
After installing, start the app with:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
netsunhinged
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Your browser opens the app at http://127.0.0.1:8765. It runs only on your computer: nothing is
|
|
112
|
+
uploaded anywhere. Stop it with Ctrl+C in the terminal. `netsunhinged serve` does the same and takes
|
|
113
|
+
options: `--port 9000` uses another port, `--no-browser` does not open a browser window.
|
|
114
|
+
|
|
115
|
+
If the command is not found (e.g. because the environment you installed it into is not active), use
|
|
116
|
+
`python -m netsunhinged` instead.
|
|
117
|
+
|
|
118
|
+
Analyse CIF files from the command line:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
netsunhinged analyze my.cif other.cif --preset paper
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`netsunhinged analyze --help` lists all options. `python -m netsunhinged` works as well.
|
|
125
|
+
|
|
126
|
+
The **Examples** menu lists the literature structures in `netsunhinged/examples/`: open-licence (CC0)
|
|
127
|
+
copies from the Crystallography Open Database, named `{trivial name}_COD-{id}.cif` (see
|
|
128
|
+
`netsunhinged/examples/README.md`). In a source checkout, files in `examples_local/` (e.g. CSD
|
|
129
|
+
downloads, which may not be redistributed) appear locally as "Local only" and are never published.
|
|
130
|
+
|
|
131
|
+
## Limitations
|
|
132
|
+
|
|
133
|
+
* This is a screening tool. As the paper notes, it finds *potential* modes. Energetics, sterics and
|
|
134
|
+
guest effects need force-field or DFT follow-up.
|
|
135
|
+
* The model is all-or-nothing: an angle or torsion is either fixed or completely free. A mechanism
|
|
136
|
+
or a "flexible" regime therefore means that the deformation is possible without distorting any
|
|
137
|
+
rigid body, not that it costs no energy. In the material, the released angles and torsions,
|
|
138
|
+
non-bonded interactions and guests still resist it. The reported E and F measure the geometric
|
|
139
|
+
mismatch at the joints (Ų), not an energy.
|
|
140
|
+
* Bodies are geometric: atoms have no size, so very large deformations can pass through each other.
|
|
141
|
+
Inspect the deformed frames.
|
|
142
|
+
* Bonds come from covalent radii (+0.45 Å). Only the first disorder component is kept, and partially
|
|
143
|
+
occupied sites are kept as full atoms.
|
|
144
|
+
* Frameworks with fewer than 3 periodic dimensions (layers, chains) have no bonds, and so no
|
|
145
|
+
constraints, in the remaining directions. The model reports them as flexible there, although
|
|
146
|
+
interlayer or interchain interactions may hold them in place. A warning is shown.
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT, see `LICENSE`. The bundled three.js is MIT-licensed as well. The example structures come from
|
|
151
|
+
the Crystallography Open Database and are in the public domain (CC0); please cite the original
|
|
152
|
+
publications listed in `netsunhinged/examples/README.md`.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# NetsUnhinged
|
|
2
|
+
|
|
3
|
+
A vibe-coded web app that predicts whether a framework material (MOFs, ZIFs, zeolites and other nets)
|
|
4
|
+
is **potentially flexible** by treating it as a periodic network of rigid bodies joined by hinges
|
|
5
|
+
and pivots. It implements and generalises
|
|
6
|
+
|
|
7
|
+
> L. Sarkisov, R. L. Martin, M. Haranczyk, B. Smit, *On the Flexibility of Metal–Organic
|
|
8
|
+
> Frameworks*, J. Am. Chem. Soc. **2014**, 136, 2228, [doi:10.1021/ja411673b](https://doi.org/10.1021/ja411673b).
|
|
9
|
+
|
|
10
|
+
What it does:
|
|
11
|
+
|
|
12
|
+
* reads a CIF (symmetry expansion, removal of guests, H and other dangling atoms),
|
|
13
|
+
* shows the structure in 3D, coloured by element, rigid body, or degrees of freedom,
|
|
14
|
+
* lets you **click atoms and bonds to choose what is flexible**,
|
|
15
|
+
* analyses the resulting mechanism twice: once infinitesimally (exact linear algebra) and once with the
|
|
16
|
+
paper's finite deformation test (13 cell-perturbation regimes).
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
NetsUnhinged needs Python ≥ 3.10 and installs `numpy` and `scipy`. three.js (0.160.0, MIT licence)
|
|
21
|
+
is bundled, so the viewer works offline and makes no third-party requests.
|
|
22
|
+
|
|
23
|
+
NetsUnhinged is on [PyPI](https://pypi.org/project/netsunhinged/).
|
|
24
|
+
|
|
25
|
+
**Without Python, with uv (simplest).** [uv](https://docs.astral.sh/uv/) downloads Python by
|
|
26
|
+
itself. Install uv once (macOS / Linux):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
or on Windows (PowerShell):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then start the app at any time with:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uvx netsunhinged
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
or install the `netsunhinged` command permanently with `uv tool install netsunhinged`. If the
|
|
45
|
+
command is not found afterwards, run `uv tool update-shell` and open a new terminal.
|
|
46
|
+
|
|
47
|
+
**With pipx.** [pipx](https://pipx.pypa.io) installs the app in its own environment and puts the
|
|
48
|
+
`netsunhinged` command on your PATH:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pipx install netsunhinged
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**With pip**, ideally inside a virtual environment or conda environment:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install netsunhinged
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**With Docker** (then open http://localhost:8765):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
docker run --rm -p 8765:8765 ghcr.io/jbweiss-chem/netsunhinged
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**The latest development version** from GitHub:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pipx install git+https://github.com/JBWeiss-chem/netsunhinged
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To update: `uv tool upgrade netsunhinged`, `pipx upgrade netsunhinged`, `pip install --upgrade
|
|
73
|
+
netsunhinged` or `docker pull` the image. `uvx` reuses the version it downloaded first; run
|
|
74
|
+
`uvx netsunhinged@latest` to get the newest release.
|
|
75
|
+
|
|
76
|
+
## Usage
|
|
77
|
+
|
|
78
|
+
After installing, start the app with:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
netsunhinged
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Your browser opens the app at http://127.0.0.1:8765. It runs only on your computer: nothing is
|
|
85
|
+
uploaded anywhere. Stop it with Ctrl+C in the terminal. `netsunhinged serve` does the same and takes
|
|
86
|
+
options: `--port 9000` uses another port, `--no-browser` does not open a browser window.
|
|
87
|
+
|
|
88
|
+
If the command is not found (e.g. because the environment you installed it into is not active), use
|
|
89
|
+
`python -m netsunhinged` instead.
|
|
90
|
+
|
|
91
|
+
Analyse CIF files from the command line:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
netsunhinged analyze my.cif other.cif --preset paper
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`netsunhinged analyze --help` lists all options. `python -m netsunhinged` works as well.
|
|
98
|
+
|
|
99
|
+
The **Examples** menu lists the literature structures in `netsunhinged/examples/`: open-licence (CC0)
|
|
100
|
+
copies from the Crystallography Open Database, named `{trivial name}_COD-{id}.cif` (see
|
|
101
|
+
`netsunhinged/examples/README.md`). In a source checkout, files in `examples_local/` (e.g. CSD
|
|
102
|
+
downloads, which may not be redistributed) appear locally as "Local only" and are never published.
|
|
103
|
+
|
|
104
|
+
## Limitations
|
|
105
|
+
|
|
106
|
+
* This is a screening tool. As the paper notes, it finds *potential* modes. Energetics, sterics and
|
|
107
|
+
guest effects need force-field or DFT follow-up.
|
|
108
|
+
* The model is all-or-nothing: an angle or torsion is either fixed or completely free. A mechanism
|
|
109
|
+
or a "flexible" regime therefore means that the deformation is possible without distorting any
|
|
110
|
+
rigid body, not that it costs no energy. In the material, the released angles and torsions,
|
|
111
|
+
non-bonded interactions and guests still resist it. The reported E and F measure the geometric
|
|
112
|
+
mismatch at the joints (Ų), not an energy.
|
|
113
|
+
* Bodies are geometric: atoms have no size, so very large deformations can pass through each other.
|
|
114
|
+
Inspect the deformed frames.
|
|
115
|
+
* Bonds come from covalent radii (+0.45 Å). Only the first disorder component is kept, and partially
|
|
116
|
+
occupied sites are kept as full atoms.
|
|
117
|
+
* Frameworks with fewer than 3 periodic dimensions (layers, chains) have no bonds, and so no
|
|
118
|
+
constraints, in the remaining directions. The model reports them as flexible there, although
|
|
119
|
+
interlayer or interchain interactions may hold them in place. A warning is shown.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT, see `LICENSE`. The bundled three.js is MIT-licensed as well. The example structures come from
|
|
124
|
+
the Crystallography Open Database and are in the public domain (CC0); please cite the original
|
|
125
|
+
publications listed in `netsunhinged/examples/README.md`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""NetsUnhinged - large-amplitude flexibility of framework materials (MOFs, ZIFs, zeolites)
|
|
2
|
+
from rigid-body / hinge models.
|
|
3
|
+
|
|
4
|
+
Implements and generalises the approach of Sarkisov, Martin, Haranczyk & Smit,
|
|
5
|
+
"On the Flexibility of Metal-Organic Frameworks", J. Am. Chem. Soc. 2014, 136, 2228.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .cif import read_cif
|
|
9
|
+
from .structure import Structure
|
|
10
|
+
from .model import MechanicalModel, ModelOptions, preset
|
|
11
|
+
|
|
12
|
+
__all__ = ["read_cif", "Structure", "MechanicalModel", "ModelOptions", "preset", "load"]
|
|
13
|
+
__version__ = "0.1.0"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load(path):
|
|
17
|
+
with open(path, encoding="utf-8", errors="replace") as fh:
|
|
18
|
+
return Structure(read_cif(fh.read()))
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Command line: ``python -m netsunhinged [serve|analyze] ...``"""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def cmd_analyze(args):
|
|
11
|
+
from . import deform, load, rigidity
|
|
12
|
+
from .model import MechanicalModel, ModelOptions, preset
|
|
13
|
+
|
|
14
|
+
rows = []
|
|
15
|
+
for path in args.cif:
|
|
16
|
+
st = load(path)
|
|
17
|
+
if args.options:
|
|
18
|
+
with open(args.options, encoding="utf-8") as fh:
|
|
19
|
+
opts = ModelOptions.from_dict(json.load(fh))
|
|
20
|
+
else:
|
|
21
|
+
opts = preset(st, args.preset)
|
|
22
|
+
m = MechanicalModel(st, opts)
|
|
23
|
+
rig = rigidity.analyze(m)
|
|
24
|
+
print(f"\n=== {path} ({st.formula(st.framework)}, {st.N} atoms, {st.n_guest} guest atoms)")
|
|
25
|
+
for w in st.warnings:
|
|
26
|
+
print(" warning:", w)
|
|
27
|
+
s = m.summary()
|
|
28
|
+
print(f" model: {s['n_bodies']} rigid bodies, {s['n_hinges']} hinges, "
|
|
29
|
+
f"{s['n_ball_joints']} ball joints, {s['n_flex_angle_atoms']} pivot atoms")
|
|
30
|
+
print(f" infinitesimal: {rig['n_macroscopic']} cell-changing mechanism(s), "
|
|
31
|
+
f"{rig['n_internal']} internal mechanism(s)")
|
|
32
|
+
for k, md in enumerate(rig["macroscopic_modes"]):
|
|
33
|
+
print(f" mode {k + 1}: {md['kind']}: {md['description']}")
|
|
34
|
+
verdict = "-"
|
|
35
|
+
if not args.no_finite:
|
|
36
|
+
regimes = list(deform.REGIMES) + (list(deform.EXTENDED) if args.extended else [])
|
|
37
|
+
_, res, verdict, dt = deform.run_all(
|
|
38
|
+
m, regimes=regimes, step=args.step, metric=args.metric,
|
|
39
|
+
thr=args.thr, thr2=args.thr2, modes=rig["macroscopic_modes"])
|
|
40
|
+
print(f" finite deformation ({dt:.1f} s):")
|
|
41
|
+
key = "F" if args.metric == "relative" else "E"
|
|
42
|
+
for name, r in res.items():
|
|
43
|
+
mx = max(p[key] for p in r["points"])
|
|
44
|
+
print(f" {name:8s} {r['classification']:14s} max {key} = {mx:9.2e} {r['detail']}")
|
|
45
|
+
print(f" VERDICT: {verdict.upper()}")
|
|
46
|
+
rows.append((path, rig["n_macroscopic"], verdict))
|
|
47
|
+
if len(rows) > 1:
|
|
48
|
+
print("\nsummary:")
|
|
49
|
+
for path, nm, v in rows:
|
|
50
|
+
print(f" {v:14s} {nm} mode(s) {path}")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main(argv=None):
|
|
54
|
+
p = argparse.ArgumentParser(prog="netsunhinged", description=__doc__)
|
|
55
|
+
sub = p.add_subparsers(dest="cmd")
|
|
56
|
+
s = sub.add_parser("serve", help="start the interactive web app")
|
|
57
|
+
s.add_argument("--port", type=int, default=8765)
|
|
58
|
+
s.add_argument("--host", default="127.0.0.1")
|
|
59
|
+
s.add_argument("--no-browser", action="store_true")
|
|
60
|
+
a = sub.add_parser("analyze", help="analyse CIF files from the command line")
|
|
61
|
+
a.add_argument("cif", nargs="+")
|
|
62
|
+
a.add_argument("--preset", default="auto",
|
|
63
|
+
choices=["auto", "paper", "zeolite", "rigid", "bondbend", "donor_pivots"])
|
|
64
|
+
a.add_argument("--options", help="JSON file with model options (as exported by the app)")
|
|
65
|
+
a.add_argument("--step", type=float, default=0.02)
|
|
66
|
+
a.add_argument("--metric", default="relative", choices=["relative", "absolute"])
|
|
67
|
+
a.add_argument("--thr", type=float, default=0.01)
|
|
68
|
+
a.add_argument("--thr2", type=float, default=0.05)
|
|
69
|
+
a.add_argument("--extended", action="store_true", help="also run fully relaxed regimes")
|
|
70
|
+
a.add_argument("--no-finite", action="store_true", help="only infinitesimal analysis")
|
|
71
|
+
args = p.parse_args(argv)
|
|
72
|
+
if args.cmd == "analyze":
|
|
73
|
+
cmd_analyze(args)
|
|
74
|
+
else:
|
|
75
|
+
from .server import serve
|
|
76
|
+
if args.cmd is None:
|
|
77
|
+
serve()
|
|
78
|
+
else:
|
|
79
|
+
serve(args.host, args.port, not args.no_browser)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
sys.exit(main())
|