23#include <boost/algorithm/string.hpp>
24#include <boost/format.hpp>
47 Index ignored_corelevels = 0;
50 basis.
Load(
"corelevels");
51 Index coreElectrons = 0;
52 for (
const auto& atom :
orbitals_.QMAtoms()) {
55 ignored_corelevels = coreElectrons / 2;
57 return ignored_corelevels;
70 const bool is_uks =
orbitals_.hasUnrestrictedOrbitals();
78 num_of_occlevels = std::max(
orbitals_.getNumberOfAlphaElectrons(),
82 std::string ranges = options.
get(
".ranges").
as<std::string>();
86 if (ranges ==
"factor") {
88 double rpamaxfactor = options.
get(
".rpamax").
as<
double>();
89 rpamax =
Index(rpamaxfactor *
double(num_of_levels)) -
92 double qpminfactor = options.
get(
".qpmin").
as<
double>();
94 num_of_occlevels -
Index(qpminfactor *
double(num_of_occlevels)) - 1;
96 double qpmaxfactor = options.
get(
".qpmax").
as<
double>();
98 num_of_occlevels +
Index(qpmaxfactor *
double(num_of_occlevels)) - 1;
100 double bseminfactor = options.
get(
".bsemin").
as<
double>();
102 num_of_occlevels -
Index(bseminfactor *
double(num_of_occlevels)) - 1;
104 double bsemaxfactor = options.
get(
".bsemax").
as<
double>();
106 num_of_occlevels +
Index(bsemaxfactor *
double(num_of_occlevels)) - 1;
108 }
else if (ranges ==
"explicit") {
113 bse_vmin = options.
get(
".bsemin").
as<
Index>();
114 bse_cmax = options.
get(
".bsemax").
as<
Index>();
115 }
else if (ranges ==
"default") {
116 rpamax = num_of_levels - 1;
118 qpmax = 3 * homo + 1;
120 bse_cmax = 3 * homo + 1;
121 }
else if (ranges ==
"full") {
122 rpamax = num_of_levels - 1;
124 qpmax = num_of_levels - 1;
126 bse_cmax = num_of_levels - 1;
128 std::string ignore_corelevels =
129 options.
get(
".ignore_corelevels").
as<std::string>();
131 if (ignore_corelevels ==
"RPA" || ignore_corelevels ==
"GW" ||
132 ignore_corelevels ==
"BSE") {
134 if (ignore_corelevels ==
"RPA") {
135 rpamin = ignored_corelevels;
137 if (ignore_corelevels ==
"GW" || ignore_corelevels ==
"RPA") {
138 if (qpmin < ignored_corelevels) {
139 qpmin = ignored_corelevels;
142 if (ignore_corelevels ==
"GW" || ignore_corelevels ==
"RPA" ||
143 ignore_corelevels ==
"BSE") {
144 if (bse_vmin < ignored_corelevels) {
145 bse_vmin = ignored_corelevels;
150 <<
TimeStamp() <<
" Ignoring " << ignored_corelevels
151 <<
" core levels for " << ignore_corelevels <<
" and beyond." << flush;
155 if (rpamax >= num_of_levels) {
156 rpamax = num_of_levels - 1;
158 if (qpmax >= num_of_levels) {
159 qpmax = num_of_levels - 1;
161 if (bse_cmax >= num_of_levels) {
162 bse_cmax = num_of_levels - 1;
171 Index bse_vmax = homo;
172 Index bse_cmin = homo + 1;
174 if (rpamin < 0 || rpamax < 0 || rpamin > rpamax) {
175 throw std::runtime_error(
"Invalid RPA level range after setup/clamping.");
177 if (qpmin < 0 || qpmax < 0 || qpmin > qpmax) {
178 throw std::runtime_error(
"Invalid GW level range after setup/clamping.");
180 if (bse_vmin < 0 || bse_vmax < 0 || bse_vmin > bse_vmax) {
181 throw std::runtime_error(
182 "Invalid BSE occupied level range after setup/clamping.");
184 if (bse_cmin < 0 || bse_cmax < 0 || bse_cmin > bse_cmax) {
185 throw std::runtime_error(
186 "Invalid BSE virtual level range after setup/clamping.");
188 if (bse_vmax >= num_of_levels || bse_cmax >= num_of_levels) {
189 throw std::runtime_error(
190 "BSE level range exceeds available orbital indices.");
192 if (bse_vmax >= bse_cmin) {
193 throw std::runtime_error(
"BSE occupied and virtual level ranges overlap.");
212 orbitals_.setBSEindices(bse_vmin, bse_cmax);
216 Index bse_vtotal = bse_vmax - bse_vmin + 1;
217 Index bse_ctotal = bse_cmax - bse_cmin + 1;
218 Index bse_size = bse_vtotal * bse_ctotal;
221 <<
":" << rpamax <<
"]" << flush;
223 <<
":" << qpmax <<
"]" << flush;
225 <<
TimeStamp() <<
" BSE level range occ[" << bse_vmin <<
":" << bse_vmax
226 <<
"] virt[" << bse_cmin <<
":" << bse_cmax <<
"]" << flush;
236 options.
get(
"bse.davidson.correction").
as<std::string>();
239 options.
get(
"bse.davidson.tolerance").
as<std::string>();
242 options.
get(
"bse.davidson.update").
as<std::string>();
254 Index full_bse_size = (
bseopt_.useTDA) ? bse_size : 2 * bse_size;
256 << full_bse_size <<
"x" << full_bse_size << flush;
258 bseopt_.use_Hqp_offdiag = options.
get(
"bse.use_Hqp_offdiag").
as<
bool>();
261 if (!
bseopt_.use_Hqp_offdiag) {
263 <<
" BSE without Hqp offdiagonal elements" << flush;
266 <<
" BSE with Hqp offdiagonal elements" << flush;
270 bseopt_.dyn_tolerance = options.
get(
"bse.dyn_screen_tol").
as<
double>();
271 if (
bseopt_.max_dyn_iter > 0) {
281 }
else if (options.
exists(
".auxbasisset")) {
288 }
catch (std::runtime_error&) {
290 "There is no auxbasis from the dftcalculation nor did you specify an "
291 "auxbasisset for the gwbse calculation. Also no auxiliary basisset "
296 <<
" Could not find an auxbasisset using " <<
auxbasis_name_ << flush;
299 std::string mode = options.
get(
"gw.mode").
as<std::string>();
300 if (mode ==
"G0W0") {
301 gwopt_.gw_sc_max_iterations = 1;
302 }
else if (mode ==
"evGW") {
310 gwopt_.shift = options.
get(
"gw.scissor_shift").
as<
double>();
312 options.
get(
"gw.qp_sc_limit").
as<
double>();
315 gwopt_.g_sc_max_iterations =
321 if (mode ==
"evGW") {
326 options.
get(
"gw.sc_limit").
as<
double>();
329 <<
" qp_sc_limit [Hartree]: " <<
gwopt_.g_sc_limit << flush;
330 if (
gwopt_.gw_sc_max_iterations > 1) {
332 <<
" gw_sc_limit [Hartree]: " <<
gwopt_.gw_sc_limit << flush;
334 bseopt_.min_print_weight = options.
get(
"bse.print_weight").
as<
double>();
338 std::string tasks_string = options.
get(
".tasks").
as<std::string>();
339 boost::algorithm::to_lower(tasks_string);
341 if (tasks_string.find(
"gw") != std::string::npos) {
346 if (tasks_string.find(
"excitons") != std::string::npos ||
347 tasks_string.find(
"exciton_uks") != std::string::npos) {
352 if (tasks_string.find(
"singlets") != std::string::npos ||
353 tasks_string.find(
"triplets") != std::string::npos) {
354 throw std::runtime_error(
355 "Invalid gwbse task for UKS reference: 'singlets' and 'triplets' "
356 "are not defined for open-shell systems.\n"
357 "Use 'exciton_uks' (or 'excitons') instead.");
360 if (tasks_string.find(
"all") != std::string::npos) {
370 if (tasks_string.find(
"singlets") != std::string::npos) {
373 if (tasks_string.find(
"triplets") != std::string::npos) {
392 if (options.
exists(
"bse.fragments")) {
393 std::vector<tools::Property*> prop_region =
394 options.
Select(
"bse.fragments.fragment");
397 std::string indices = prop->get(
"indices").as<std::string>();
403 gwopt_.sigma_integration =
404 options.
get(
"gw.sigma_integrator").
as<std::string>();
406 <<
" Sigma integration: " <<
gwopt_.sigma_integration << flush;
409 if (
gwopt_.sigma_integration ==
"exact") {
411 <<
" RPA Hamiltonian size: " << (homo + 1 - rpamin) * (rpamax - homo)
414 if (
gwopt_.sigma_integration ==
"cda") {
417 <<
" Quadrature integration order : " <<
gwopt_.order << flush;
418 gwopt_.quadrature_scheme =
419 options.
get(
"gw.quadrature_scheme").
as<std::string>();
421 <<
" Quadrature integration scheme : " <<
gwopt_.quadrature_scheme
423 gwopt_.alpha = options.
get(
"gw.alpha").
as<
double>();
425 <<
" Alpha smoothing parameter : " <<
gwopt_.alpha << flush;
427 gwopt_.qp_solver = options.
get(
"gw.qp_solver").
as<std::string>();
430 if (
gwopt_.qp_solver ==
"grid") {
439 if (options.
exists(
"gw.qp_full_window_half_width")) {
440 gwopt_.qp_full_window_half_width =
441 options.
get(
"gw.qp_full_window_half_width").
as<
double>();
443 if (options.
exists(
"gw.qp_dense_spacing")) {
444 gwopt_.qp_dense_spacing = options.
get(
"gw.qp_dense_spacing").
as<
double>();
446 if (options.
exists(
"gw.qp_adaptive_shell_width")) {
447 gwopt_.qp_adaptive_shell_width =
448 options.
get(
"gw.qp_adaptive_shell_width").
as<
double>();
450 if (options.
exists(
"gw.qp_adaptive_shell_count")) {
451 gwopt_.qp_adaptive_shell_count =
452 options.
get(
"gw.qp_adaptive_shell_count").
as<
Index>();
457 const bool has_legacy_steps = options.
exists(
"gw.qp_grid_steps");
458 const bool has_legacy_spacing = options.
exists(
"gw.qp_grid_spacing");
460 if (has_legacy_steps != has_legacy_spacing) {
461 throw std::runtime_error(
462 "Deprecated gw.qp_grid_steps and gw.qp_grid_spacing must be given "
463 "together if either is used.");
466 if (has_legacy_steps && has_legacy_spacing) {
468 gwopt_.qp_grid_spacing = options.
get(
"gw.qp_grid_spacing").
as<
double>();
470 const double legacy_half_width =
472 const double legacy_shell_width =
475 if (
gwopt_.qp_full_window_half_width <= 0.0) {
476 gwopt_.qp_full_window_half_width = legacy_half_width;
478 if (
gwopt_.qp_dense_spacing <= 0.0) {
481 if (
gwopt_.qp_adaptive_shell_count <= 0 &&
482 gwopt_.qp_adaptive_shell_width <= 0.0) {
483 gwopt_.qp_adaptive_shell_width = legacy_shell_width;
487 <<
" Deprecated GW QP options detected: "
488 <<
"qp_grid_steps=" <<
gwopt_.qp_grid_steps
489 <<
" qp_grid_spacing=" <<
gwopt_.qp_grid_spacing
490 <<
" -> mapped to qp_full_window_half_width="
491 <<
gwopt_.qp_full_window_half_width
492 <<
" qp_dense_spacing=" <<
gwopt_.qp_dense_spacing
493 <<
" qp_adaptive_shell_width=" <<
gwopt_.qp_adaptive_shell_width
502 <<
" QP full window half-width: " <<
gwopt_.qp_full_window_half_width
505 <<
" QP dense spacing: " <<
gwopt_.qp_dense_spacing << flush;
507 <<
" QP adaptive shell width: " <<
gwopt_.qp_adaptive_shell_width
510 <<
" QP adaptive shell count: " <<
gwopt_.qp_adaptive_shell_count
513 gwopt_.qp_root_finder = options.
get(
"gw.qp_root_finder").
as<std::string>();
515 <<
" QP root finder: " <<
gwopt_.qp_root_finder << flush;
523 gwopt_.gw_mixing_alpha = options.
get(
"gw.mixing_alpha").
as<
double>();
524 gwopt_.qp_grid_search_mode =
525 options.
get(
"gw.qp_grid_search_mode").
as<std::string>();
526 gwopt_.qp_restrict_search = options.
get(
"gw.qp_restrict_search").
as<
bool>();
527 gwopt_.qp_zero_margin = options.
get(
"gw.qp_zero_margin").
as<
double>();
528 gwopt_.qp_virtual_min_energy =
529 options.
get(
"gw.qp_virtual_min_energy").
as<
double>();
535 "gw.qsgw_max_iterations", 20);
538 gwopt_.qsgw_max_virt_correction =
540 "gw.qsgw_max_virt_correction", 0.5);
543 <<
" QSGW enabled: max_iter=" <<
gwopt_.qsgw_max_iterations
544 <<
" sc_limit=" <<
gwopt_.qsgw_sc_limit <<
" Ha"
545 <<
" max_virt_correction=" <<
gwopt_.qsgw_max_virt_correction <<
" Ha ("
546 <<
gwopt_.qsgw_max_virt_correction * 27.2114 <<
" eV)" << std::flush;
549 if (mode ==
"evGW") {
550 if (
gwopt_.gw_mixing_order == 0) {
552 }
else if (
gwopt_.gw_mixing_order == 1) {
554 <<
gwopt_.gw_mixing_alpha << std::flush;
557 <<
gwopt_.gw_mixing_order <<
" using alpha "
558 <<
gwopt_.gw_mixing_alpha << std::flush;
562 if (options.
exists(
"gw.sigma_plot")) {
567 options.
get(
"gw.sigma_plot.filename").
as<std::string>();
588 (boost::format(
"%1$+1.6f ") % (
orbitals_.getDFTTotalEnergy() * hrt2ev))
591 if (
orbitals_.hasUnrestrictedOrbitals()) {
592 gwbse_summary.
add(
"dft_alpha",
"");
593 gwbse_summary.
add(
"dft_beta",
"");
607 (boost::format(
"%1$+1.6f ") %
610 level_alpha.
add(
"gw_energy",
611 (boost::format(
"%1$+1.6f ") %
612 (
orbitals_.QPpertEnergiesAlpha()(state) * hrt2ev))
616 (boost::format(
"%1$+1.6f ") %
617 (
orbitals_.QPdiagAlpha().eigenvalues()(state) * hrt2ev))
624 (boost::format(
"%1$+1.6f ") %
628 level_beta.
add(
"gw_energy",
629 (boost::format(
"%1$+1.6f ") %
630 (
orbitals_.QPpertEnergiesBeta()(state) * hrt2ev))
632 level_beta.
add(
"qp_energy",
633 (boost::format(
"%1$+1.6f ") %
634 (
orbitals_.QPdiagBeta().eigenvalues()(state) * hrt2ev))
647 (boost::format(
"%1$+1.6f ") %
650 level_summary.
add(
"gw_energy",
651 (boost::format(
"%1$+1.6f ") %
652 (
orbitals_.QPpertEnergies()(state) * hrt2ev))
654 level_summary.
add(
"qp_energy",
655 (boost::format(
"%1$+1.6f ") %
656 (
orbitals_.QPdiag().eigenvalues()(state) * hrt2ev))
667 "omega", (boost::format(
"%1$+1.6f ") %
668 (
orbitals_.BSESinglets().eigenvalues()(state) * hrt2ev))
672 const Eigen::Vector3d& dipoles = (
orbitals_.TransitionDipoles())[state];
673 double f = 2 * dipoles.squaredNorm() *
674 orbitals_.BSESinglets().eigenvalues()(state) / 3.0;
676 level_summary.
add(
"f", (boost::format(
"%1$+1.6f ") % f).str());
678 "Trdipole", (boost::format(
"%1$+1.4f %2$+1.4f %3$+1.4f") %
679 dipoles.x() % dipoles.y() % dipoles.z())
692 "omega", (boost::format(
"%1$+1.6f ") %
693 (
orbitals_.BSETriplets().eigenvalues()(state) * hrt2ev))
700 const bool has_dipoles =
orbitals_.hasTransitionDipoles();
701 Eigen::VectorXd oscs = Eigen::VectorXd::Zero(0);
707 for (
Index state = 0;
713 level_summary.
add(
"omega",
714 (boost::format(
"%1$+1.6f ") %
715 (
orbitals_.BSEUKS().eigenvalues()(state) * hrt2ev))
719 const Index nosc =
static_cast<Index>(oscs.size());
721 if (has_dipoles && state < ndip && state < nosc) {
722 const Eigen::Vector3d& dipoles =
orbitals_.TransitionDipoles()[state];
724 level_summary.
add(
"f",
725 (boost::format(
"%1$+1.6f ") % oscs(state)).str());
728 "Trdipole", (boost::format(
"%1$+1.4f %2$+1.4f %3$+1.4f") %
729 dipoles.x() % dipoles.y() % dipoles.z())
751 if (
orbitals_.getXCFunctionalName().empty()) {
755 throw std::runtime_error(
"Functionals from DFT " +
756 orbitals_.getXCFunctionalName() +
" GWBSE " +
764 <<
TimeStamp() <<
" Setup grid for integration with gridsize: " <<
grid_
765 <<
" with " << grid.
getGridSize() <<
" points, divided into "
772 Eigen::MatrixXd DMAT =
orbitals_.DensityMatrixGroundState();
779 Eigen::MatrixXd mos =
782 Eigen::MatrixXd vxc = mos.transpose() * e_vxc_ao.
matrix() * mos;
784 <<
TimeStamp() <<
" Calculated exchange-correlation expectation values "
792 if (
orbitals_.getXCFunctionalName().empty()) {
795 throw std::runtime_error(
"Functionals from DFT " +
796 orbitals_.getXCFunctionalName() +
" GWBSE " +
805 auto dmats =
orbitals_.DensityMatrixGroundStateSpinResolved();
809 Eigen::MatrixXd mos_alpha =
811 Eigen::MatrixXd mos_beta =
814 Eigen::MatrixXd vxc_alpha =
815 mos_alpha.transpose() * e_vxc_ao.vxc_alpha * mos_alpha;
816 Eigen::MatrixXd vxc_beta =
817 mos_beta.transpose() * e_vxc_ao.vxc_beta * mos_beta;
819 return std::make_pair(vxc_alpha, vxc_beta);
830 <<
TimeStamp() <<
" Using MKL overload for Eigen " << flush;
834 <<
" Using native Eigen implementation, no BLAS overload " << flush;
839 <<
TimeStamp() <<
" Using CUDA support for tensor multiplication with "
840 << nogpus <<
" GPUs." << flush;
844 <<
TimeStamp() <<
" Molecule Coordinates [A] " << flush;
846 std::string output = (boost::format(
"%5d"
848 " %1.4f %1.4f %1.4f") %
849 atom.getId() % atom.getElement() %
858 std::string dft_package =
orbitals_.getQMpackage();
860 <<
TimeStamp() <<
" DFT data was created by " << dft_package << flush;
883 <<
" size:" << frag.size() << flush;
891 throw std::runtime_error(
892 "You want no GW calculation but the orb file has no matching QP "
896 const bool is_uks =
orbitals_.hasUnrestrictedOrbitals();
907 <<
TimeStamp() <<
" Calculating alpha spin Mmn " << flush;
910 <<
TimeStamp() <<
" Calculating beta spin Mmn " << flush;
916 <<
TimeStamp() <<
" Calculating Mmn (3-center-repulsion x orbitals) "
918 Mmn.
Fill(auxbasis, dftbasis,
orbitals_.MOs().eigenvectors());
921 <<
" functions from Aux Coulomb matrix to avoid near linear "
925 <<
TimeStamp() <<
" Calculated Mmn (3-center-repulsion x orbitals) "
930 Eigen::MatrixXd Hqp_alpha;
931 Eigen::MatrixXd Hqp_beta;
934 std::chrono::time_point<std::chrono::system_clock> start =
935 std::chrono::system_clock::now();
989 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es_alpha =
991 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es_beta =
993 orbitals_.QPdiagAlpha().eigenvectors() = es_alpha.eigenvectors();
994 orbitals_.QPdiagAlpha().eigenvalues() = es_alpha.eigenvalues();
995 orbitals_.QPdiagBeta().eigenvectors() = es_beta.eigenvectors();
996 orbitals_.QPdiagBeta().eigenvalues() = es_beta.eigenvalues();
997 std::chrono::duration<double> elapsed_time =
998 std::chrono::system_clock::now() - start;
1000 <<
TimeStamp() <<
" UKS GW calculation took " << elapsed_time.count()
1001 <<
" seconds." << flush;
1018 <<
TimeStamp() <<
" Calculating offdiagonal part of Sigma " << flush;
1025 const std::string seed_label =
1026 (
gwopt_.gw_sc_max_iterations == 1) ?
"G0W0" :
"evGW";
1047 Eigen::MatrixXd C_qp =
orbitals_.MOs().eigenvectors();
1048 C_qp.middleCols(
gwopt_.qpmin, qptotal) =
1052 <<
TimeStamp() <<
" Rebuilding Mmn in QSGW QP wavefunction basis"
1054 Mmn.
Fill(auxbasis, dftbasis, C_qp);
1057 <<
" Rebuilt Mmn (3-center-repulsion x QP orbitals)" << flush;
1063 Hqp = qsgw_energies.asDiagonal();
1072 orbitals_.QPdiag().eigenvalues() = qsgw_energies;
1080 <<
TimeStamp() <<
" Calculated offdiagonal part of Sigma "
1085 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es =
1087 if (es.info() == Eigen::ComputationInfo::Success) {
1089 <<
TimeStamp() <<
" Diagonalized QP Hamiltonian " << flush;
1092 orbitals_.QPdiag().eigenvectors() = es.eigenvectors();
1093 orbitals_.QPdiag().eigenvalues() = es.eigenvalues();
1095 std::chrono::duration<double> elapsed_time =
1096 std::chrono::system_clock::now() - start;
1098 <<
TimeStamp() <<
" GW calculation took " << elapsed_time.count()
1099 <<
" seconds." << flush;
1107 throw std::runtime_error(
1108 "The ranges for GW and RPA do not agree with the ranges from the "
1109 ".orb file, rerun your GW calculation");
1113 const Eigen::MatrixXd& qpcoeff_alpha =
1115 const Eigen::MatrixXd& qpcoeff_beta =
1118 Hqp_alpha = qpcoeff_alpha *
1119 orbitals_.QPdiagAlpha().eigenvalues().asDiagonal() *
1120 qpcoeff_alpha.transpose();
1121 Hqp_beta = qpcoeff_beta *
1122 orbitals_.QPdiagBeta().eigenvalues().asDiagonal() *
1123 qpcoeff_beta.transpose();
1127 const Eigen::MatrixXd& U =
orbitals_.QPdiag().eigenvectors();
1129 Eigen::MatrixXd C_qp =
orbitals_.MOs().eigenvectors();
1130 C_qp.middleCols(
gwopt_.qpmin, qptotal) =
1134 <<
" Rebuilding Mmn in QSGW QP wavefunction basis (BSE-only)"
1136 Mmn.
Fill(auxbasis, dftbasis, C_qp);
1138 <<
TimeStamp() <<
" Rebuilt Mmn (3-center-repulsion x QP orbitals)"
1140 Hqp =
orbitals_.QPdiag().eigenvalues().asDiagonal();
1142 const Eigen::MatrixXd& qpcoeff =
orbitals_.QPdiag().eigenvectors();
1144 Hqp = qpcoeff *
orbitals_.QPdiag().eigenvalues().asDiagonal() *
1145 qpcoeff.transpose();
1152 std::chrono::time_point<std::chrono::system_clock> start =
1153 std::chrono::system_clock::now();
1165 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es_bse(
1168 Eigen::VectorXd epsilon_0_inv_bse =
1169 Eigen::VectorXd::Zero(es_bse.eigenvalues().size());
1170 for (
Index i = 0; i < es_bse.eigenvalues().size(); ++i) {
1171 if (es_bse.eigenvalues()(i) > 1
e-8) {
1172 epsilon_0_inv_bse(i) = 1.0 / es_bse.eigenvalues()(i);
1199 Hqp_alpha, Hqp_beta, epsilon_0_inv_bse, es_bse.eigenvectors());
1203 <<
TimeStamp() <<
" Solved combined UKS BSE exciton problem "
1218 <<
TimeStamp() <<
" Solved BSE for triplets " << flush;
1225 <<
TimeStamp() <<
" Solved BSE for singlets " << flush;
1242 std::chrono::duration<double> elapsed_time =
1243 std::chrono::system_clock::now() - start;
1245 << elapsed_time.count() <<
" seconds." << flush;
1248 <<
TimeStamp() <<
" GWBSE calculation finished " << flush;
Container to hold Basisfunctions for all atoms.
Index AOBasisSize() const
void configure_with_precomputed_screening(const options &opt, Index homo_alpha, Index homo_beta, const Eigen::VectorXd &RPAInputEnergiesAlpha, const Eigen::VectorXd &RPAInputEnergiesBeta, const Eigen::MatrixXd &Hqp_alpha_in, const Eigen::MatrixXd &Hqp_beta_in, const Eigen::VectorXd &epsilon_0_inv, const Eigen::MatrixXd &epsilon_eigenvectors)
void Perturbative_DynamicalScreening(Orbitals &orb)
void Solve_excitons_uks(Orbitals &orb) const
void Analyze_excitons_uks(std::vector< QMFragment< BSE_Population > > fragments, const Orbitals &orb) const
void Solve_singlets(Orbitals &orb) const
void Analyze_singlets(std::vector< QMFragment< BSE_Population > > fragments, const Orbitals &orb) const
void Perturbative_DynamicalScreening(const QMStateType &type, Orbitals &orb)
void Analyze_triplets(std::vector< QMFragment< BSE_Population > > fragments, const Orbitals &orb) const
void configure(const options &opt, const Eigen::VectorXd &RPAEnergies, const Eigen::MatrixXd &Hqp_in)
void Solve_triplets(Orbitals &orb) const
void Load(const std::string &name)
void Load(const std::string &name)
const ECPElement & getElement(std::string element_type) const
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > CalculateVXCSpinResolved(const AOBasis &dftbasis)
std::vector< QMFragment< BSE_Population > > fragments_
std::string sigma_plot_states_
void addoutput(tools::Property &summary)
std::string auxbasis_name_
Eigen::MatrixXd CalculateVXC(const AOBasis &dftbasis)
std::string dftbasis_name_
void Initialize(tools::Property &options)
double sigma_plot_spacing_
std::string sigma_plot_filename_
bool do_dynamical_screening_bse_
Eigen::SelfAdjointEigenSolver< Eigen::MatrixXd > DiagonalizeQPHamiltonianAlpha() const
Eigen::VectorXd getGWAResultsAlpha() const
const Eigen::VectorXd & RPAInputEnergiesAlpha() const
const Eigen::VectorXd & RPAInputEnergiesBeta() const
Eigen::MatrixXd getHQPBeta() const
Eigen::VectorXd getGWAResultsBeta() const
Eigen::MatrixXd getHQPAlpha() const
Eigen::SelfAdjointEigenSolver< Eigen::MatrixXd > DiagonalizeQPHamiltonianBeta() const
void configure(const options &opt)
void CalculateGWPerturbation()
void PlotSigma(std::string filename, Index steps, double spacing, std::string states) const
const Eigen::VectorXd & getQSGWSeedEnergies() const
Return the seed (G0W0/evGW) energies that QSGW started from.
Eigen::SelfAdjointEigenSolver< Eigen::MatrixXd > DiagonalizeQPHamiltonian() const
void PrintQSGW_Energies(const std::string &seed_label, const Eigen::VectorXd &seed_energies, const Eigen::VectorXd &qsgw_energies) const
Print a two-column comparison of seed (G0W0 or evGW) vs converged QSGW quasiparticle energies.
void CalculateQSGW()
Run quasiparticle self-consistent GW (QSGW).
void configure(const options &opt)
Eigen::MatrixXd getHQP() const
void PrintQSGW_Composition(double threshold=0.01) const
Print the dominant DFT-KS orbital contributions to each converged QSGW quasiparticle state.
Eigen::VectorXd getGWAResults() const
Eigen::VectorXd RPAInputEnergies() const
const Eigen::MatrixXd & getQSGWRotation() const
void CalculateGWPerturbation()
Eigen::MatrixXd & matrix()
Unrestricted RPA helper for spin-resolved GW screening.
void setRPAInputEnergies(const Eigen::VectorXd &rpaenergies_alpha, const Eigen::VectorXd &rpaenergies_beta)
Set alpha and beta RPA input energies directly.
void configure(Index homo_alpha, Index homo_beta, Index rpamin, Index rpamax)
Configure orbital window and spin-resolved HOMO indices.
Eigen::MatrixXd calculate_epsilon_r(double frequency) const
Dielectric matrix on the real frequency axis.
void Fill(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &dft_orbitals)
void Initialize(Index basissize, Index mmin, Index mmax, Index nmin, Index nmax)
Index Removedfunctions() const
Timestamp returns the current time as a string Example: cout << TimeStamp().
Index getGridSize() const
void GridSetup(const std::string &type, const QMMolecule &atoms, const AOBasis &basis)
Index getBoxesSize() const
Mat_p_Energy IntegrateVXC(const Eigen::MatrixXd &density_matrix) const
void setXCfunctional(const std::string &functional)
SpinResult IntegrateVXCSpin(const Eigen::MatrixXd &dmat_alpha, const Eigen::MatrixXd &dmat_beta) const
#define XTP_LOG(level, log)
double LegacyAdaptiveShellWidth(const Opt &opt)
void NormalizeGridSearchOptions(Opt &opt)
double LegacyFullWindowHalfWidth(const Opt &opt)
Charge transport classes.
bool XTP_HAS_MKL_OVERLOAD()
Provides a means for comparing floating point numbers.
std::string davidson_update
std::string davidson_tolerance
std::string davidson_correction
Index qp_adaptive_shell_count
double qp_virtual_min_energy
std::string quadrature_scheme
double qp_full_window_half_width
std::string qp_grid_search_mode
std::string sigma_integration
Index g_sc_max_iterations
std::string qp_root_finder
Index gw_sc_max_iterations
double qp_adaptive_shell_width