Skip to content

Commit a4d9ae9

Browse files
committed
update benchmarks, add coments
1 parent f021d33 commit a4d9ae9

File tree

15 files changed

+144
-270
lines changed

15 files changed

+144
-270
lines changed

benchmark/dimer/dimer.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Two impurity sites coupled to two bath sites.
2+
# Data in dimer.ref.h5 is obtained by running this script on 800 cores.
3+
4+
from triqs.gf import *
5+
from triqs.gf.tools import *
6+
from triqs.gf.gf_factories import make_gf_from_fourier
7+
from triqs.operators.util import U_matrix_kanamori, h_int_density
8+
import h5
9+
import triqs.utility.mpi as mpi
10+
from triqs.utility.h5diff import h5diff
11+
from triqs.operators import n
12+
13+
from triqs_ctseg import Solver
14+
15+
import numpy as np
16+
from numpy import linalg
17+
18+
# Numerical values
19+
beta = 10. # Inverse temperature
20+
mu = 0.0 # Chemical potential
21+
eps = np.array([0.0, 0.1]) # Impurity site energies
22+
eps_bath = np.array([0.27, -0.4]) # Bath site energies
23+
U = 1. # Density-density interaction
24+
J = 0.2 # Hund's coupling
25+
V = 1 # Bath-impurity coupling
26+
block_names = ['up', 'dn']
27+
n_orb = len(eps)
28+
n_orb_bath = len(eps_bath)
29+
n_tau = 10001
30+
gf_struct = [(s, n_orb) for s in block_names] # Green's function structure
31+
32+
########################################################################
33+
# --------------- Construct Delta(tau) and h_loc0 ---------------
34+
35+
# Non-interacting impurity Hamiltonian in matrix representation
36+
h_0_mat = np.diag(eps - mu)
37+
38+
# Bath Hamiltonian in matrix representation
39+
h_bath_mat = np.diag(eps_bath)
40+
41+
# Coupling matrix
42+
V_mat = np.matrix([[V, V],
43+
[V, V]])
44+
45+
# Total non-interacting Hamiltonian
46+
h_tot_mat = np.block([[h_0_mat, V_mat],
47+
[V_mat.H, h_bath_mat]])
48+
49+
# Non-interacting impurity Green's function
50+
n_iw = int(10 * beta)
51+
iw_mesh = MeshImFreq(beta, 'Fermion', n_iw)
52+
G0_iw = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)
53+
for bl, iw in product(block_names, iw_mesh):
54+
G0_iw[bl][iw] = linalg.inv(iw.value * np.eye(2*n_orb) - h_tot_mat)[:n_orb, :n_orb]
55+
56+
# Get Delta(iw) and h_loc0 from G0(iw)
57+
def get_h0_Delta(G0_iw):
58+
h0_lst, Delta_iw = [], G0_iw.copy()
59+
for bl in G0_iw.indices:
60+
Delta_iw[bl] << iOmega_n - inverse(G0_iw[bl])
61+
tail, err = fit_hermitian_tail(Delta_iw[bl])
62+
Delta_iw[bl] << Delta_iw[bl] - tail[0]
63+
h0_lst.append(tail[0].real)
64+
return h0_lst, Delta_iw
65+
66+
h0_lst, Delta_iw = get_h0_Delta(G0_iw)
67+
h_loc0 = sum(h0_lst[i][0,0] * n(bl, 0) + h0_lst[i][1,1] * n(bl, 1) for i, bl in enumerate(block_names))
68+
69+
# Fourier-transform to get Delta(tau)
70+
tau_mesh = MeshImTime(beta, 'Fermion', n_tau)
71+
Delta_tau = BlockGf(mesh = tau_mesh, gf_struct = gf_struct)
72+
for name, g0 in Delta_iw:
73+
known_moments = make_zero_tail(Delta_iw[name], 1)
74+
tail, err = fit_hermitian_tail(Delta_iw[name], known_moments)
75+
Delta_tau[name] << make_gf_from_fourier(Delta_iw[name], tau_mesh, tail).real
76+
###########################################################
77+
78+
# --------- Construct the CTSEG solver ----------
79+
constr_params = {
80+
'beta': beta,
81+
'gf_struct': gf_struct,
82+
'n_tau': n_tau,
83+
}
84+
S = Solver(**constr_params)
85+
86+
# Input Delta(tau)
87+
S.Delta_tau << Delta_tau
88+
89+
# Impurity interaction Hamiltonian
90+
Umat, Upmat = U_matrix_kanamori(n_orb, U_int=U, J_hund=J)
91+
h_int = h_int_density(block_names, n_orb, Umat, Upmat, off_diag=True)
92+
93+
# --------- Solve parameters ----------
94+
solve_params = {
95+
'h_int': h_int,
96+
'h_loc0': h_loc0,
97+
'n_warmup_cycles': 5000,
98+
'n_cycles': 200000000,
99+
'length_cycle': 100,
100+
}
101+
102+
# ---------- Solve ----------
103+
S.solve(**solve_params)
104+
105+
# --------- Save output ---------
106+
if mpi.is_master_node():
107+
with h5.HDFArchive("dimer.out.h5", 'w') as A:
108+
A['G_tau'] = S.results.G_tau
109+

