ForceBalance API  1.3
Automated optimization of force fields and empirical potentials
chemistry.py
Go to the documentation of this file.
1 from __future__ import division
2 from collections import defaultdict, OrderedDict
3 import re
4 import numpy as np
5 
6 # To look up a 2-tuple of (bond energy in kJ/mol / bond order in Angstrom):
7 # Do BondEnergies[Elem1][Elem2][BO]
8 BondEnergies = defaultdict(lambda:defaultdict(dict))
9 
10 
12 Radii = [0.31, 0.28, # H and He
13  1.28, 0.96, 0.84, 0.76, 0.71, 0.66, 0.57, 0.58, # First row elements
14  0.0, 1.41, 1.21, 1.11, 1.07, 1.05, 1.02, 1.06, # Second row elements
15  2.03, 1.76, 1.70, 1.60, 1.53, 1.39, 1.61, 1.52, 1.50,
16  1.24, 1.32, 1.22, 1.22, 1.20, 1.19, 1.20, 1.20, 1.16, # Third row elements, K through Kr
17  2.20, 1.95, 1.90, 1.75, 1.64, 1.54, 1.47, 1.46, 1.42,
18  1.39, 1.45, 1.44, 1.42, 1.39, 1.39, 1.38, 1.39, 1.40, # Fourth row elements, Rb through Xe
19  2.44, 2.15, 2.07, 2.04, 2.03, 2.01, 1.99, 1.98,
20  1.98, 1.96, 1.94, 1.92, 1.92, 1.89, 1.90, 1.87, # Fifth row elements, s and f blocks
21  1.87, 1.75, 1.70, 1.62, 1.51, 1.44, 1.41, 1.36,
22  1.36, 1.32, 1.45, 1.46, 1.48, 1.40, 1.50, 1.50, # Fifth row elements, d and p blocks
23  2.60, 2.21, 2.15, 2.06, 2.00, 1.96, 1.90, 1.87, 1.80, 1.69] # Sixth row elements
24 
25 # The periodic table
26 
27 PeriodicTable = OrderedDict([('H',1.0079),('He',4.0026),
28  ('Li',6.941),('Be',9.0122),('B',10.811),('C',12.0107),('N',14.0067),('O',15.9994),('F',18.9984),('Ne',20.1797),
29  ('Na',22.9897),('Mg',24.305),('Al',26.9815),('Si',28.0855),('P',30.9738),('S',32.065),('Cl',35.453),('Ar',39.948),
30  ('K',39.0983),('Ca',40.078),('Sc',44.9559),('Ti',47.867),('V',50.9415),('Cr',51.9961),('Mn',54.938),('Fe',55.845),('Co',58.9332),
31  ('Ni',58.6934),('Cu',63.546),('Zn',65.39),('Ga',69.723),('Ge',72.64),('As',74.9216),('Se',78.96),('Br',79.904),('Kr',83.8),
32  ('Rb',85.4678),('Sr',87.62),('Y',88.9059),('Zr',91.224),('Nb',92.9064),('Mo',95.94),('Tc',98),('Ru',101.07),('Rh',102.9055),
33  ('Pd',106.42),('Ag',107.8682),('Cd',112.411),('In',114.818),('Sn',118.71),('Sb',121.76),('Te',127.6),('I',126.9045),('Xe',131.293),
34  ('Cs',132.9055),('Ba',137.327),('La',138.9055),('Ce',140.116),('Pr',140.9077),('Nd',144.24),('Pm',145),('Sm',150.36),
35  ('Eu',151.964),('Gd',157.25),('Tb',158.9253),('Dy',162.5),('Ho',164.9303),('Er',167.259),('Tm',168.9342),('Yb',173.04),
36  ('Lu',174.967),('Hf',178.49),('Ta',180.9479),('W',183.84),('Re',186.207),('Os',190.23),('Ir',192.217),('Pt',195.078),
37  ('Au',196.9665),('Hg',200.59),('Tl',204.3833),('Pb',207.2),('Bi',208.9804),('Po',209),('At',210),('Rn',222),
38  ('Fr',223),('Ra',226),('Ac',227),('Th',232.0381),('Pa',231.0359),('U',238.0289),('Np',237),('Pu',244),
39  ('Am',243),('Cm',247),('Bk',247),('Cf',251),('Es',252),('Fm',257),('Md',258),('No',259),
40  ('Lr',262),('Rf',261),('Db',262),('Sg',266),('Bh',264),('Hs',277),('Mt',268)])
41 
42 Elements = ["None",'H','He',
43  'Li','Be','B','C','N','O','F','Ne',
44  'Na','Mg','Al','Si','P','S','Cl','Ar',
45  'K','Ca','Sc','Ti','V','Cr','Mn','Fe','Co','Ni','Cu','Zn','Ga','Ge','As','Se','Br','Kr',
46  'Rb','Sr','Y','Zr','Nb','Mo','Tc','Ru','Rh','Pd','Ag','Cd','In','Sn','Sb','Te','I','Xe',
47  'Cs','Ba','La','Ce','Pr','Nd','Pm','Sm','Eu','Gd','Tb','Dy','Ho','Er','Tm','Yb',
48  'Lu','Hf','Ta','W','Re','Os','Ir','Pt','Au','Hg','Tl','Pb','Bi','Po','At','Rn',
49  'Fr','Ra','Ac','Th','Pa','U','Np','Pu','Am','Cm','Bk','Cf','Es','Fm','Md','No','Lr','Rf','Db','Sg','Bh','Hs','Mt']
50 
51 BondChars = ['-','=','3']
52 
53 # Sources: http://www.science.uwaterloo.ca/~cchieh/cact/c120/bondel.html
54 # http://www.wiredchemist.com/chemistry/data/bond_energies_lengths.html
55 # http://s-owl.cengage.com/ebooks/vining_owlbook_prototype/ebook/ch8/Sect8-3-a.html
56 data_from_web= """H-H 432 74
57 H-B 389 119
58 H-C 411 109
59 H-Si 318 148
60 H-Ge 288 153
61 H-Sn 251 170
62 H-N 386 101
63 H-P 322 144
64 H-As 247 152
65 H-O 459 96
66 H-S 363 134
67 H-Se 276 146
68 H-Te 238 170
69 H-F 565 92
70 H-Cl 428 127
71 H-Br 362 141
72 H-I 295 161
73 B-Cl 456 175
74 C-C 346 154
75 C=C 602 134
76 C3C 835 120
77 C-Si 318 185
78 C-Ge 238 195
79 C-Sn 192 216
80 C-Pb 130 230
81 C-N 305 147
82 C=N 615 129
83 C3N 887 116
84 C-P 264 184
85 C-O 358 143
86 C=O 799 120
87 C3O 1072 113
88 C-S 272 182
89 C=S 573 160
90 C-F 485 135
91 C-Cl 327 177
92 C-Br 285 194
93 C-I 213 214
94 Si-Si 222 233
95 Si-O 452 163
96 Si-S 293 200
97 Si-F 565 160
98 Si-Cl 381 202
99 Si-Br 310 215
100 Si-I 234 243
101 Ge-Ge 188 241
102 Ge-F 470 168
103 Ge-Cl 349 210
104 Ge-Br 276 230
105 Sn-Cl 323 233
106 Sn-Br 273 250
107 Sn-I 205 270
108 Pb-Cl 243 242
109 Pb-I 142 279
110 N-N 167 145
111 N=N 418 125
112 N3N 942 110
113 N-O 201 140
114 N=O 607 121
115 N-F 283 136
116 N-Cl 313 175
117 P-P 201 221
118 P-O 335 163
119 P=O 544 150
120 P=S 335 186
121 P-F 490 154
122 P-Cl 326 203
123 As-As 146 243
124 As-O 301 178
125 As-F 484 171
126 As-Cl 322 216
127 As-Br 458 233
128 As-I 200 254
129 Sb-Cl 315 232
130 O-O 142 148
131 O=O 494 121
132 O-F 190 142
133 S=O 522 143
134 S-S 226 205
135 S=S 425 149
136 S-F 284 156
137 S-Cl 255 207
138 Se=Se 272 215
139 F-F 155 142
140 Cl-Cl 240 199
141 Br-Br 190 228
142 I-I 148 267
143 I-F 273 191
144 I-Cl 208 232
145 Kr-F 50 190
146 Xe-O 84 175
147 Xe-F 130 195"""
148 
149 for line in data_from_web.split('\n'):
150  line = line.expandtabs()
151  BE = float(line.split()[1]) # In kJ/mol
152  L = float(line.split()[2]) * 0.01 # In Angstrom
153  atoms = re.split('[-=3]', line.split()[0])
154  A = atoms[0]
155  B = atoms[1]
156  bo = BondChars.index(re.findall('[-=3]', line.split()[0])[0]) + 1
157  BondEnergies[A][B][bo] = (BE, L)
158  BondEnergies[B][A][bo] = (BE, L)
159 
160 def LookupByMass(mass):
161  Deviation = 1e10
162  EMatch = None
163  for e, m in PeriodicTable.items():
164  if np.abs(mass - m) < Deviation:
165  EMatch = e
166  Deviation = np.abs(mass - m)
167  return EMatch
168 
169 def BondStrengthByLength(A, B, length, artol = 0.33, bias=0.0):
170  # Bond length Must be in Angstrom!!
171  # Set artol lower to get more aromatic bonds ; 0.5 means no aromatic bonds.
172  Deviation = 1e10
173  BOMatch = None
174  if length < 0.5: # Assume using nanometers
175  length *= 10
176  if length > 50: # Assume using picometers
177  length /= 100
178  # A positive bias means a lower bond order.
179  length += bias
180  # Determine the bond order and the bond strength
181  # We allow bond order 1.5 as well :)
182  Devs = {}
183  for BO, Vals in BondEnergies[A][B].items():
184  S = Vals[0]
185  L = Vals[1]
186  Devs[BO] = np.abs(length-L)
187  if np.abs(length-L) < Deviation:
188  BOMatch = BO
189  Strength = S
190  Deviation = np.abs(length-L)
191  if len(Devs.items()) >= 2:
192  Spac = Devs[1] + Devs[2]
193  Frac1 = Devs[1]/Spac
194  Frac2 = Devs[2]/Spac
195  if Frac1 > artol and Frac2 > artol:
196  #print A, B, L, Frac1, Frac2
197  BOMatch = 1.5
198  Strength = 0.5 * (BondEnergies[A][B][1][0] + BondEnergies[A][B][2][0])
199  return Strength, BOMatch
def LookupByMass(mass)
Definition: chemistry.py:160
def BondStrengthByLength(A, B, length, artol=0.33, bias=0.0)
Definition: chemistry.py:169