Coverage for hiphive/input_output/gpumd.py: 98%
Shortcuts 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
Shortcuts 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 numpy as np
2from itertools import permutations, product
5def write_fcs_gpumd(fname_fc: str,
6 fname_clusters: str,
7 fcs,
8 order: int,
9 tol: float = 1e-10):
10 """
11 Writes force constants of given order in GPUMD format.
13 Parameters
14 ----------
15 fname_fc
16 name of file which contains the lookup force constants
17 fname_clusters
18 name of file which contains the clusters and the force constant lookup index
19 fcs
20 force constants
21 order
22 force constants for this order will be written to file
23 tol
24 if the norm of a force constant term is less than this value it will be excluded
25 from the output;
26 if two force-constants differ by this value or less, they are considered equal.
27 """
28 cluster_lookup, fc_lookup = _get_lookup_data_smart(fcs, order, tol)
29 _write_clusters(fname_clusters, cluster_lookup, order)
30 _write_fc_lookup(fname_fc, fc_lookup, order)
33def _write_fc_lookup(fname, fc_lookup, order):
34 """ Writes the lookup force constants to file """
35 fmt = '{}' + ' {}'*order
36 with open(fname, 'w') as f:
37 f.write(str(len(fc_lookup)) + '\n\n')
38 for fc in fc_lookup:
39 for xyz in product(range(3), repeat=order):
40 f.write(fmt.format(*xyz, fc[xyz])+'\n')
41 f.write('\n')
44def _write_clusters(fname, cluster_lookup, order):
45 """ Writes the cluster lookup to file """
46 fmt = '{}' + ' {}'*order
47 with open(fname, 'w') as f:
48 f.write(str(len(cluster_lookup)) + '\n\n')
49 for c, i in cluster_lookup.items():
50 line = fmt.format(*c, i) + '\n'
51 f.write(line)
54def _get_clusters(fcs,
55 order: int,
56 tol: float):
57 """ Collect all relevant clusters; for 2nd and 3rd-order force constants
58 all permutations are included.
59 """
60 if order in [2, 3]:
61 clusters = []
62 for c in fcs._fc_dict.keys():
63 if len(c) == order and np.linalg.norm(fcs[c]) > tol:
64 for ci in permutations(c):
65 clusters.append(ci)
66 clusters = list(sorted(set(clusters)))
67 else:
68 clusters = [c for c in fcs._fc_dict.keys() if len(c) == order and np.linalg.norm(fcs[c]) > tol] # noqa
69 return clusters
72def _get_lookup_data_naive(fcs,
73 order: int,
74 tol: float):
75 """ Groups force constants for a given order into groups for which the
76 force constant is identical. """
77 fc_lookup = []
78 cluster_lookup = dict()
80 clusters = _get_clusters(fcs, order, tol)
82 for c in clusters:
83 fc1 = fcs[c]
84 if np.linalg.norm(fc1) < tol: 84 ↛ 85line 84 didn't jump to line 85, because the condition on line 84 was never true
85 continue
86 for i, fc2 in enumerate(fc_lookup):
87 if np.linalg.norm(fc1 - fc2) < tol:
88 cluster_lookup[c] = i
89 break
90 else:
91 cluster_lookup[c] = len(fc_lookup)
92 fc_lookup.append(fc1)
93 return cluster_lookup, fc_lookup
96def _get_lookup_data_smart(fcs,
97 order: int,
98 tol: float):
99 """ Groups force constants for a given order into groups for which the
100 force constant is identical. """
101 fc_lookup = []
102 cluster_lookup = dict()
103 axis = tuple(range(1, order+1))
105 clusters = _get_clusters(fcs, order, tol)
106 fc_all = np.array([fcs[c] for c in clusters])
108 indices = list(range(len(clusters)))
109 while len(indices) > 0:
110 i = indices[0]
111 delta = fc_all[indices] - fc_all[i]
112 delta_norm = np.sqrt(np.sum(delta**2, axis=axis))
114 inds_to_del = [indices[x] for x in np.where(delta_norm < tol)[0]]
115 assert i in inds_to_del
117 fc_lookup.append(fc_all[i])
118 for j in inds_to_del:
119 indices.remove(j)
120 cluster_lookup[clusters[j]] = len(fc_lookup)-1
121 return cluster_lookup, fc_lookup
124def write_fcp_txt(fname: str,
125 path: str,
126 n_types: int,
127 max_order: int,
128 heat_current_order: int = 2):
129 """ Write driver potential file for GPUMD.
131 Parameters
132 ----------
133 fname
134 file name
135 path
136 path to directory with force constant file
137 n_types
138 number of atom types
139 max_order
140 maximum order of the force constant potential
141 heat_current_order
142 heat current order used in thermal conductivity
145 Format is a simple file containing the following
147 fcp number_of_atom_types
148 highest_force_order heat_current_order
149 path_to_force_constant_files
151 which in practice for a binary system with a sixth order model,
152 consider third-order heat-currents, would mean
154 fcp 2
155 6 3
156 /path/to/your/folder
157 """
159 with open(fname, 'w') as f:
160 f.write('fcp {}\n'.format(n_types))
161 f.write('{} {}\n'.format(max_order, heat_current_order))
162 f.write('{}'.format(path.rstrip('/'))) # without a trailing '/'
165def write_r0(fname, atoms):
166 """
167 Write GPUMD r0 file, with reference atomic positions.
169 Parameters
170 ----------
171 fname : str
172 name of file to which to write the atomic positions
173 atoms : ase.Atoms
174 input structure
176 """
177 line = '{} {} {}\n'
178 with open(fname, 'w') as f:
179 for a in atoms:
180 f.write(line.format(*a.position))