1111from emmet .core .openff import MoleculeSpec
1212from pymatgen .core import Element , Molecule
1313from pymatgen .io .openff import create_openff_mol
14+ from scipy .units import Avogadro
1415
1516if TYPE_CHECKING :
1617 import pathlib
@@ -145,6 +146,7 @@ def calculate_elyte_composition(
145146 salts : dict [str , float ],
146147 solvent_densities : dict = None ,
147148 solvent_ratio_dimension : Literal ["mass" , "volume" ] = "mass" ,
149+ atomic_masses : dict [int , float ] | None = None ,
148150) -> dict [str , float ]:
149151 """Calculate the normalized mass ratios of an electrolyte solution.
150152
@@ -158,6 +160,9 @@ def calculate_elyte_composition(
158160 Dictionary of solvent SMILES strings and their densities (g/ml).
159161 solvent_ratio_dimension: optional, str
160162 Whether the solvents are included with a ratio of "mass" or "volume"
163+ atomic_masses : dict[int,float] or None (Default)
164+ The mass of each element in the species dict. Defaults to the
165+ most recent data from pymatgen.core.periodic_table.Element
161166
162167 Returns
163168 -------
@@ -186,11 +191,11 @@ def calculate_elyte_composition(
186191 }
187192
188193 # Calculate the molecular weights of the solvent
189- masses = {el .Z : el .atomic_mass for el in Element }
194+ atomic_masses = atomic_masses or {el .Z : el .atomic_mass for el in Element }
190195 salt_mws = {}
191196 for smile in salts :
192197 mol = tk .Molecule .from_smiles (smile , allow_undefined_stereo = True )
193- salt_mws [smile ] = sum (masses [atom .atomic_number ] for atom in mol .atoms )
198+ salt_mws [smile ] = sum (atomic_masses [atom .atomic_number ] for atom in mol .atoms )
194199
195200 # Convert salt mole ratios to mass ratios
196201 salt_mass_ratio = {
@@ -207,7 +212,9 @@ def calculate_elyte_composition(
207212 return {species : mass / total_mass for species , mass in combined_mass_ratio .items ()}
208213
209214
210- def counts_from_masses (species : dict [str , float ], n_mol : int ) -> dict [str , float ]:
215+ def counts_from_masses (
216+ species : dict [str , float ], n_mol : int , atomic_masses : dict [int , float ] | None = None
217+ ) -> dict [str , float ]:
211218 """Calculate the number of mols needed to yield a given mass ratio.
212219
213220 Parameters
@@ -216,19 +223,21 @@ def counts_from_masses(species: dict[str, float], n_mol: int) -> dict[str, float
216223 Dictionary of species SMILES strings and their relative mass fractions.
217224 n_mol : float
218225 Total number of mols. Returned array will sum to near n_mol.
219-
226+ atomic_masses : dict[int,float] or None (Default)
227+ The mass of each element in the species dict. Defaults to the
228+ most recent data from pymatgen.core.periodic_table.Element
220229
221230 Returns
222231 -------
223232 numpy.ndarray
224233 n_mols: Number of each SMILES needed for the given mass ratio.
225234 """
226- masses = {el .Z : el .atomic_mass for el in Element }
235+ atomic_masses = atomic_masses or {el .Z : el .atomic_mass for el in Element }
227236
228237 mol_weights = []
229238 for smile in species :
230239 mol = tk .Molecule .from_smiles (smile , allow_undefined_stereo = True )
231- mol_weights .append (sum (masses [atom .atomic_number ] for atom in mol .atoms ))
240+ mol_weights .append (sum (atomic_masses [atom .atomic_number ] for atom in mol .atoms ))
232241
233242 mol_ratio = np .array (list (species .values ())) / np .array (mol_weights )
234243 mol_ratio /= sum (mol_ratio )
@@ -239,7 +248,10 @@ def counts_from_masses(species: dict[str, float], n_mol: int) -> dict[str, float
239248
240249
241250def counts_from_box_size (
242- species : dict [str , float ], side_length : float , density : float = 0.8
251+ species : dict [str , float ],
252+ side_length : float ,
253+ density : float = 0.8 ,
254+ atomic_masses : dict [int , float ] | None = None ,
243255) -> dict [str , float ]:
244256 """Calculate the number of molecules needed to fill a box.
245257
@@ -251,25 +263,27 @@ def counts_from_box_size(
251263 Side length of the cubic simulation box in nm.
252264 density : int, optional
253265 Density of the system in g/cm^3. Default is 1 g/cm^3.
266+ atomic_masses : dict[int,float] or None (Default)
267+ The mass of each element in the species dict. Defaults to the
268+ most recent data from pymatgen.core.periodic_table.Element
254269
255270 Returns
256271 -------
257272 dict of str, float
258273 Number of each species needed to fill the box with the given density.
259274 """
260- masses = {el .Z : el .atomic_mass for el in Element }
275+ atomic_masses = atomic_masses or {el .Z : el .atomic_mass for el in Element }
261276
262- na = 6.02214076e23 # Avogadro's number
263277 volume = (side_length * 1e-7 ) ** 3 # Convert from nm3 to cm^3
264278 total_mass = volume * density # grams
265279
266280 # Calculate molecular weights
267281 mol_weights = []
268282 for smile in species :
269283 mol = tk .Molecule .from_smiles (smile , allow_undefined_stereo = True )
270- mol_weights .append (sum (masses [atom .atomic_number ] for atom in mol .atoms ))
284+ mol_weights .append (sum (atomic_masses [atom .atomic_number ] for atom in mol .atoms ))
271285 mean_mw = np .mean (mol_weights )
272- n_mol = (total_mass / mean_mw ) * na
286+ n_mol = (total_mass / mean_mw ) * Avogadro
273287
274288 # Calculate the number of moles needed for each species
275289 mol_ratio = np .array (list (species .values ())) / np .array (mol_weights )
0 commit comments