benchmark/move_double/ctint.ref.h5

-2.58 MB
Binary file not shown.

benchmark/move_double/multiorb.py

Lines changed: 0 additions & 81 deletions
This file was deleted.

benchmark/move_double/multiorb.ref.h5

-836 KB
Binary file not shown.

benchmark/move_double/plot.ipynb

Lines changed: 0 additions & 145 deletions
This file was deleted.
-220 KB
Binary file not shown.

benchmark/spin_spin/plot.ipynb

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"### Compare `spin_spin.py` result with `ctint`\n",
7+
"### Comparison between `CTSEG` and `CTINT` reference. \n",
88
"\n",
9-
"We use black line to denote the ctint result. "
9+
"Single-orbital impurity with retarded spin-spin interactions. "
1010
]
1111
},
1212
{
@@ -29,11 +29,7 @@
2929
"mpl.rcParams['figure.dpi'] = 150\n",
3030
"plt.rcParams['mathtext.fontset'] = 'cm'\n",
3131
"plt.rcParams['mathtext.rm'] = 'serif'\n",
32-
"plt.rc('font', size=12, family='Times New Roman')\n",
33-
"\n",
34-
"def normalize_color(color):\n",
35-
" brightness = color[0]**2 + color[1]**2 + color[2]**2\n",
36-
" return (color[0]/brightness, color[1]/brightness, color[2]/brightness, color[3])\n"
32+
"plt.rc('font', size=12, family='Times New Roman')"
3733
]
3834
},
3935
{
@@ -64,9 +60,9 @@
6460
"with HDFArchive(\"spin_spin.ref.h5\", \"r\") as A:\n",
6561
" G_tau_seg = A[\"G_tau\"]\n",
6662
"\n",
67-
"oplot(G_tau_int[\"up\"].real, 'k', linewidth = 2, label=\"ctint\")\n",
68-
"oplot(G_tau_seg[\"up\"].real, color=\"aqua\", linewidth = 0.6, label=\"ctseg\")\n",
69-
"plt.title(\"Spin Spin\")\n",
63+
"oplot(G_tau_int[\"up\"].real, 'k', linewidth = 2, label=\"CTINT\")\n",
64+
"oplot(G_tau_seg[\"up\"].real, color=\"aqua\", linewidth = 0.6, label=\"CTSEG\")\n",
65+
"plt.title(\"Impurity with spin-spin interactions\")\n",
7066
"plt.ylabel(r\"$G(\\tau)$\")\n",
7167
"plt.legend()\n",
7268
"plt.show()"

benchmark/move_double/spin_spin.py renamed to benchmark/spin_spin/spin_spin.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Single orbital with dynamical spin-spin interactions.
2-
# Can be compared with reference obtained with CTINT (ctint.ref.h5)
2+
# Data in spin_spin.ref.h5 is obtained by running this script on 800 cores.
33
from triqs.gf import *
44
import triqs.utility.mpi as mpi
55
from triqs.gf.descriptors import Function
@@ -57,20 +57,17 @@
5757
"n_cycles": 1000000,
5858
"measure_F_tau": True,
5959
"measure_nn_tau": True,
60-
"measure_nn_static": True,
61-
"move_double_insert_segment": True,
62-
"move_double_remove_segment": True,
60+
"measure_nn_static": True
6361
}
6462

