forked from jboes/ase-espresso
-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.py
106 lines (94 loc) · 4.26 KB
/
utils.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
#****************************************************************************
# Copyright (C) 2013 SUNCAT
# This file is distributed under the terms of the
# GNU General Public License. See the file `COPYING'
# in the root directory of the present distribution,
# or http://www.gnu.org/copyleft/gpl.txt .
#****************************************************************************
import numpy as np
from ase import constraints
class SpecObject:
"""Small species class containing the attributes of a species."""
def __init__(self, s='X', mass=0., magmom=0., U=0., J=0., U_alpha=0.):
self.s = s
self.mass = mass
self.magmom = magmom
self.U = U
self.J = J
self.U_alpha = U_alpha
# add 'd0' to floating point number to avoid random trailing digits in
# Fortran input routines
def num2str(x):
s = str(x)
if s.find('e') < 0:
s += 'd0'
return s
# convert python to fortran logical
def bool2str(x):
if x:
return '.true.'
else:
return '.false.'
def convert_constraints(atoms):
"""Convert some of ase's constraints to pw.x constraints for pw.x internal
relaxationreturns constraints which are simply expressed as setting force
components as first list and other contraints that are implemented in
espresso as second list.
"""
if atoms.constraints:
n = len(atoms)
if n == 0:
return [], []
forcefilter = []
otherconstr = []
for c in atoms.constraints:
if isinstance(c, constraints.FixAtoms):
if len(forcefilter) == 0:
forcefilter = np.ones((n, 3), np.int)
forcefilter[c.index] = [0, 0, 0]
elif isinstance(c, constraints.FixCartesian):
if len(forcefilter) == 0:
forcefilter = np.ones((n, 3), np.int)
forcefilter[c.a] = c.mask
elif isinstance(c, constraints.FixBondLengths):
for d in c.constraints:
otherconstr.append("'distance' %d %d" % (d.indices[0] + 1,
d.indices[1] + 1))
elif isinstance(c, constraints.FixBondLength):
otherconstr.append("'distance' %d %d" % (c.indices[0] + 1,
c.indices[1] + 1))
elif isinstance(c, constraints.FixInternals):
# we ignore the epsilon in FixInternals because there can only be one global
# epsilon be defined in espresso for all constraints
for d in c.constraints:
if isinstance(d,
constraints.FixInternals.FixBondLengthAlt):
otherconstr.append("'distance' %d %d %s" %
(d.indices[0] + 1, d.indices[1] + 1,
num2str(d.bond)))
elif isinstance(d, constraints.FixInternals.FixAngle):
otherconstr.append(
"'planar_angle' %d %d %d %s" %
(d.indices[0] + 1, d.indices[1] + 1,
d.indices[2] + 1,
num2str(np.arccos(d.angle) * 180. / np.pi)))
elif isinstance(d, constraints.FixInternals.FixDihedral):
otherconstr.append(
"'torsional_angle' %d %d %d %d %s" %
(d.indices[0] + 1, d.indices[1] + 1,
d.indices[2] + 1, d.indices[3] + 1,
num2str(np.arccos(d.angle) * 180. / np.pi)))
else:
raise NotImplementedError(
'constraint ' + d.__name__ +
' from FixInternals not implemented\n'
'consider ase-based relaxation with this constraint instead'
)
else:
raise NotImplementedError(
'constraint ' + c.__name__ + ' not implemented\n'
'consider ase-based relaxation with this constraint instead'
)
return forcefilter, otherconstr
else:
return [], []