mdinterface 1.2.0__tar.gz → 1.4.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.
Files changed (69) hide show
  1. mdinterface-1.4.0/MANIFEST.in +26 -0
  2. mdinterface-1.4.0/PKG-INFO +237 -0
  3. mdinterface-1.4.0/README.md +193 -0
  4. mdinterface-1.4.0/assets/mdinterface.png +0 -0
  5. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/__init__.py +2 -2
  6. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/build/box.py +142 -15
  7. mdinterface-1.4.0/mdinterface/build/polymerize.py +306 -0
  8. mdinterface-1.4.0/mdinterface/build/snippets.py +140 -0
  9. mdinterface-1.4.0/mdinterface/core/polymer.py +170 -0
  10. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/core/specie.py +327 -108
  11. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/core/topology.py +123 -16
  12. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/database/ions.py +31 -5
  13. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/database/molecules.py +10 -3
  14. mdinterface-1.4.0/mdinterface/examples/make_box.py +76 -0
  15. mdinterface-1.4.0/mdinterface/examples/make_polymer.py +74 -0
  16. mdinterface-1.4.0/mdinterface/examples/make_solvent_box.py +67 -0
  17. mdinterface-1.4.0/mdinterface/examples/make_specie_ligpargen_resp.py +26 -0
  18. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/externals/__init__.py +8 -0
  19. mdinterface-1.4.0/mdinterface/externals/aimd.py +103 -0
  20. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/externals/ligpargen.py +27 -9
  21. mdinterface-1.4.0/mdinterface/externals/optimization.py +80 -0
  22. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/externals/pyscf.py +5 -2
  23. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/io/lammpswriter.py +172 -20
  24. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/io/read.py +2 -2
  25. mdinterface-1.4.0/mdinterface/read/cp2ktraj.py +139 -0
  26. mdinterface-1.4.0/mdinterface/read/lammpstraj.py +73 -0
  27. mdinterface-1.4.0/mdinterface/read/read.py +270 -0
  28. mdinterface-1.4.0/mdinterface/read/trajectory.py +402 -0
  29. mdinterface-1.4.0/mdinterface/read/xyztraj.py +33 -0
  30. mdinterface-1.4.0/mdinterface/simulationbox.py +577 -0
  31. mdinterface-1.4.0/mdinterface/utils/draw.py +40 -0
  32. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/utils/graphs.py +65 -41
  33. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/utils/map.py +6 -3
  34. mdinterface-1.4.0/mdinterface/utils/poisson.py +239 -0
  35. mdinterface-1.4.0/mdinterface/utils/units.py +42 -0
  36. mdinterface-1.4.0/mdinterface.egg-info/PKG-INFO +237 -0
  37. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface.egg-info/SOURCES.txt +17 -2
  38. mdinterface-1.4.0/mdinterface.egg-info/requires.txt +19 -0
  39. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface.egg-info/top_level.txt +2 -0
  40. mdinterface-1.4.0/pyproject.toml +65 -0
  41. mdinterface-1.4.0/requirements.txt +7 -0
  42. mdinterface-1.4.0/setup.cfg +4 -0
  43. mdinterface-1.2.0/MANIFEST.in +0 -1
  44. mdinterface-1.2.0/PKG-INFO +0 -133
  45. mdinterface-1.2.0/README.md +0 -111
  46. mdinterface-1.2.0/mdinterface/build/polymerize.py +0 -95
  47. mdinterface-1.2.0/mdinterface/core/polymer.py +0 -158
  48. mdinterface-1.2.0/mdinterface/simulationbox.py +0 -438
  49. mdinterface-1.2.0/mdinterface.egg-info/PKG-INFO +0 -133
  50. mdinterface-1.2.0/mdinterface.egg-info/requires.txt +0 -7
  51. mdinterface-1.2.0/pyproject.toml +0 -3
  52. mdinterface-1.2.0/requirements.txt +0 -7
  53. mdinterface-1.2.0/setup.cfg +0 -27
  54. {mdinterface-1.2.0 → mdinterface-1.4.0}/LICENSE +0 -0
  55. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/build/__init__.py +0 -0
  56. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/build/charges.py +0 -0
  57. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/build/continuum2sim.py +0 -0
  58. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/config.py +0 -0
  59. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/core/__init__.py +0 -0
  60. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/database/__init__.py +0 -0
  61. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/database/graphene.py +0 -0
  62. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/database/metals.py +0 -0
  63. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/externals/obabel.py +0 -0
  64. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/io/__init__.py +0 -0
  65. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/io/packmol.py +0 -0
  66. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/utils/__init__.py +0 -0
  67. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface/utils/auxiliary.py +0 -0
  68. {mdinterface-1.2.0 → mdinterface-1.4.0}/mdinterface.egg-info/dependency_links.txt +0 -0
  69. {mdinterface-1.2.0 → mdinterface-1.4.0}/setup.py +0 -0
