forked from duartegroup/autodE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_value.py
253 lines (167 loc) · 6.46 KB
/
test_value.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
import pytest
import numpy as np
from autode.constants import Constants
from autode.units import (ha, kjmol, kcalmol, ev,
ang, a0, nm, pm, m,
rad, deg)
from autode.values import (Value, Distance, MWDistance, Angle, Mass,
Energy, Energies,
PotentialEnergy, Enthalpy, FreeEnergy,
FreeEnergyCont, EnthalpyCont,
Frequency,
GradientRMS)
class TmpValue(Value):
def __repr__(self):
return ''
def test_base_value():
val = TmpValue(0.0)
assert val == 0.0
assert val != None
assert hasattr(val, 'units')
# Same representation as the string
assert repr(val) == ""
val2 = val.copy()
val += 1
assert val2 == 0.
# Values are equal to default numpy isclose precision
# (1e-08 as of 20/05/21)
assert TmpValue(0.0) == TmpValue(1E-10)
def test_base_value_numpy_add():
res = np.array([0.0, 0.0]) + TmpValue(0.1)
assert isinstance(res, np.ndarray)
assert np.allclose(res, np.array([0.1, 0.1]), atol=1E-10)
def test_energy():
with pytest.raises(ValueError):
Energy(0.0, units='not_an_energy_unit')
e1 = Energy(0.0)
assert 'energy' in repr(e1).lower()
assert type(e1.method_str) is str
assert e1 == 0.0
assert -0.001 < e1 < 0.001
assert -0.001 <= e1 <= 0.001
assert e1.units == ha
# Cannot convert to a non-existent unit
with pytest.raises(TypeError):
_ = e1.to('xxx')
# or to a non-energy unit
with pytest.raises(TypeError):
_ = e1.to(deg)
# but can convert to a different type of energy unit
e1_kcal = e1.to(kcalmol)
assert e1_kcal == 0.0
# Conversion is not in place
assert e1.units == ha
e1 -= 0.1
assert isinstance(e1, Energy)
assert e1 == -0.1
e1 *= 10
assert np.isclose(e1, -1.0)
# Should be able to add two energies
e3 = e1 + Energy(1)
assert e3 == 0.0
e_kcal = Energy(1*Constants.ha_to_kcalmol, units=kcalmol)
e_ha = Energy(1.0)
# Values have implicit type conversion, left precedence
assert np.isclose((e_ha + e_kcal), 2.0)
assert (e_ha + e_kcal).units == ha
# So the other way should add in kcal mol-1
assert (e_kcal + e_ha) > 600
# Comparisons are viable in different units
assert Energy(1*Constants.ha_to_kcalmol, units=kcalmol) < Energy(2, units=ha)
assert Energy(1*Constants.ha_to_kcalmol, units=kcalmol) > Energy(0.5, units=ha)
# Math operations should not be in-place
e1 = Energy(0.1)
e2 = Energy(0.2)
e3 = e1 + e2
assert e3 == 0.3 and e1 == 0.1
assert Energy(1.0) == Energy(1.0)
assert Energy(1.0) != Energy(1.1)
assert Energy(1.0, units=ha) == Energy(1.0*Constants.ha_to_kcalmol,
units=kcalmol)
assert np.isclose(Energy(1.0, units=kcalmol),
Energy(4.0, units=kjmol).to('kcal'),
atol=0.5)
assert np.isclose(Energy(27, units=ev),
Energy(1, units=ha).to(ev),
atol=0.5)
assert (Energy(1.0) * 10.0) == 10
assert (10.0 * Energy(1.0)) == 10
def test_energy_equality():
"""Energies must be equal to within """
assert (Energy(-151.552245224975, units='Ha')
!= Energy(-151.551673511378, units='Ha'))
# Allowable comparison of energies and floats, assuming Ha units
assert (Energy(-151.552245224975, units='Ha')
!= -151.551673511378)
def test_enthalpy():
assert Enthalpy(1.0) != PotentialEnergy(1.0)
assert PotentialEnergy(1.0) != Enthalpy(1.0)
def test_free_energy():
assert FreeEnergy(1.0) != PotentialEnergy(1.0)
assert FreeEnergy(1.0) != Enthalpy(1.0)
assert PotentialEnergy(1.0) != FreeEnergy(1.0)
def test_distance():
assert 'dist' in repr(Distance(1.0)).lower()
assert all(w in repr(MWDistance(1.0)).lower() for w in ('dist', 'mass'))
# Bohrs are ~2 angstroms
assert np.isclose(Distance(1.0, units=ang),
Distance(2.0, units=a0).to(ang),
atol=0.3)
assert Distance(1.0, units=ang) == Distance(0.1, units=nm)
assert Distance(1.0, units=ang) == Distance(100, units=pm)
assert Distance(1.0, units=ang) == Distance(1E-10, units=m)
def test_angle():
assert 'ang' in repr(Angle(1.0)).lower()
assert Angle(np.pi, units=rad) == Angle(180.0, units=deg)
def test_energies():
energies = Energies()
energies.append(Energy(1.0))
energies.append(Energy(1.0))
# Should not append identical energies
assert len(energies) == 1
energies = Energies(Energy(1.0), FreeEnergy(0.1))
assert energies.last(FreeEnergy) == FreeEnergy(0.1)
assert 'free' in repr(FreeEnergy(0.0)).lower()
assert 'enthalpy' in repr(Enthalpy(0.0)).lower()
assert 'cont' in repr(FreeEnergyCont(0.0)).lower()
assert 'cont' in repr(EnthalpyCont(0.0)).lower()
# Check that adding an energy that is already present moves it to the end
energies = Energies()
energies.append(Energy(1.0))
energies.append(Energy(5.0))
energies.append(Energy(1.0))
assert energies.last(Energy) == 1.0
def test_freqs():
# Negative frequencies are actually imaginary (accepted convention in QM
# codes)
assert Frequency(-1.0).is_imaginary
assert not Frequency(1.0).is_imaginary
assert 'freq' in repr(Frequency(1.0)).lower()
assert Frequency(-1.0) != Frequency(1.0)
assert Frequency(-1.0).real == Frequency(1.0)
def test_mass():
one_amu = Mass(1.0, units='amu')
assert 'mass' in repr(one_amu).lower()
assert np.isclose(one_amu.to('kg'), 1E-17, atol=1E-17)
assert np.isclose(one_amu.to('me'), 1823, atol=1)
def test_contrib_guidelines():
"""If any of these tests fail please modify doc/dev/contributing.rst
to reflect any changes"""
r = Distance(1.0)
assert repr(r) == 'Distance(1.0 Å)'
assert repr(r.to('nm')) == 'Distance(0.1 nm)'
assert repr(r.to('nanometer')) == "Distance(0.1 nm)"
assert r > Distance(9.0, units='pm')
with pytest.raises(TypeError):
_ = r.to('eV')
def test_gradient_norm():
assert repr(GradientRMS(0.1)) is not None
def test_to_wrong_type():
from autode.values import _to
# To function must have either a Value or a ValueArray
with pytest.raises(Exception):
_to('a', units='Å')
class Tmp:
units = 'X'
with pytest.raises(Exception):
_to(Tmp(), units='Å')