-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathh2Quanty.py
266 lines (229 loc) · 7.5 KB
/
h2Quanty.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
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/usr/bin/env python3
"""
h2Quanty
======================
This module contains functions which are useful for interfacing to Quanty.
"""
import numpy as np
import scipy.sparse
# Write Hamiltonian in Quanty format
# - In Quanty, the orbital ordering is differently than in RSPt.
# A reordering is nececcary.
#
# - The Hamiltonian processes are split up into several groups.
# This is done because the .lua file is not read properly by
# Quanty if the operator contains "too" many elements.
# It seems the column width is somehow limited in the .lua files
# (when read and used by Quanty).
#
# - Due to the eventual core states (e.g. 2p), one has to be careful
# about the indices and shift the indices.
def print_QuantyH_from_dense_rsptH(h_rspt, ang=2, previous_orbitals=6,
next_orbitals=0, filename='h0.lua',
op_name='H0'):
"""
Print Hamiltonian in a Quanty friendly format.
Parameters
----------
h_rspt : (N,N) array
Hamiltonian matrix ordered in RSPt format.
Contains impurity orbitals of one angular momentum and
associated bath orbitals.
ang : int
Angular momentum of impurity orbitals.
previous_orbitals : int
Number of spin-orbitals appearing before current orbitals in
the total Hamiltonian.
next_orbitals : int
Number of spin-orbitals appearing after current orbitals in
the total Hamiltonian.
filename : str
Output filename.
op_name : str
Variable name for saved operator.
"""
# Convert Hamiltonian to Quanty's orbital ordering format
h_quanty = rspt_2_quanty_matrix(h_rspt,ang)
norb = 2*ang + 1
nb = np.shape(h_rspt)[0]//(2*norb) - 1
# Number of spin-orbitals in the system studied in Quanty
nf = previous_orbitals + 2*norb*(1 + nb) + next_orbitals
# Index shifts
ishift, jshift = previous_orbitals, previous_orbitals
# Maximum number of elements in each operator
nmax = 85
# Transform matrix into several Quanty operators.
# Save to disk.
write_quanty_opps(h_quanty, nf, n=nmax, op_name=op_name, ishift=ishift,
jshift=jshift,filename=filename)
# Save also all elements into one operator
save21 = False
if save21:
# Transform matrix into one Quanty operator.
# Save to disk.
write_quanty_opp(h_quanty, nf, op_name='H_0', ishift=ishift,
jshift=jshift,filename='H0.lua')
def quanty_index(i,ang=2):
"""
Return spin-orbital index in common Quanty ordering notation.
In RSPt, spin-orbitals are ordered:
((orb1_dn, orb2_dn, ... | orb1_up, orb2_up, ...), (... | ...), )
In Quanty, a common notation is the spin-orbital ordering:
(orb1_dn, orb1_up, orb2_dn, orb2_up, ...)
Parameters
----------
i : int
index of orbital in RSPt ordering.
ang : int
Angular momentum of impurity orbitals.
"""
norb = 2*ang + 1
k = (i//(2*norb))*(2*norb)
if (i-k) < norb:
j = k + 2*(i-k)
else:
j = k + 2*((i-k)-norb) + 1
return j
def rspt_2_quanty_matrix(x,ang=2):
r"""
Maps matrix from represented in the RSPt notation to common Quanty notation.
In RSPt, spin-orbitals are ordered:
((orb1_dn, orb2_dn, ... | orb1_up, orb2_up, ...), (... | ...), )
In Quanty, a common notation is the spin-orbital ordering:
(orb1_dn, orb1_up, orb2_dn, orb2_up, ...)
Parameters
----------
x : (N,N) array
Matrix to transform.
ang : int
Angular momentum of impurity orbitals.
Returns
-------
xt : matrix
Matrix x, transformed into common Quanty notation.
"""
xt = np.zeros_like(x)
norb = 2*ang + 1
for i in range(np.shape(x)[0]):
for j in range(np.shape(x)[1]):
if x[i,j] != 0:
iq = quanty_index(i,ang)
jq = quanty_index(j,ang)
xt[iq, jq] = x[i,j]
return xt
def write_quanty_opp(x, nf, op_name='Opp', ishift=0, jshift=0,
filename='tmp.lua', mode='a'):
r"""
Write matrix to disk, as one Quanty operator.
Parameters
----------
x : (N,N) array
Matrix to write to disk.
nf : int
Number of spin-orbitals in the system studied by Quanty.
op_name : str
Name of the operator.
ishift : int
Shift of row index to apply operator to correct spin-orbitals
in the Quanty script.
jshift : int
Shift of column index to apply operator to correct spin-orbitals
in the Quanty script.
filename : str
File where the matrix is saved.
mode : {'a', 'w'}
To append or overwrite.
"""
if not (mode == 'a' or mode == 'w'):
print('Warning: writing mode not supported.')
return
# create the three lists needed in Quanty: i,j,e
i, j, e = scipy.sparse.find(x)
# take care that indices may be shifted
i += ishift
j += jshift
s = "\n"
s += op_name
s += " = NewOperator(\"Number\","
s += str(nf)
s += ",\n {"
s += ', '.join([str(el) for el in i])
s += '},\n {'
s += ', '.join([str(el) for el in j])
s += '},\n'
s_onerow = '{'
s_onerow += ', '.join([(str(el.real) + '+I*'
+ str(el.imag)) for el in e])
s_onerow += '})'
s += s_onerow
s += '\n'
if len(s_onerow) > 3000:
print('Warning: Lua does not support '
'lines longer than 3000')
f = open(filename, mode)
f.write(s)
f.close()
def write_quanty_opps(x, nf, n=1, op_name='Opp', ishift=0, jshift=0,
filename='tmp.lua', mode='a'):
"""
Write matrix x to disk, by dividing it into
several Quanty operators.
Parameters
----------
x : (N,N) array
Dense matrix to be written in sparse format for Quanty.
nf : int
Number of spin-orbitals in the system studied by Quanty.
n : int
Max number of elements in each operator.
op_name : str
Common name of the operators.
ishift : int
To apply operator to correct spin-orbitals.
jshift : int
To apply operator to correct spin-orbitals.
filename : str
File where the matrix is saved.
mode : {'a', 'w'}
To append or overwrite.
"""
if not (mode == 'a' or mode == 'w'):
print('Warning: writing mode not supported.')
return
# create the three lists needed in Quanty: i,j,e
i, j, e = scipy.sparse.find(x)
# take care that indices may be shifted
i += ishift
j += jshift
# divide up the elements in bunches of
# max n in each bunch
k = 0
d = []
while k + n < len(i):
d.append([i[k:k + n], j[k:k + n], e[k:k + n]])
k += n
d.append([i[k:], j[k:], e[k:]])
# write operators to file
f = open(filename, mode)
# loop over the operators
for k, (ii, jj, ee) in enumerate(d):
s = "\n"
s += op_name + '_' + str(k)
s += " = NewOperator(\"Number\","
s += str(nf)
s += ",\n {"
s += ', '.join([str(el) for el in ii])
s += '},\n {'
s += ', '.join([str(el) for el in jj])
s += '},\n'
s_onerow = '{'
s_onerow += ', '.join([(str(el.real) + '+I*'
+ str(el.imag)) for el in ee])
s_onerow += '})'
s += s_onerow
s += '\n'
if len(s_onerow) > 3000:
print('Warning: Lua does not support '
'lines longer than 3000')
f.write(s)
f.close()