6563
# Solve
6664
S.solve(**solve_params)
6765

68-
# Save and compare to reference
66+
# Save data
6967
if mpi.is_master_node():
7068
with h5.HDFArchive("spin_spin.out.h5", 'w') as A:
7169
A['G_tau'] = S.results.G_tau
7270
A['F_tau'] = S.results.F_tau
7371
A['nn_tau'] = S.results.nn_tau
7472
A['nn'] = S.results.nn_static
7573
A['densities'] = S.results.densities
76-

c++/triqs_ctseg/moves/double_insert_segment.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace triqs_ctseg::moves {
2525

2626
LOG("\n =================== ATTEMPT DOUBLE INSERT ================ \n");
2727

28-
// ------------ Choice of segment --------------
28+
// ------------ Choice of segments --------------
2929
// Select insertion colors
3030
int color_0 = rng(config.n_color());
3131
int color_1 = rng(config.n_color() - 1);
@@ -90,12 +90,12 @@ namespace triqs_ctseg::moves {
9090
ln_trace_ratio += -real(wdata.K(double(prop_seg[i].length()))(color, color)); // Correct double counting
9191
} // color
9292

93-
// Counting the overlap between the inserting segments
94-
// Make the prop_seg[1] as a seglist to use K_overlap()
95-
std::vector<segment_t> seglist_temp = {prop_seg[1]};
93+
// Overlap between the inserted segments
9694
ln_trace_ratio += -wdata.U(color_0, color_1) * overlap(prop_seg[1], prop_seg[0]);
97-
if (wdata.has_Dt)
95+
if (wdata.has_Dt) {
96+
std::vector<segment_t> seglist_temp = {prop_seg[1]};
9897
ln_trace_ratio += K_overlap(seglist_temp, prop_seg[0].tau_c, prop_seg[0].tau_cdag, wdata.K, color_0, color_1);
98+
}
9999

100100
double trace_ratio = std::exp(ln_trace_ratio);
101101

@@ -116,24 +116,24 @@ namespace triqs_ctseg::moves {
116116
return 0;
117117
}
118118
if (prop_seg[0].tau_cdag == prop_seg[1].tau_cdag or prop_seg[0].tau_c == prop_seg[1].tau_c) {
119-
LOG("Two inserting segments have same times. Rejecting.");
119+
LOG("Two identical times in inserted segments. Rejecting.");
120120
return 0;
121121
}
122122
}
123-
// Sort smaller and larger times for tau_cdag and tau_c
123+
// Find the ordering of the two tau_cdag and the two tau_c to be inserted. They must be inserted in the correct (inceasing) order.
124124
auto tau_cdag_lower = prop_seg[0].tau_cdag > prop_seg[1].tau_cdag ? prop_seg[1].tau_cdag : prop_seg[0].tau_cdag;
125125
auto tau_cdag_upper = prop_seg[0].tau_cdag < prop_seg[1].tau_cdag ? prop_seg[1].tau_cdag : prop_seg[0].tau_cdag;
126126
auto tau_c_lower = prop_seg[0].tau_c > prop_seg[1].tau_c ? prop_seg[1].tau_c : prop_seg[0].tau_c;
127127
auto tau_c_upper = prop_seg[0].tau_c < prop_seg[1].tau_c ? prop_seg[1].tau_c : prop_seg[0].tau_c;
128-
// Determine block indices corresponding to lower and upper tau values
129-
auto bl_cdag_lower = prop_seg[0].tau_cdag > prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
130-
auto bl_cdag_upper = prop_seg[0].tau_cdag < prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
131-
auto bl_c_lower = prop_seg[0].tau_c > prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
132-
auto bl_c_upper = prop_seg[0].tau_c < prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
128+
// Determine orbital indices (inside the block) corresponding to lower and upper tau values
129+
auto idx_cdag_lower = prop_seg[0].tau_cdag > prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
130+
auto idx_cdag_upper = prop_seg[0].tau_cdag < prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
131+
auto idx_c_lower = prop_seg[0].tau_c > prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
132+
auto idx_c_upper = prop_seg[0].tau_c < prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
133133
det_ratio = D.try_insert2(det_lower_bound_x(D, tau_cdag_lower), det_lower_bound_x(D, tau_cdag_upper) + 1, // +1 to avoid duplicates
134134
det_lower_bound_y(D, tau_c_lower) , det_lower_bound_y(D, tau_c_upper) + 1, // +1 to avoid duplicates
135-
{tau_cdag_lower, bl_cdag_lower} , {tau_cdag_upper, bl_cdag_upper} ,
136-
{tau_c_lower , bl_c_lower} , {tau_c_upper , bl_c_upper} );
135+
{tau_cdag_lower, idx_cdag_lower} , {tau_cdag_upper, idx_cdag_upper} ,
136+
{tau_c_lower , idx_c_lower} , {tau_c_upper , idx_c_upper} );
137137
}
138138
else { // insert on different blocks
139139
auto &D_0 = wdata.dets[bl_0];

c++/triqs_ctseg/moves/double_remove_segment.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace triqs_ctseg::moves {
2424

2525
LOG("\n =================== ATTEMPT DOUBLE REMOVE ================ \n");
2626

27-
// ------------ Choice of segment --------------
27+
// ------------ Choice of segments --------------
2828
// Select removal colors
2929
int color_0 = rng(config.n_color());
3030
int color_1 = rng(config.n_color() - 1);
@@ -59,7 +59,6 @@ namespace triqs_ctseg::moves {
5959

6060
// ------------ Trace ratio -------------
6161
// Same as double insert, up to the sign
62-
// FIXME : pull it out ?
6362
double ln_trace_ratio = 0.0;
6463
for (auto const &[i, color] : itertools::enumerate(colors)) {
6564
ln_trace_ratio += -wdata.mu(color) * prop_seg[i].length();
@@ -71,18 +70,16 @@ namespace triqs_ctseg::moves {
7170
if (wdata.has_Dt) ln_trace_ratio -= real(wdata.K(double(prop_seg[i].length()))(color, color));
7271
} // color
7372

74-
// Counting the overlap between the removal segments
75-
// Make the prop_seg[1] as a seglist to use K_overlap()
76-
// Be careful to the sign here!
77-
std::vector<segment_t> seglist_temp = {prop_seg[1]};
73+
// Overlap between the removed segments
7874
ln_trace_ratio += -wdata.U(color_0, color_1) * overlap(prop_seg[1], prop_seg[0]);
79-
if (wdata.has_Dt)
75+
if (wdata.has_Dt) {
76+
std::vector<segment_t> seglist_temp = {prop_seg[1]}; // trick for using K_overlap on a single segment
8077
ln_trace_ratio += K_overlap(seglist_temp, prop_seg[0].tau_c, prop_seg[0].tau_cdag, wdata.K, color_0, color_1);
78+
}
8179

8280
double trace_ratio = std::exp(ln_trace_ratio);
8381

8482
// ------------ Det ratio ---------------
85-
// same code as in double insert. In Insert, it is a true bound, does not insert at same time
8683
auto &bl_0 = wdata.block_number[color_0];
8784
auto &bl_1 = wdata.block_number[color_1];
8885
is_same_block = bl_0 == bl_1;

0 commit comments

Comments
 (0)