ctint_solver::ctint_solver(double beta_, int n_iw, int n_tau) : beta(beta_) { g0_iw = make_block_gf({"up", "down"}, gf<imfreq>{{beta, Fermion, n_iw}, {1, 1}}); g0tilde_tau = make_block_gf({"up", "down"}, gf<imtime>{{beta, Fermion, n_tau}, {1, 1}}); g0tilde_iw = g0_iw; g_iw = g0_iw; M_iw = g0_iw; }
block_gf<imtime> atomic_gf(atom_diag const& atom, double beta, std::map<std::string, indices_t> const& gf_struct, int n_tau, std::vector<std::pair<int, int>> const& excluded_states) { double z = partition_function(atom, beta); std::vector<std::string> block_names; std::vector<gf<imtime>> gf_blocks; auto const & fops = atom.get_fops(); auto is_excluded = [&excluded_states](int A, int ia) { return std::find(excluded_states.begin(), excluded_states.end(), std::make_pair(A, ia)) != excluded_states.end(); }; for (auto const& block : gf_struct) { block_names.push_back(block.first); int bl_size = block.second.size(); auto g = gf<imtime>{{beta, Fermion, n_tau}, {bl_size, bl_size}}; for (int inner_index1 = 0; inner_index1 < bl_size; ++inner_index1) for (int inner_index2 = 0; inner_index2 < bl_size; ++inner_index2) { int n1 = fops[{block.first, block.second[inner_index1]}]; // linear_index of c int n2 = fops[{block.first, block.second[inner_index2]}]; // linear_index of c_dag for (int A = 0; A < atom.n_blocks(); ++A) { // index of the A block. sum over all int B = atom.cdag_connection(n2, A); // index of the block connected to A by operator c_n if (B == -1) continue; // no matrix element if (atom.c_connection(n1, B) != A) continue; // for (int ia = 0; ia < atom.get_block_dim(A); ++ia) for (int ib = 0; ib < atom.get_block_dim(B); ++ib) { auto Ea = atom.get_eigenvalue(A, ia); auto Eb = atom.get_eigenvalue(B, ib); if (is_excluded(A, ia) || is_excluded(B, ib)) continue; for (auto tau : g.mesh()) g[tau](inner_index1, inner_index2) += -atom.cdag_matrix(n2, A)(ib, ia) * atom.c_matrix(n1, B)(ia, ib) * std::exp(-(Eb - Ea) * tau - beta * Ea) / z; } } } g.singularity()(1) = 1.0; gf_blocks.push_back(std::move(g)); } return make_block_gf(block_names, gf_blocks); }
template <typename F, typename G> gf<block_index, std14::result_of_t<F(G)>> map(F &&f, gf_const_view<block_index, G> g) { return make_block_gf(get_block_names(g), _map(f, g.data())); }