@@ -0,0 +1,26 @@
1
+ # Include important files
2
+ include README.md
3
+ include LICENSE
4
+ include requirements.txt
5
+ include pyproject.toml
6
+
7
+ # Include package data
8
+ recursive-include mdinterface *.py
9
+ recursive-include mdinterface/database *.json *.txt *.dat
10
+ recursive-include mdinterface/examples *.py
11
+ recursive-include mdinterface/config *.ini
12
+
13
+ # Include documentation and assets if they exist
14
+ recursive-include docs *
15
+ include assets/*
16
+
17
+ # Exclude unwanted files
18
+ exclude *.pyc
19
+ exclude *~
20
+ exclude *.bak
21
+ exclude .DS_Store
22
+ recursive-exclude * __pycache__
23
+ recursive-exclude * *.py[co]
24
+ recursive-exclude * .git*
25
+ recursive-exclude * .tox*
26
+ recursive-exclude * .pytest_cache*
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdinterface
3
+ Version: 1.4.0
4
+ Summary: Build Interface Systems for Molecular Dynamics Simulations
5
+ Author-email: Fabrice Roncoroni <fabrice.roncoroni@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://gitlab.com/roncofaber/mdinterface
8
+ Project-URL: Repository, https://gitlab.com/roncofaber/mdinterface.git
9
+ Project-URL: Documentation, https://gitlab.com/roncofaber/mdinterface
10
+ Project-URL: Bug Tracker, https://gitlab.com/roncofaber/mdinterface/-/issues
11
+ Keywords: molecular dynamics,simulation,interface,chemistry,materials science
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
23
+ Classifier: Topic :: Scientific/Engineering :: Physics
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: mdanalysis>=2.0.0
28
+ Requires-Dist: ase>=3.22.0
29
+ Requires-Dist: numpy>=1.20.0
30
+ Requires-Dist: networkx>=2.5
31
+ Requires-Dist: platformdirs>=2.0.0
32
+ Requires-Dist: configparser>=5.0.0
33
+ Requires-Dist: libarvo
34
+ Provides-Extra: resp
35
+ Requires-Dist: pyscf>=2.0.0; extra == "resp"
36
+ Requires-Dist: pymbxas; extra == "resp"
37
+ Provides-Extra: aimd
38
+ Requires-Dist: fairchem-core; extra == "aimd"
39
+ Provides-Extra: all
40
+ Requires-Dist: pyscf>=2.0.0; extra == "all"
41
+ Requires-Dist: pymbxas; extra == "all"
42
+ Requires-Dist: fairchem-core; extra == "all"
43
+ Dynamic: license-file
44
+
45
+ <div style="display: flex; align-items: center;">
46
+ <img src="./assets/mdinterface.png" alt="Logo" width="80" style="margin-right: 10px;">
47
+ <div style="display: flex; flex-direction: column;">
48
+ <h1 style="margin: 0;">mdinterface: Build Interface Systems for Molecular Dynamics Simulations</h1>
49
+ </div>
50
+ </div>
51
+
52
+ [![PyPI version](https://badge.fury.io/py/mdinterface.svg?icon=si%3Apython)](https://pypi.org/project/mdinterface/) [![GitHub version](https://badge.fury.io/gh/roncofaber%2Fmdinterface.svg?icon=si%3Agithub)](https://github.com/roncofaber/mdinterface)
53
+
54
+ `mdinterface` is a Python package designed to build systems for Molecular Dynamics (MD) simulations. Initially developed to construct electrolyte/electrode solid-liquid interfaces, it is also well-suited for generating MD boxes of liquids, electrolyte systems, and polymer networks.
55
+
56
+ ## Features
57
+
58
+ Using `mdinterface` you can:
59
+
60
+ - Create layered simulation boxes with solvents, solutes, and interface slabs.
61
+ - Populate your system with ions and solvents using PACKMOL, and provide the starting concentration profile of the species to get the MD where you want it to be, but faster.
62
+ - Import common molecules/metals/polymers with pre-defined classical force fields parameters from the database, or automatically generate new OPLS-AA force field parameters using [LigParGen](https://github.com/Isra3l/ligpargen).
63
+ - Generate polymer chains of any length from a starting monomer.
64
+ - Estimate the RESP charges of molecules using the [PySCF electronic structure code](https://github.com/pyscf/pyscf).
65
+ - Perform Ab Initio Molecular Dynamics (AIMD) simulations using [FAIRChem](https://github.com/facebookresearch/fairchem) machine learning potentials (optional).
66
+ - Automatically write LAMMPS data files and coefficients, so you can start making them atoms dance as soon as possible!
67
+ - Integrate your workflow with [MDAnalysis](https://github.com/MDAnalysis/mdanalysis): create your molecules with `mdinterface` and convert them to `mda.Universe` objects with a simple interface.
68
+
69
+ ## Requirements
70
+
71
+ Check the file [requirements.txt](requirements.txt) to see which packages are needed. Installing the package using `pip` should already take care of all mandatory dependencies.
72
+
73
+ Additionally, you need the `packmol` utility installed to generate MD boxes. You can follow the instructions at [https://m3g.github.io/packmol/](https://m3g.github.io/packmol/) to install it. Alternatively, you can install it using `conda`:
74
+
75
+ ```bash
76
+ conda install -c conda-forge packmol
77
+ ```
78
+
79
+ ### Optional packages
80
+
81
+ #### Automatic OPLS-AA force field generator with LigParGen
82
+
83
+ If you want to use LigParGen, please follow the instructions on their [GitHub](https://github.com/Isra3l/ligpargen). If you are having trouble installing, you can try my own [fork](https://github.com/roncofaber/ligpargen) of the original repo. To make sure that BOSS is recognized by the package, specify the environment variable `BOSSdir`.
84
+
85
+ You can do this manually every time, or just add the path to the `config.ini` file to your config directory:
86
+
87
+ ```bash
88
+ # config.ini
89
+ [settings]
90
+ BOSSdir = /path/to/your/boss/dir
91
+ ```
92
+
93
+ The config directory is found using [`platformdirs`](https://pypi.org/project/platformdirs/) and is OS dependent.
94
+
95
+ #### RESP charge analysis with PySCF
96
+
97
+ To use the RESP charge analysis feature, you need to install [PySCF](https://github.com/pyscf/pyscf) and [PyMBXAS](https://gitlab.com/roncofaber/pymbxas). To my knowledge, the RESP feature is only implemented in [gpu4pyscf](https://github.com/pyscf/gpu4pyscf) at the moment, so follow the repo instructions on how to install it.
98
+
99
+ #### AIMD simulations with FAIRChem
100
+
101
+ For Ab Initio Molecular Dynamics (AIMD) simulations, you need to install [FAIRChem](https://github.com/facebookresearch/fairchem). This provides machine learning potentials for accelerated quantum mechanical simulations. Install it with:
102
+
103
+ ```bash
104
+ pip install fairchem-core
105
+ ```
106
+
107
+ This functionality is completely optional and the package will work without it for all other features.
108
+
109
+ ## Installation
110
+
111
+ ### System Requirements
112
+
113
+ - **Python**: 3.8 or higher
114
+ - **PACKMOL**: Required for molecular packing (see below)
115
+ - **Operating System**: Linux, macOS, Windows (with some limitations on Windows)
116
+
117
+ ### Core Installation
118
+
119
+ #### Option 1: Install from PyPI (Recommended)
120
+
121
+ Install the latest stable release with all core dependencies:
122
+
123
+ ```bash
124
+ pip install mdinterface
125
+ ```
126
+
127
+ #### Option 2: Install from Source
128
+
129
+ For the latest development version or to contribute:
130
+
131
+ ```bash
132
+ # Clone the repository
133
+ git clone https://gitlab.com/roncofaber/mdinterface.git
134
+ cd mdinterface
135
+
136
+ # Install in normal mode
137
+ pip install .
138
+
139
+ # Or install in development mode (for contributors)
140
+ pip install -e .
141
+ ```
142
+
143
+ ### Installing PACKMOL
144
+
145
+ PACKMOL is required for molecular packing and must be installed separately:
146
+
147
+ #### Using conda (Recommended):
148
+ ```bash
149
+ conda install -c conda-forge packmol
150
+ ```
151
+
152
+ #### From source:
153
+ Follow instructions at [https://m3g.github.io/packmol/](https://m3g.github.io/packmol/)
154
+
155
+ ### Optional Dependencies
156
+
157
+ Install additional features as needed:
158
+
159
+ ```bash
160
+ # RESP charge analysis (requires additional setup)
161
+ pip install mdinterface[resp]
162
+
163
+ # AIMD simulations with FAIRChem
164
+ pip install mdinterface[aimd]
165
+
166
+ # All optional dependencies
167
+ pip install mdinterface[all]
168
+ ```
169
+
170
+ ### Verifying Installation
171
+
172
+ Test your installation:
173
+
174
+ ```python
175
+ import mdinterface
176
+ from mdinterface import SimulationBox, Specie
177
+ print(f"mdinterface version: {mdinterface.__version__}")
178
+ ```
179
+
180
+ ### Troubleshooting
181
+
182
+ #### Common Issues:
183
+
184
+ 1. **PACKMOL not found**: Ensure PACKMOL is in your PATH or install via conda
185
+ 2. **Import errors**: Check that all dependencies are properly installed
186
+ 3. **Version conflicts**: Use a clean virtual environment
187
+
188
+ #### Python Environment Setup:
189
+
190
+ We recommend using a virtual environment:
191
+
192
+ ```bash
193
+ # Create virtual environment
194
+ python -m venv mdinterface-env
195
+ source mdinterface-env/bin/activate # On Windows: mdinterface-env\Scripts\activate
196
+
197
+ # Install mdinterface
198
+ pip install mdinterface
199
+ ```
200
+
201
+ #### For conda users:
202
+
203
+ ```bash
204
+ # Create conda environment
205
+ conda create -n mdinterface python=3.10
206
+ conda activate mdinterface
207
+
208
+ # Install dependencies
209
+ conda install -c conda-forge packmol
210
+ pip install mdinterface
211
+ ```
212
+
213
+ ## Usage
214
+
215
+ Creating a new Specie (with its topology attributes) is as simple as doing:
216
+
217
+ ```python
218
+ #%% Make a specie, and use LigParGen to estimate FF parameters
219
+ my_specie = Specie("CH3ONO", ligpargen=True) # molecule is in ASE database
220
+
221
+ # make a specie from any ASE readable file
222
+ my_specie = Specie("methylnitrite.xyz", ligpargen=True)
223
+
224
+ # convert specie to mdanalysis universe (and all the attributes!)
225
+ my_specie.to_universe()
226
+
227
+ ```
228
+
229
+ Please, check the files in [examples](mdinterface/examples/) to learn how to use the package. Including setting up simulation boxes, creating polymers, perform RESP analysis and much more!
230
+
231
+ ## Roadmap
232
+
233
+ Since the original idea was to make a package to build MD boxes layer by layer, I am strongly debating renaming everything as "Workflow for Easy Molecular DYnamics Simulations", aka WEMDYS.
234
+
235
+ ## Questions & Issues
236
+
237
+ Sir, this is a WEMDY'S. Please contact me or open an issue, glad to talk about ideas and improvements!
@@ -0,0 +1,193 @@
1
+ <div style="display: flex; align-items: center;">
2
+ <img src="./assets/mdinterface.png" alt="Logo" width="80" style="margin-right: 10px;">
3
+ <div style="display: flex; flex-direction: column;">
4
+ <h1 style="margin: 0;">mdinterface: Build Interface Systems for Molecular Dynamics Simulations</h1>
5
+ </div>
6
+ </div>
7
+
8
+ [![PyPI version](https://badge.fury.io/py/mdinterface.svg?icon=si%3Apython)](https://pypi.org/project/mdinterface/) [![GitHub version](https://badge.fury.io/gh/roncofaber%2Fmdinterface.svg?icon=si%3Agithub)](https://github.com/roncofaber/mdinterface)
9
+
10
+ `mdinterface` is a Python package designed to build systems for Molecular Dynamics (MD) simulations. Initially developed to construct electrolyte/electrode solid-liquid interfaces, it is also well-suited for generating MD boxes of liquids, electrolyte systems, and polymer networks.
11
+
12
+ ## Features
13
+
14
+ Using `mdinterface` you can:
15
+
16
+ - Create layered simulation boxes with solvents, solutes, and interface slabs.
17
+ - Populate your system with ions and solvents using PACKMOL, and provide the starting concentration profile of the species to get the MD where you want it to be, but faster.
18
+ - Import common molecules/metals/polymers with pre-defined classical force fields parameters from the database, or automatically generate new OPLS-AA force field parameters using [LigParGen](https://github.com/Isra3l/ligpargen).
19
+ - Generate polymer chains of any length from a starting monomer.
20
+ - Estimate the RESP charges of molecules using the [PySCF electronic structure code](https://github.com/pyscf/pyscf).
21
+ - Perform Ab Initio Molecular Dynamics (AIMD) simulations using [FAIRChem](https://github.com/facebookresearch/fairchem) machine learning potentials (optional).
22
+ - Automatically write LAMMPS data files and coefficients, so you can start making them atoms dance as soon as possible!
23
+ - Integrate your workflow with [MDAnalysis](https://github.com/MDAnalysis/mdanalysis): create your molecules with `mdinterface` and convert them to `mda.Universe` objects with a simple interface.
24
+
25
+ ## Requirements
26
+
27
+ Check the file [requirements.txt](requirements.txt) to see which packages are needed. Installing the package using `pip` should already take care of all mandatory dependencies.
28
+
29
+ Additionally, you need the `packmol` utility installed to generate MD boxes. You can follow the instructions at [https://m3g.github.io/packmol/](https://m3g.github.io/packmol/) to install it. Alternatively, you can install it using `conda`:
30
+
31
+ ```bash
32
+ conda install -c conda-forge packmol
33
+ ```
34
+
35
+ ### Optional packages
36
+
37
+ #### Automatic OPLS-AA force field generator with LigParGen
38
+
39
+ If you want to use LigParGen, please follow the instructions on their [GitHub](https://github.com/Isra3l/ligpargen). If you are having trouble installing, you can try my own [fork](https://github.com/roncofaber/ligpargen) of the original repo. To make sure that BOSS is recognized by the package, specify the environment variable `BOSSdir`.
40
+
41
+ You can do this manually every time, or just add the path to the `config.ini` file to your config directory:
42
+
43
+ ```bash
44
+ # config.ini
45
+ [settings]
46
+ BOSSdir = /path/to/your/boss/dir
47
+ ```
48
+
49
+ The config directory is found using [`platformdirs`](https://pypi.org/project/platformdirs/) and is OS dependent.
50
+
51
+ #### RESP charge analysis with PySCF
52
+
53
+ To use the RESP charge analysis feature, you need to install [PySCF](https://github.com/pyscf/pyscf) and [PyMBXAS](https://gitlab.com/roncofaber/pymbxas). To my knowledge, the RESP feature is only implemented in [gpu4pyscf](https://github.com/pyscf/gpu4pyscf) at the moment, so follow the repo instructions on how to install it.
54
+
55
+ #### AIMD simulations with FAIRChem
56
+
57
+ For Ab Initio Molecular Dynamics (AIMD) simulations, you need to install [FAIRChem](https://github.com/facebookresearch/fairchem). This provides machine learning potentials for accelerated quantum mechanical simulations. Install it with:
58
+
59
+ ```bash
60
+ pip install fairchem-core
61
+ ```
62
+
63
+ This functionality is completely optional and the package will work without it for all other features.
64
+
65
+ ## Installation
66
+
67
+ ### System Requirements
68
+
69
+ - **Python**: 3.8 or higher
70
+ - **PACKMOL**: Required for molecular packing (see below)
71
+ - **Operating System**: Linux, macOS, Windows (with some limitations on Windows)
72
+
73
+ ### Core Installation
74
+
75
+ #### Option 1: Install from PyPI (Recommended)
76
+
77
+ Install the latest stable release with all core dependencies:
78
+
79
+ ```bash
80
+ pip install mdinterface
81
+ ```
82
+
83
+ #### Option 2: Install from Source
84
+
85
+ For the latest development version or to contribute:
86
+
87
+ ```bash
88
+ # Clone the repository
89
+ git clone https://gitlab.com/roncofaber/mdinterface.git
90
+ cd mdinterface
91
+
92
+ # Install in normal mode
93
+ pip install .
94
+
95
+ # Or install in development mode (for contributors)
96
+ pip install -e .
97
+ ```
98
+
99
+ ### Installing PACKMOL
100
+
101
+ PACKMOL is required for molecular packing and must be installed separately:
102
+
103
+ #### Using conda (Recommended):
104
+ ```bash
105
+ conda install -c conda-forge packmol
106
+ ```
107
+
108
+ #### From source:
109
+ Follow instructions at [https://m3g.github.io/packmol/](https://m3g.github.io/packmol/)
110
+
111
+ ### Optional Dependencies
112
+
113
+ Install additional features as needed:
114
+
115
+ ```bash
116
+ # RESP charge analysis (requires additional setup)
117
+ pip install mdinterface[resp]
118
+
119
+ # AIMD simulations with FAIRChem
120
+ pip install mdinterface[aimd]
121
+
122
+ # All optional dependencies
123
+ pip install mdinterface[all]
124
+ ```
125
+
126
+ ### Verifying Installation
127
+
128
+ Test your installation:
129
+
130
+ ```python
131
+ import mdinterface
132
+ from mdinterface import SimulationBox, Specie
133
+ print(f"mdinterface version: {mdinterface.__version__}")
134
+ ```
135
+
136
+ ### Troubleshooting
137
+
138
+ #### Common Issues:
139
+
140
+ 1. **PACKMOL not found**: Ensure PACKMOL is in your PATH or install via conda
141
+ 2. **Import errors**: Check that all dependencies are properly installed
142
+ 3. **Version conflicts**: Use a clean virtual environment
143
+
144
+ #### Python Environment Setup:
145
+
146
+ We recommend using a virtual environment:
147
+
148
+ ```bash
149
+ # Create virtual environment
150
+ python -m venv mdinterface-env
151
+ source mdinterface-env/bin/activate # On Windows: mdinterface-env\Scripts\activate
152
+
153
+ # Install mdinterface
154
+ pip install mdinterface
155
+ ```
156
+
157
+ #### For conda users:
158
+
159
+ ```bash
160
+ # Create conda environment
161
+ conda create -n mdinterface python=3.10
162
+ conda activate mdinterface
163
+
164
+ # Install dependencies
165
+ conda install -c conda-forge packmol
166
+ pip install mdinterface
167
+ ```
168
+
169
+ ## Usage
170
+
171
+ Creating a new Specie (with its topology attributes) is as simple as doing:
172
+
173
+ ```python
174
+ #%% Make a specie, and use LigParGen to estimate FF parameters
175
+ my_specie = Specie("CH3ONO", ligpargen=True) # molecule is in ASE database
176
+
177
+ # make a specie from any ASE readable file
178
+ my_specie = Specie("methylnitrite.xyz", ligpargen=True)
179
+
180
+ # convert specie to mdanalysis universe (and all the attributes!)
181
+ my_specie.to_universe()
182
+
183
+ ```
184
+
185
+ Please, check the files in [examples](mdinterface/examples/) to learn how to use the package. Including setting up simulation boxes, creating polymers, perform RESP analysis and much more!
186
+
187
+ ## Roadmap
188
+
189
+ Since the original idea was to make a package to build MD boxes layer by layer, I am strongly debating renaming everything as "Workflow for Easy Molecular DYnamics Simulations", aka WEMDYS.
190
+
191
+ ## Questions & Issues
192
+
193
+ Sir, this is a WEMDY'S. Please contact me or open an issue, glad to talk about ideas and improvements!
Binary file
@@ -6,8 +6,8 @@ Initially developed to construct electrolyte/electrode interfaces, it is also we
6
6
 
7
7
  """
8
8
 
9
- __version__ = '1.2.0'
10
- __date__ = '28 Mar. 2025'
9
+ __version__ = '1.4.0'
10
+ __date__ = '14 Oct. 2025'
11
11
  __author__ = 'Fabrice Roncoroni'
12
12
  __all__ = ['SimulationBox', "Specie", "Polymer"]
13
13
 
@@ -6,6 +6,7 @@ Created on Tue Jan 14 10:23:57 2025
6
6
  @author: roncofaber
7
7
  """
8
8
 
9
+ from typing import List, Optional, Union, Tuple, Dict, Any
9
10
  from mdinterface.io.packmol import header, box_place, fix_place
10
11
  from mdinterface.build.continuum2sim import discretize_concentration
11
12
 
@@ -18,13 +19,129 @@ import subprocess
18
19
 
19
20
  #%%
20
21
 
21
- def make_solvent_box(species, solvent, ions, volume, density, nions, concentration,
22
- conmodel, ion_pos):
23
-
24
- # make sure info is sound
25
- assert not( nions is not None and concentration is not None),\
26
- "'nions' and 'concentration' cannot both be not None"
27
-
22
+ def _validate_solvent_box_parameters(
23
+ nions: Optional[Union[int, List[int]]],
24
+ concentration: Optional[float],
25
+ conmodel: Optional[Dict[int, Tuple[List[float], List[float]]]],
26
+ ions: Optional[List[Any]],
27
+ solvent: Optional[Any],
28
+ density: Optional[float],
29
+ nsolvent: Optional[int] = None
30
+ ) -> None:
31
+ """
32
+ Validate parameter combinations for make_solvent_box function.
33
+
34
+ Raises appropriate errors for invalid parameter combinations.
35
+ """
36
+
37
+ # Basic mutual exclusivity check
38
+ if nions is not None and concentration is not None:
39
+ raise ValueError("Cannot specify both 'nions' and 'concentration'. Use one or the other.")
40
+
41
+ # If concentration model is provided, ions must be provided
42
+ if conmodel is not None and (ions is None or len(ions) == 0):
43
+ raise ValueError("When using 'conmodel', 'ions' must be provided and non-empty.")
44
+
45
+ # If nions is a list, it must match the number of ion species
46
+ if isinstance(nions, (list, tuple)) and ions is not None:
47
+ if len(nions) != len(ions):
48
+ raise ValueError(f"Length of 'nions' ({len(nions)}) must match number of ion species ({len(ions)}).")
49
+
50
+ # Validate density vs nsolvent mutual exclusivity
51
+ if density is not None and nsolvent is not None:
52
+ import warnings
53
+ warnings.warn(
54
+ "Both 'density' and 'nsolvent' are specified. Using 'nsolvent' and ignoring 'density'.",
55
+ UserWarning, stacklevel=4
56
+ )
57
+
58
+ # If solvent density or nsolvent is provided but no solvent, warn the user
59
+ if (density is not None or nsolvent is not None) and solvent is None:
60
+ import warnings
61
+ warnings.warn("Density or nsolvent specified but no solvent provided. Will be ignored.",
62
+ UserWarning, stacklevel=4)
63
+
64
+ # If no solvent and no ions, nothing to do
65
+ if solvent is None and (ions is None or len(ions) == 0):
66
+ import warnings
67
+ warnings.warn("No solvent or ions specified. Empty box will be created.",
68
+ UserWarning, stacklevel=3)
69
+
70
+ def make_solvent_box(
71
+ species: List[Any],
72
+ solvent: Optional[Any],
73
+ ions: Optional[List[Any]],
74
+ volume: List[float],
75
+ density: Optional[float],
76
+ nions: Optional[Union[int, List[int]]],
77
+ concentration: Optional[float],
78
+ conmodel: Optional[Dict[int, Tuple[List[float], List[float]]]],
79
+ ion_pos: Optional[str],
80
+ nsolvent: Optional[int] = None
81
+ ) -> Optional[mda.Universe]:
82
+ """
83
+ Build a solvent box with optional ionic species.
84
+
85
+ This function creates a simulation box containing solvent molecules and ionic species
86
+ using PACKMOL for molecular packing. It supports various placement strategies and
87
+ concentration models.
88
+
89
+ Parameters:
90
+ -----------
91
+ species : list
92
+ List of all available species in the simulation
93
+ solvent : object or None
94
+ Solvent molecule object (e.g., Water). If None, only ions are placed.
95
+ ions : list or None
96
+ List of ionic species to add to the box
97
+ volume : list
98
+ Box dimensions [x, y, z] in Angstroms
99
+ density : float or None
100
+ Solvent density in g/cm³. Ignored if solvent is None or if nsolvent is specified.
101
+ nions : int, list, or None
102
+ Number of each ionic species. Can be:
103
+ - int: Same number for all ion types
104
+ - list: Different number for each ion type (must match len(ions))
105
+ - None: No ions added
106
+ concentration : float or None
107
+ Ionic concentration in Molar. Alternative to nions.
108
+ Cannot be used simultaneously with nions.
109
+ conmodel : dict or None
110
+ Advanced concentration model for spatially varying concentrations.
111
+ Format: {ion_index: (z_coords, concentration_profile)}
112
+ ion_pos : str or None
113
+ Ion placement strategy:
114
+ - "random": Random placement (default)
115
+ - "center": Place all ions at box center
116
+ - "box": Use PACKMOL box placement
117
+ - "left": Constrain to left half of box
118
+ - None: Defaults to "random"
119
+ nsolvent : int or None
120
+ Number of solvent molecules to place. If specified, takes precedence over density.
121
+ Cannot be used simultaneously with density.
122
+
123
+ Returns:
124
+ --------
125
+ MDAnalysis.Universe or None
126
+ Merged universe containing solvent and ions, or None if no components
127
+
128
+ Examples:
129
+ ---------
130
+ # Simple water box with NaCl
131
+ make_solvent_box(species, water, [na, cl], [20, 20, 20], 1.0, [5, 5], None, None, "random")
132
+
133
+ # Concentration-based approach
134
+ make_solvent_box(species, water, [na, cl], [20, 20, 20], 1.0, None, 0.1, None, "random")
135
+
136
+ # Complex polymer solution
137
+ make_solvent_box(species, None, [polymer, hydronium, water], [50, 50, 50], None, [10, 50, 200], None, None, "box")
138
+ """
139
+
140
+ # Validate parameter combinations
141
+ _validate_solvent_box_parameters(nions, concentration, conmodel, ions, solvent, density, nsolvent)
142
+
143
+ # Legacy parameter compatibility is handled in the calling function (simulationbox.py)
144
+
28
145
  # convert concentration to number of ions
29
146
  if concentration is not None:
30
147
  nions = int(concentration*np.prod(volume)*units.mol/((units.m/10)**3))
@@ -40,12 +157,18 @@ def make_solvent_box(species, solvent, ions, volume, density, nions, concentrati
40
157
 
41
158
  # add solvent
42
159
  if solvent is not None:
43
- solvent_volume = 1e-24*np.prod(volume)
44
- mass = solvent.atoms.masses.sum()
160
+ if nsolvent is not None:
161
+ # Use directly specified number of solvent molecules
162
+ nummols = nsolvent
163
+ elif density is not None:
164
+ # Calculate number of solvent molecules from density
165
+ solvent_volume = 1e-24*np.prod(volume)
166
+ mass = solvent.atoms.masses.sum()
167
+ nummols = int(units.mol*density*(1.0/mass)*solvent_volume)
168
+ else:
169
+ # This should be caught by validation, but defensive programming
170
+ raise ValueError("Either 'density' or 'nsolvent' must be specified for solvent placement")
45
171
 
46
- # number of solvent molecules
47
- nummols = int(units.mol*density*(1.0/mass)*solvent_volume)
48
-
49
172
  instructions.append([solvent, nummols, "box"])
50
173
 
51
174
  # generate universe file
@@ -70,9 +193,12 @@ def make_solvent_box(species, solvent, ions, volume, density, nions, concentrati
70
193
 
71
194
  return solution
72
195
 
73
- # populate a box with solvent and ions
74
- def populate_box(volume, instructions, input_file="input_packmol.in",
75
- output_file="system.pdb"):
196
+ def populate_box(
197
+ volume: List[float],
198
+ instructions: List[Tuple[Any, Union[int, List[float]], str]],
199
+ input_file: str = "input_packmol.in",
200
+ output_file: str = "system.pdb"
201
+ ) -> Optional[mda.Universe]:
76
202
 
77
203
  if not instructions:
78
204
  return None
@@ -168,6 +294,7 @@ def make_interface_slab(interface_uc, xsize, ysize, layers=1):
168
294
 
169
295
  #THANKS CHATGPT (but mostly me tbh)
170
296
  def populate_with_ions(ions, nions, volume, ion_pos=False, conmodel=None):
297
+
171
298
  def place_ion(ion, volume, ion_coords, ion_radii, zpos=None, max_attempts=100):
172
299
  ion_radius = ion.estimate_specie_radius()
173
300
  for _ in range(max_attempts):