Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import fractions
2import functools
3import re
4from collections import OrderedDict
5from typing import List, Tuple, Dict
7import numpy as np
8from scipy.spatial import ConvexHull
10import ase.units as units
11from ase.formula import Formula
13_solvated: List[Tuple[str, Dict[str, int], float, bool, float]] = []
16def parse_formula(formula):
17 aq = formula.endswith('(aq)')
18 if aq:
19 formula = formula[:-4]
20 charge = formula.count('+') - formula.count('-')
21 if charge:
22 formula = formula.rstrip('+-')
23 count = Formula(formula).count()
24 return count, charge, aq
27def float2str(x):
28 f = fractions.Fraction(x).limit_denominator(100)
29 n = f.numerator
30 d = f.denominator
31 if abs(n / d - f) > 1e-6:
32 return '{:.3f}'.format(f)
33 if d == 0:
34 return '0'
35 if f.denominator == 1:
36 return str(n)
37 return '{}/{}'.format(f.numerator, f.denominator)
40def solvated(symbols):
41 """Extract solvation energies from database.
43 symbols: str
44 Extract only those molecules that contain the chemical elements
45 given by the symbols string (plus water and H+).
47 Data from:
49 Johnson JW, Oelkers EH, Helgeson HC (1992)
50 Comput Geosci 18(7):899.
51 doi:10.1016/0098-3004(92)90029-Q
53 and:
55 Pourbaix M (1966)
56 Atlas of electrochemical equilibria in aqueous solutions.
57 No. v. 1 in Atlas of Electrochemical Equilibria in Aqueous Solutions.
58 Pergamon Press, New York.
60 Returns list of (name, energy) tuples.
61 """
63 if isinstance(symbols, str):
64 symbols = Formula(symbols).count().keys()
65 if len(_solvated) == 0:
66 for line in _aqueous.splitlines():
67 energy, formula = line.split(',')
68 name = formula + '(aq)'
69 count, charge, aq = parse_formula(name)
70 energy = float(energy) * 0.001 * units.kcal / units.mol
71 _solvated.append((name, count, charge, aq, energy))
72 references = []
73 for name, count, charge, aq, energy in _solvated:
74 for symbol in count:
75 if symbol not in 'HO' and symbol not in symbols:
76 break
77 else:
78 references.append((name, energy))
79 return references
82def bisect(A, X, Y, f):
83 a = []
84 for i in [0, -1]:
85 for j in [0, -1]:
86 if A[i, j] == -1:
87 A[i, j] = f(X[i], Y[j])
88 a.append(A[i, j])
90 if np.ptp(a) == 0:
91 A[:] = a[0]
92 return
93 if a[0] == a[1]:
94 A[0] = a[0]
95 if a[1] == a[3]:
96 A[:, -1] = a[1]
97 if a[3] == a[2]:
98 A[-1] = a[3]
99 if a[2] == a[0]:
100 A[:, 0] = a[2]
101 if not (A == -1).any():
102 return
103 i = len(X) // 2
104 j = len(Y) // 2
105 bisect(A[:i + 1, :j + 1], X[:i + 1], Y[:j + 1], f)
106 bisect(A[:i + 1, j:], X[:i + 1], Y[j:], f)
107 bisect(A[i:, :j + 1], X[i:], Y[:j + 1], f)
108 bisect(A[i:, j:], X[i:], Y[j:], f)
111def print_results(results):
112 total_energy = 0.0
113 print('reference coefficient energy')
114 print('------------------------------------')
115 for name, coef, energy in results:
116 total_energy += coef * energy
117 if abs(coef) < 1e-7:
118 continue
119 print('{:14}{:>10}{:12.3f}'.format(name, float2str(coef), energy))
120 print('------------------------------------')
121 print('Total energy: {:22.3f}'.format(total_energy))
122 print('------------------------------------')
125class Pourbaix:
126 def __init__(self, references, formula=None, T=300.0, **kwargs):
127 """Pourbaix object.
129 references: list of (name, energy) tuples
130 Examples of names: ZnO2, H+(aq), H2O(aq), Zn++(aq), ...
131 formula: str
132 Stoichiometry. Example: ``'ZnO'``. Can also be given as
133 keyword arguments: ``Pourbaix(refs, Zn=1, O=1)``.
134 T: float
135 Temperature in Kelvin.
136 """
138 if formula:
139 assert not kwargs
140 kwargs = parse_formula(formula)[0]
142 if 'O' not in kwargs:
143 kwargs['O'] = 0
144 if 'H' not in kwargs:
145 kwargs['H'] = 0
147 self.kT = units.kB * T
148 self.references = []
149 for name, energy in references:
150 if name == 'O':
151 continue
152 count, charge, aq = parse_formula(name)
153 if all(symbol in kwargs for symbol in count):
154 self.references.append((count, charge, aq, energy, name))
156 self.references.append(({}, -1, False, 0.0, 'e-')) # an electron
158 self.count = kwargs
160 self.N = {'e-': 0}
161 for symbol in kwargs:
162 if symbol not in self.N:
163 self.N[symbol] = len(self.N)
165 def decompose(self, U, pH, verbose=True, concentration=1e-6):
166 """Decompose material.
168 U: float
169 Potential in V.
170 pH: float
171 pH value.
172 verbose: bool
173 Default is True.
174 concentration: float
175 Concentration of solvated references.
177 Returns optimal coefficients and energy:
179 >>> from ase.phasediagram import Pourbaix, solvated
180 >>> refs = solvated('CoO') + [
181 ... ('Co', 0.0),
182 ... ('CoO', -2.509),
183 ... ('Co3O4', -9.402)]
184 >>> pb = Pourbaix(refs, Co=3, O=4)
185 >>> coefs, energy = pb.decompose(U=1.5, pH=0,
186 ... concentration=1e-6,
187 ... verbose=True)
188 0 HCoO2-(aq) -3.974
189 1 CoO2--(aq) -3.098
190 2 H2O(aq) -2.458
191 3 CoOH+(aq) -2.787
192 4 CoO(aq) -2.265
193 5 CoOH++(aq) -1.355
194 6 Co++(aq) -0.921
195 7 H+(aq) 0.000
196 8 Co+++(aq) 1.030
197 9 Co 0.000
198 10 CoO -2.509
199 11 Co3O4 -9.402
200 12 e- -1.500
201 reference coefficient energy
202 ------------------------------------
203 H2O(aq) 4 -2.458
204 Co++(aq) 3 -0.921
205 H+(aq) -8 0.000
206 e- -2 -1.500
207 ------------------------------------
208 Total energy: -9.596
209 ------------------------------------
210 """
212 alpha = np.log(10) * self.kT
213 entropy = -np.log(concentration) * self.kT
215 # We want to minimize np.dot(energies, x) under the constraints:
216 #
217 # np.dot(x, eq2) == eq1
218 #
219 # with bounds[i,0] <= x[i] <= bounds[i, 1].
220 #
221 # First two equations are charge and number of hydrogens, and
222 # the rest are the remaining species.
224 eq1 = [0] + list(self.count.values())
225 eq2 = []
226 energies = []
227 bounds = []
228 names = []
229 for count, charge, aq, energy, name in self.references:
230 eq = np.zeros(len(self.N))
231 eq[0] = charge
232 for symbol, n in count.items():
233 eq[self.N[symbol]] = n
234 eq2.append(eq)
235 if name in ['H2O(aq)', 'H+(aq)', 'e-']:
236 bounds.append((-np.inf, np.inf))
237 if name == 'e-':
238 energy = -U
239 elif name == 'H+(aq)':
240 energy = -pH * alpha
241 else:
242 bounds.append((0, np.inf))
243 if aq:
244 energy -= entropy
245 if verbose:
246 print('{:<5}{:10}{:10.3f}'.format(len(energies),
247 name, energy))
248 energies.append(energy)
249 names.append(name)
251 from scipy.optimize import linprog
253 result = linprog(c=energies,
254 A_eq=np.transpose(eq2),
255 b_eq=eq1,
256 bounds=bounds,
257 options={'lstsq': True,
258 'presolve': True})
260 if verbose:
261 print_results(zip(names, result.x, energies))
263 return result.x, result.fun
265 def diagram(self, U, pH, plot=True, show=False, ax=None):
266 """Calculate Pourbaix diagram.
268 U: list of float
269 Potentials in V.
270 pH: list of float
271 pH values.
272 plot: bool
273 Create plot.
274 show: bool
275 Open graphical window and show plot.
276 ax: matplotlib axes object
277 When creating plot, plot onto the given axes object.
278 If none given, plot onto the current one.
279 """
280 a = np.empty((len(U), len(pH)), int)
281 a[:] = -1
282 colors = {}
283 f = functools.partial(self.colorfunction, colors=colors)
284 bisect(a, U, pH, f)
285 compositions = [None] * len(colors)
286 names = [ref[-1] for ref in self.references]
287 for indices, color in colors.items():
288 compositions[color] = ' + '.join(names[i] for i in indices
289 if names[i] not in
290 ['H2O(aq)', 'H+(aq)', 'e-'])
291 text = []
292 for i, name in enumerate(compositions):
293 b = (a == i)
294 x = np.dot(b.sum(1), U) / b.sum()
295 y = np.dot(b.sum(0), pH) / b.sum()
296 name = re.sub(r'(\S)([+-]+)', r'\1$^{\2}$', name)
297 name = re.sub(r'(\d+)', r'$_{\1}$', name)
298 text.append((x, y, name))
300 if plot:
301 import matplotlib.pyplot as plt
302 import matplotlib.cm as cm
303 if ax is None:
304 ax = plt.gca()
306 # rasterized pcolormesh has a bug which leaves a tiny
307 # white border. Unrasterized pcolormesh produces
308 # unreasonably large files. Avoid this by using the more
309 # general imshow.
310 ax.imshow(a, cmap=cm.Accent,
311 extent=[min(pH), max(pH), min(U), max(U)],
312 origin='lower',
313 aspect='auto')
315 for x, y, name in text:
316 ax.text(y, x, name, horizontalalignment='center')
317 ax.set_xlabel('pH')
318 ax.set_ylabel('potential [V]')
319 ax.set_xlim(min(pH), max(pH))
320 ax.set_ylim(min(U), max(U))
321 if show:
322 plt.show()
324 return a, compositions, text
326 def colorfunction(self, U, pH, colors):
327 coefs, energy = self.decompose(U, pH, verbose=False)
328 indices = tuple(sorted(np.where(abs(coefs) > 1e-3)[0]))
329 color = colors.get(indices)
330 if color is None:
331 color = len(colors)
332 colors[indices] = color
333 return color
336class PhaseDiagram:
337 def __init__(self, references, filter='', verbose=True):
338 """Phase-diagram.
340 references: list of (name, energy) tuples
341 List of references. The energy must be the total energy and not
342 energy per atom. The names can also be dicts like
343 ``{'Zn': 1, 'O': 2}`` which would be equivalent to ``'ZnO2'``.
344 filter: str or list of str
345 Use only those references that match the given filter.
346 Example: ``filter='ZnO'`` will select those that
347 contain zinc or oxygen.
348 verbose: bool
349 Write information.
350 """
352 if not references:
353 raise ValueError("You must provide a non-empty list of references"
354 " for the phase diagram! "
355 "You have provided '{}'".format(references))
356 filter = parse_formula(filter)[0]
358 self.verbose = verbose
360 self.species = OrderedDict()
361 self.references = []
362 for name, energy in references:
363 if isinstance(name, str):
364 count = parse_formula(name)[0]
365 else:
366 count = name
368 if filter and any(symbol not in filter for symbol in count):
369 continue
371 if not isinstance(name, str):
372 name = Formula.from_dict(count).format('metal')
374 natoms = 0
375 for symbol, n in count.items():
376 natoms += n
377 if symbol not in self.species:
378 self.species[symbol] = len(self.species)
379 self.references.append((count, energy, name, natoms))
381 ns = len(self.species)
382 self.symbols = [None] * ns
383 for symbol, id in self.species.items():
384 self.symbols[id] = symbol
386 if verbose:
387 print('Species:', ', '.join(self.symbols))
388 print('References:', len(self.references))
389 for i, (count, energy, name, natoms) in enumerate(self.references):
390 print('{:<5}{:10}{:10.3f}'.format(i, name, energy))
392 self.points = np.zeros((len(self.references), ns + 1))
393 for s, (count, energy, name, natoms) in enumerate(self.references):
394 for symbol, n in count.items():
395 self.points[s, self.species[symbol]] = n / natoms
396 self.points[s, -1] = energy / natoms
398 if len(self.points) == ns:
399 # Simple case that qhull would choke on:
400 self.simplices = np.arange(ns).reshape((1, ns))
401 self.hull = np.ones(ns, bool)
402 else:
403 hull = ConvexHull(self.points[:, 1:])
405 # Find relevant simplices:
406 ok = hull.equations[:, -2] < 0
407 self.simplices = hull.simplices[ok]
409 # Create a mask for those points that are on the convex hull:
410 self.hull = np.zeros(len(self.points), bool)
411 for simplex in self.simplices:
412 self.hull[simplex] = True
414 if verbose:
415 print('Simplices:', len(self.simplices))
417 def decompose(self, formula=None, **kwargs):
418 """Find the combination of the references with the lowest energy.
420 formula: str
421 Stoichiometry. Example: ``'ZnO'``. Can also be given as
422 keyword arguments: ``decompose(Zn=1, O=1)``.
424 Example::
426 pd = PhaseDiagram(...)
427 pd.decompose(Zn=1, O=3)
429 Returns energy, indices of references and coefficients."""
431 if formula:
432 assert not kwargs
433 kwargs = parse_formula(formula)[0]
435 point = np.zeros(len(self.species))
436 N = 0
437 for symbol, n in kwargs.items():
438 point[self.species[symbol]] = n
439 N += n
441 # Find coordinates within each simplex:
442 X = self.points[self.simplices, 1:-1] - point[1:] / N
444 # Find the simplex with positive coordinates that sum to
445 # less than one:
446 eps = 1e-15
447 for i, Y in enumerate(X):
448 try:
449 x = np.linalg.solve((Y[1:] - Y[:1]).T, -Y[0])
450 except np.linalg.linalg.LinAlgError:
451 continue
452 if (x > -eps).all() and x.sum() < 1 + eps:
453 break
454 else:
455 assert False, X
457 indices = self.simplices[i]
458 points = self.points[indices]
460 scaledcoefs = [1 - x.sum()]
461 scaledcoefs.extend(x)
463 energy = N * np.dot(scaledcoefs, points[:, -1])
465 coefs = []
466 results = []
467 for coef, s in zip(scaledcoefs, indices):
468 count, e, name, natoms = self.references[s]
469 coef *= N / natoms
470 coefs.append(coef)
471 results.append((name, coef, e))
473 if self.verbose:
474 print_results(results)
476 return energy, indices, np.array(coefs)
478 def plot(self, ax=None, dims=None, show=False, **plotkwargs):
479 """Make 2-d or 3-d plot of datapoints and convex hull.
481 Default is 2-d for 2- and 3-component diagrams and 3-d for a
482 4-component diagram.
483 """
484 import matplotlib.pyplot as plt
486 N = len(self.species)
488 if dims is None:
489 if N <= 3:
490 dims = 2
491 else:
492 dims = 3
494 if ax is None:
495 projection = None
496 if dims == 3:
497 projection = '3d'
498 from mpl_toolkits.mplot3d import Axes3D
499 Axes3D # silence pyflakes
500 fig = plt.figure()
501 ax = fig.add_subplot(projection=projection)
502 else:
503 if dims == 3 and not hasattr(ax, 'set_zlim'):
504 raise ValueError('Cannot make 3d plot unless axes projection '
505 'is 3d')
507 if dims == 2:
508 if N == 2:
509 self.plot2d2(ax, **plotkwargs)
510 elif N == 3:
511 self.plot2d3(ax)
512 else:
513 raise ValueError('Can only make 2-d plots for 2 and 3 '
514 'component systems!')
515 else:
516 if N == 3:
517 self.plot3d3(ax)
518 elif N == 4:
519 self.plot3d4(ax)
520 else:
521 raise ValueError('Can only make 3-d plots for 3 and 4 '
522 'component systems!')
523 if show:
524 plt.show()
525 return ax
527 def plot2d2(self, ax=None,
528 only_label_simplices=False, only_plot_simplices=False):
529 x, e = self.points[:, 1:].T
530 names = [re.sub(r'(\d+)', r'$_{\1}$', ref[2])
531 for ref in self.references]
532 hull = self.hull
533 simplices = self.simplices
534 xlabel = self.symbols[1]
535 ylabel = 'energy [eV/atom]'
537 if ax:
538 for i, j in simplices:
539 ax.plot(x[[i, j]], e[[i, j]], '-b')
540 ax.plot(x[hull], e[hull], 'sg')
541 if not only_plot_simplices:
542 ax.plot(x[~hull], e[~hull], 'or')
544 if only_plot_simplices or only_label_simplices:
545 x = x[self.hull]
546 e = e[self.hull]
547 names = [name for name, h in zip(names, self.hull) if h]
548 for a, b, name in zip(x, e, names):
549 ax.text(a, b, name, ha='center', va='top')
551 ax.set_xlabel(xlabel)
552 ax.set_ylabel(ylabel)
554 return (x, e, names, hull, simplices, xlabel, ylabel)
556 def plot2d3(self, ax=None):
557 x, y = self.points[:, 1:-1].T.copy()
558 x += y / 2
559 y *= 3**0.5 / 2
560 names = [re.sub(r'(\d+)', r'$_{\1}$', ref[2])
561 for ref in self.references]
562 hull = self.hull
563 simplices = self.simplices
565 if ax:
566 for i, j, k in simplices:
567 ax.plot(x[[i, j, k, i]], y[[i, j, k, i]], '-b')
568 ax.plot(x[hull], y[hull], 'og')
569 ax.plot(x[~hull], y[~hull], 'sr')
570 for a, b, name in zip(x, y, names):
571 ax.text(a, b, name, ha='center', va='top')
573 return (x, y, names, hull, simplices)
575 def plot3d3(self, ax):
576 x, y, e = self.points[:, 1:].T
578 ax.scatter(x[self.hull], y[self.hull], e[self.hull],
579 c='g', marker='o')
580 ax.scatter(x[~self.hull], y[~self.hull], e[~self.hull],
581 c='r', marker='s')
583 for a, b, c, ref in zip(x, y, e, self.references):
584 name = re.sub(r'(\d+)', r'$_{\1}$', ref[2])
585 ax.text(a, b, c, name, ha='center', va='bottom')
587 for i, j, k in self.simplices:
588 ax.plot(x[[i, j, k, i]],
589 y[[i, j, k, i]],
590 zs=e[[i, j, k, i]], c='b')
592 ax.set_xlim3d(0, 1)
593 ax.set_ylim3d(0, 1)
594 ax.view_init(azim=115, elev=30)
595 ax.set_xlabel(self.symbols[1])
596 ax.set_ylabel(self.symbols[2])
597 ax.set_zlabel('energy [eV/atom]')
599 def plot3d4(self, ax):
600 x, y, z = self.points[:, 1:-1].T
601 a = x / 2 + y + z / 2
602 b = 3**0.5 * (x / 2 + y / 6)
603 c = (2 / 3)**0.5 * z
605 ax.scatter(a[self.hull], b[self.hull], c[self.hull],
606 c='g', marker='o')
607 ax.scatter(a[~self.hull], b[~self.hull], c[~self.hull],
608 c='r', marker='s')
610 for x, y, z, ref in zip(a, b, c, self.references):
611 name = re.sub(r'(\d+)', r'$_{\1}$', ref[2])
612 ax.text(x, y, z, name, ha='center', va='bottom')
614 for i, j, k, w in self.simplices:
615 ax.plot(a[[i, j, k, i, w, k, j, w]],
616 b[[i, j, k, i, w, k, j, w]],
617 zs=c[[i, j, k, i, w, k, j, w]], c='b')
619 ax.set_xlim3d(0, 1)
620 ax.set_ylim3d(0, 1)
621 ax.set_zlim3d(0, 1)
622 ax.view_init(azim=115, elev=30)
625_aqueous = """\
626-525700,SiF6--
627-514100,Rh(SO4)3----
628-504800,Ru(SO4)3----
629-499900,Pd(SO4)3----
630-495200,Ru(SO4)3---
631-485700,H4P2O7
632-483700,Rh(SO4)3---
633-483600,H3P2O7-
634-480400,H2P2O7--
635-480380,Pt(SO4)3----
636-471400,HP2O7---
637-458700,P2O7----
638-447500,LaF4-
639-437600,LaH2PO4++
640-377900,LaF3
641-376299,Ca(HSiO3)+
642-370691,BeF4--
643-355400,BF4-
644-353025,Mg(HSiO3)+
645-346900,LaSO4+
646-334100,Rh(SO4)2--
647-325400,Ru(SO4)2--
648-319640,Pd(SO4)2--
649-317900,Ru(SO4)2-
650-312970,Cr2O7--
651-312930,CaSO4
652-307890,NaHSiO3
653-307800,LaF2+
654-307000,LaHCO3++
655-306100,Rh(SO4)2-
656-302532,BeF3-
657-300670,Pt(SO4)2--
658-299900,LaCO3+
659-289477,MgSO4
660-288400,LaCl4-
661-281500,HZrO3-
662-279200,HHfO3-
663-276720,Sr(HCO3)+
664-275700,Ba(HCO3)+
665-273830,Ca(HCO3)+
666-273100,H3PO4
667-270140,H2PO4-
668-266500,S2O8--
669-264860,Sr(CO3)
670-264860,SrCO3
671-263830,Ba(CO3)
672-263830,BaCO3
673-262850,Ca(CO3)
674-262850,CaCO3
675-260310,HPO4--
676-257600,LaCl3
677-250200,Mg(HCO3)+
678-249200,H3VO4
679-248700,S4O6--
680-246640,KSO4-
681-243990,H2VO4-
682-243500,PO4---
683-243400,KHSO4
684-242801,HSiO3-
685-241700,HYO2
686-241476,NaSO4-
687-239700,HZrO2+
688-239300,LaO2H
689-238760,Mg(CO3)
690-238760,MgCO3
691-237800,HHfO2+
692-236890,Ag(CO3)2---
693-236800,HNbO3
694-236600,LaF++
695-235640,MnSO4
696-233400,ZrO2
697-233000,HVO4--
698-231600,HScO2
699-231540,B(OH)3
700-231400,HfO2
701-231386,BeF2
702-231000,S2O6--
703-229000,S3O6--
704-229000,S5O6--
705-228460,HTiO3-
706-227400,YO2-
707-227100,NbO3-
708-226700,LaCl2+
709-223400,HWO4-
710-221700,LaO2-
711-218500,WO4--
712-218100,ScO2-
713-214900,VO4---
714-210000,YOH++
715-208900,LaOH++
716-207700,HAlO2
717-206400,HMoO4-
718-204800,H3PO3
719-202350,H2PO3-
720-202290,SrF+
721-201807,BaF+
722-201120,BaF+
723-200400,MoO4--
724-200390,CaF+
725-199190,SiO2
726-198693,AlO2-
727-198100,YO+
728-195900,LaO+
729-195800,LaCl++
730-194000,CaCl2
731-194000,HPO3--
732-191300,LaNO3++
733-190400,ZrOH+++
734-189000,HfOH+++
735-189000,S2O5--
736-187600,ZrO++
737-186000,HfO++
738-183700,HCrO4-
739-183600,ScO+
740-183100,H3AsO4
741-180630,HSO4-
742-180010,H2AsO4-
743-177930,SO4--
744-177690,MgF+
745-174800,CrO4--
746-173300,SrOH+
747-172300,BaOH+
748-172200,HBeO2-
749-171300,CaOH+
750-170790,HAsO4--
751-166000,ReO4-
752-165800,SrCl+
753-165475,Al(OH)++
754-165475,AlOH++
755-164730,BaCl+
756-164000,La+++
757-163800,Y+++
758-163100,CaCl+
759-162240,BO2-
760-158493,BeF+
761-158188,AlO+
762-155700,VOOH+
763-155164,CdF2
764-154970,AsO4---
765-153500,Rh(SO4)
766-152900,BeO2--
767-152370,HSO5-
768-151540,RuCl6---
769-149255,MgOH+
770-147400,H2S2O4
771-146900,HS2O4-
772-146081,CdCl4--
773-145521,BeCl2
774-145200,Ru(SO4)
775-145056,PbF2
776-143500,S2O4--
777-140330,H2AsO3-
778-140300,VO2+
779-140282,HCO3-
780-140200,Sc+++
781-139900,BeOH+
782-139700,MgCl+
783-139200,Ru(SO4)+
784-139000,Pd(SO4)
785-138160,HF2-
786-138100,HCrO2
787-138000,TiO++
788-137300,HGaO2
789-136450,RbF
790-134760,Sr++
791-134030,Ba++
792-133270,Zr++++
793-133177,PbCl4--
794-132600,Hf++++
795-132120,Ca++
796-129310,ZnCl3-
797-128700,GaO2-
798-128600,BeO
799-128570,NaF
800-128000,H2S2O3
801-127500,Rh(SO4)+
802-127200,HS2O3-
803-126191,CO3--
804-126130,HSO3-
805-125300,CrO2-
806-125100,H3PO2
807-124900,S2O3--
808-123641,MnF+
809-122400,H2PO2-
810-121000,HMnO2-
811-120700,RuCl5--
812-120400,MnO4--
813-120300,Pt(SO4)
814-119800,HInO2
815-116300,SO3--
816-115971,CdCl3-
817-115609,Al+++
818-115316,BeCl+
819-112280,AgCl4---
820-111670,TiO2++
821-111500,VOH++
822-111430,Ag(CO3)-
823-110720,HZnO2-
824-108505,Mg++
825-108100,HSeO4-
826-108000,LiOH
827-107600,MnO4-
828-106988,HgCl4--
829-106700,InO2-
830-106700,VO++
831-106100,VO+
832-105500,SeO4--
833-105100,RbOH
834-105000,CsOH
835-104500,KOH
836-104109,ZnF+
837-103900,PdCl4--
838-103579,CuCl4--
839-102600,MnO2--
840-102150,PbCl3-
841-101850,H2SeO3
842-101100,HFeO2
843-100900,CsCl
844-100500,CrOH++
845-99900,NaOH
846-99800,VOH+
847-99250,LiCl
848-98340,HSeO3-
849-98300,ZnCl2
850-97870,RbCl
851-97400,HSbO2
852-97300,HSnO2-
853-97300,MnOH+
854-97016,InF++
855-96240,HAsO2
856-95430,KCl
857-95400,HFeO2-
858-94610,CsBr
859-93290,ZnO2--
860-93250,RhCl4--
861-92910,NaCl
862-92800,CrO+
863-92250,CO2
864-91210,PtCl4--
865-91157,FeF+
866-91100,GaOH++
867-91010,RbBr
868-90550,Be++
869-90010,KBr
870-89963,CuCl3--
871-89730,RuCl4-
872-88400,SeO3--
873-88000,FeO2-
874-87373,CdF+
875-86600,GaO+
876-86500,HCdO2-
877-86290,MnCl+
878-85610,NaBr
879-84851,CdCl2
880-83900,RuCl4--
881-83650,AsO2-
882-83600,Ti+++
883-83460,CsI
884-83400,HCoO2-
885-82710,AgCl3--
886-82400,SbO2-
887-81980,HNiO2-
888-81732,CoF+
889-81500,MnO
890-81190,ZnOH+
891-81000,HPbO2-
892-79768,NiF+
893-79645,FeF++
894-79300,HBiO2
895-78900,RbI
896-77740,KI
897-77700,La++
898-77500,RhCl4-
899-75860,PbF+
900-75338,CuCl3-
901-75216,TlF
902-75100,Ti++
903-74600,InOH++
904-74504,HgCl3-
905-73480,FeCl2
906-72900,NaI
907-71980,SO2
908-71662,HF
909-71600,RuO4--
910-71200,PbCl2
911-69933,Li+
912-69810,PdCl3-
913-69710,Cs+
914-69400,InO+
915-67811,AuCl3--
916-67800,Rb+
917-67510,K+
918-67420,ZnO
919-67340,F-
920-67300,CdO2--
921-66850,ZnCl+
922-65850,FeOH+
923-65550,TlOH
924-64200,NiO2--
925-63530,RhCl3-
926-63200,CoO2--
927-62591,Na+
928-61700,BiO2-
929-61500,CdOH+
930-60100,HCuO2-
931-59226,InCl++
932-58600,SnOH+
933-58560,RuCl3
934-58038,CuCl2-
935-57900,V+++
936-57800,FeOH++
937-57760,PtCl3-
938-57600,HTlO2
939-56690,H2O
940-56025,CoOH+
941-55100,Mn++
942-54380,RuCl3-
943-53950,PbOH+
944-53739,CuF+
945-53600,SnO
946-53100,FeO+
947-53030,FeCl+
948-52850,NiOH+
949-52627,CdCl+
950-52000,V++
951-51560,AgCl2-
952-50720,FeO
953-49459,AgF
954-49300,Cr+++
955-47500,CdO
956-46190,RhCl3
957-46142,CuCl2
958-45200,HHgO2-
959-45157,CoCl+
960-44000,CoO
961-42838,HgCl2
962-41600,TlO2-
963-41200,CuO2--
964-40920,NiCl+
965-39815,TlCl
966-39400,Cr++
967-39350,PbO
968-39340,NiO
969-39050,PbCl+
970-38000,Ga+++
971-37518,FeCl++
972-36781,AuCl2-
973-35332,AuCl4-
974-35200,Zn++
975-35160,PdCl2
976-33970,RhCl2
977-32300,BiOH++
978-31700,HIO3
979-31379,Cl-
980-30600,IO3-
981-30410,HCl
982-30204,HgF+
983-30200,CuOH+
984-29300,BiO+
985-28682,CO
986-26507,NO3-
987-26440,RuCl2+
988-25590,Br3-
989-25060,RuCl2
990-24870,Br-
991-24730,HNO3
992-23700,HIO
993-23400,In+++
994-23280,OCN-
995-23000,CoOH++
996-22608,CuCl
997-22290,PtCl2
998-21900,AgOH
999-21870,Fe++
1000-20800,CuO
1001-20300,Mn+++
1002-20058,Pb(HS)2
1003-19700,HBrO
1004-19100,HClO
1005-19100,ScOH++
1006-18990,NH4+
1007-18971,Pb(HS)3-
1008-18560,Cd++
1009-18290,Rh(OH)+
1010-17450,AgCl
1011-16250,CuCl+
1012-14780,RhCl2+
1013-14000,IO4-
1014-13130,Pd(OH)+
1015-13000,Co++
1016-12700,HgOH+
1017-12410,I-
1018-12300,I3-
1019-12190,Ru(OH)2++
1020-12100,HNO2
1021-11500,PdO
1022-10900,Ni++
1023-10470,Ru(OH)+
1024-10450,RuO+
1025-9200,IO-
1026-8900,HgO
1027-8800,ClO-
1028-8000,BrO-
1029-7740,Tl+
1030-7738,AgNO3
1031-7700,NO2-
1032-7220,RhO
1033-6673,H2S
1034-6570,Sn++
1035-6383,NH3
1036-5710,Pb++
1037-5500,AgO-
1038-4500,TlOH++
1039-4120,Fe+++
1040-3380,RhCl+
1041-3200,TlO+
1042-3184,AuCl
1043-2155,HgCl+
1044-2040,ClO4-
1045-1900,ClO3-
1046-1130,PtO
1047-820,Rh(OH)++
10480,Ag(HS)2-
10490,H+
1050230,RuO
10511400,HClO2
10521560,Pt(OH)+
10532429,Au(HS)2-
10542500,PdCl+
10552860,HS-
10563140,RhO+
10573215,Xe
10583554,Kr
10593890,Ar
10604100,ClO2-
10614347,N2
10624450,BrO3-
10634565,Ne
10644658,He
10655210,RuCl+
10667100,RuCl++
10678600,H2N2O2
10689375,TlCl++
106910500,HSe-
107011950,Cu+
107115675,Cu++
107215700,S5--
107316500,S4--
107417600,S3--
107518200,HN2O2-
107618330,RhCl++
107718380,PtCl+
107818427,Ag+
107919000,S2--
108019500,SeCN-
108119700,N2H5+
108221100,N2H6++
108322160,SCN-
108422880,Bi+++
108527700,Rh++
108628200,BrO4-
108728600,HCN
108832000,Co+++
108933200,N2O2--
109035900,Ru++
109136710,Hg2++
109239360,Hg++
109341200,CN-
109441440,Ru+++
109542200,Pd++
109651300,Tl+++
109752450,Rh+++
109861600,Pt++
109964300,Ag++
1100103600,Au+++"""