Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
torchani
Commits
e88f6266
"server/tests/models/test_bloom.py" did not exist on "31d76e238df7654157ab1e372b7d57ef859daaa7"
Unverified
Commit
e88f6266
authored
May 21, 2019
by
Gao, Xiang
Committed by
GitHub
May 21, 2019
Browse files
Add vibrational mode support (#228)
parent
4452f68d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
23 additions
and
7 deletions
+23
-7
examples/vibration_analysis.py
examples/vibration_analysis.py
+6
-2
tests/test_vibrational.py
tests/test_vibrational.py
+13
-2
torchani/utils.py
torchani/utils.py
+4
-3
No files found.
examples/vibration_analysis.py
View file @
e88f6266
...
...
@@ -69,5 +69,9 @@ print(hessian.shape)
# We are now ready to compute vibrational frequencies. The output has unit
# cm^-1. Since there are in total 9 degree of freedom, there are in total 9
# frequencies. Only the frequencies of the 3 vibrational modes are interesting.
freq
=
torchani
.
utils
.
vibrational_analysis
(
masses
,
hessian
)[
-
3
:]
print
(
freq
)
freq
,
modes
=
torchani
.
utils
.
vibrational_analysis
(
masses
,
hessian
)
freq
=
freq
[
-
3
:]
modes
=
modes
[
-
3
:]
print
(
'Frequencies (cm^-1):'
,
freq
)
print
(
'Modes:'
,
modes
)
tests/test_vibrational.py
View file @
e88f6266
...
...
@@ -30,16 +30,27 @@ class TestVibrational(unittest.TestCase):
# compute vibrational frequencies by ASE
vib
=
ase
.
vibrations
.
Vibrations
(
molecule
)
vib
.
run
()
freq
=
torch
.
tensor
([
numpy
.
real
(
x
)
for
x
in
vib
.
get_frequencies
()[
-
3
:]])
freq
=
torch
.
tensor
([
numpy
.
real
(
x
)
for
x
in
vib
.
get_frequencies
()[
6
:]])
modes
=
[]
for
j
in
range
(
6
,
6
+
len
(
freq
)):
modes
.
append
(
vib
.
get_mode
(
j
))
modes
=
torch
.
tensor
(
modes
)
# compute vibrational by torchani
species
=
model
.
species_to_tensor
(
molecule
.
get_chemical_symbols
()).
unsqueeze
(
0
)
coordinates
=
torch
.
from_numpy
(
molecule
.
get_positions
()).
unsqueeze
(
0
).
requires_grad_
(
True
)
_
,
energies
=
model
((
species
,
coordinates
))
hessian
=
torchani
.
utils
.
hessian
(
coordinates
,
energies
=
energies
)
freq2
=
torchani
.
utils
.
vibrational_analysis
(
masses
[
species
],
hessian
)[
-
3
:].
float
()
freq2
,
modes2
=
torchani
.
utils
.
vibrational_analysis
(
masses
[
species
],
hessian
)
freq2
=
freq2
[
6
:].
float
()
modes2
=
modes2
[
6
:]
ratio
=
freq2
/
freq
self
.
assertLess
((
ratio
-
1
).
abs
().
max
(),
0.02
)
diff1
=
(
modes
-
modes2
).
abs
().
max
(
dim
=-
1
).
values
.
max
(
dim
=-
1
).
values
diff2
=
(
modes
+
modes2
).
abs
().
max
(
dim
=-
1
).
values
.
max
(
dim
=-
1
).
values
diff
=
torch
.
where
(
diff1
<
diff2
,
diff1
,
diff2
)
self
.
assertLess
(
diff
.
max
(),
0.02
)
if
__name__
==
'__main__'
:
unittest
.
main
()
torchani/utils.py
View file @
e88f6266
...
...
@@ -248,18 +248,19 @@ def vibrational_analysis(masses, hessian, unit='cm^-1'):
# We solve this eigenvalue problem through Lowdin diagnolization:
# Hq = w^2 * Tq ==> Hq = w^2 * T^(1/2) T^(1/2) q
# Letting q' = T^(1/2) q, we then have
# T^(-1/2) H T^(1/2) q' = w^2 * q'
# T^(-1/2) H T^(
-
1/2) q' = w^2 * q'
inv_sqrt_mass
=
(
1
/
masses
.
sqrt
()).
repeat_interleave
(
3
,
dim
=
1
)
# shape (molecule, 3 * atoms)
mass_scaled_hessian
=
hessian
*
inv_sqrt_mass
.
unsqueeze
(
1
)
*
inv_sqrt_mass
.
unsqueeze
(
2
)
if
mass_scaled_hessian
.
shape
[
0
]
!=
1
:
raise
ValueError
(
'The input should contain only one molecule'
)
mass_scaled_hessian
=
mass_scaled_hessian
.
squeeze
(
0
)
eigenvalues
=
torch
.
symeig
(
mass_scaled_hessian
).
eigenv
al
ue
s
eigenvalues
,
eigenvectors
=
torch
.
symeig
(
mass_scaled_hessian
,
eigenv
ectors
=
Tr
ue
)
angular_frequencies
=
eigenvalues
.
sqrt
()
frequencies
=
angular_frequencies
/
(
2
*
math
.
pi
)
# converting from sqrt(hartree / (amu * angstrom^2)) to cm^-1
wavenumbers
=
frequencies
*
17092
return
wavenumbers
modes
=
(
eigenvectors
.
t
()
*
inv_sqrt_mass
).
reshape
(
frequencies
.
numel
(),
-
1
,
3
)
return
wavenumbers
,
modes
__all__
=
[
'pad'
,
'pad_coordinates'
,
'present_species'
,
'hessian'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment