votca 2024.1-dev
Loading...
Searching...
No Matches
orbitals.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2023 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Standard includes
21#include <cstdio>
22#include <fstream>
23#include <iomanip>
24#include <numeric>
25
26// Local VOTCA includes
27#include "votca/tools/version.h"
28#include "votca/xtp/aomatrix.h"
29#include "votca/xtp/orbitals.h"
31#include "votca/xtp/qmstate.h"
32#include "votca/xtp/vc2index.h"
33
34namespace votca {
35namespace xtp {
36
37Orbitals::Orbitals() : atoms_("", 0) { ; }
38
47std::vector<Index> Orbitals::CheckDegeneracy(Index level,
48 double energy_difference) const {
49 if (this->isOpenShell()) {
50 throw std::runtime_error(
51 "Checking degeneracy not implemented for open-shell systems.");
52 }
53 std::vector<Index> result;
54 if (level > mos_.eigenvalues().size()) {
55 throw std::runtime_error(
56 "Level for degeneracy is higher than maximum level");
57 }
58 double MOEnergyLevel = mos_.eigenvalues()(level);
59
60 for (Index i = 0; i < mos_.eigenvalues().size(); ++i) {
61 if (std::abs(mos_.eigenvalues()(i) - MOEnergyLevel) < energy_difference) {
62 result.push_back(i);
63 }
64 }
65
66 if (result.empty()) {
67 result.push_back(level);
68 }
69 return result;
70}
71
72std::vector<Index> Orbitals::SortEnergies() {
73 if (this->isOpenShell()) {
74 throw std::runtime_error(
75 "MO sorting not implemented for open-shell systems.");
76 }
77 std::vector<Index> index = std::vector<Index>(mos_.eigenvalues().size());
78 std::iota(index.begin(), index.end(), 0);
79 std::stable_sort(index.begin(), index.end(), [this](Index i1, Index i2) {
80 return this->MOs().eigenvalues()[i1] < this->MOs().eigenvalues()[i2];
81 });
82 return index;
83}
84
90void Orbitals::SetupDftBasis(std::string basis_name) {
91 if (this->QMAtoms().size() == 0) {
92 throw std::runtime_error("Can't setup AOBasis without atoms");
93 }
94 BasisSet bs;
95 bs.Load(basis_name);
96 dftbasis_.Fill(bs, this->QMAtoms());
97}
98
99void Orbitals::SetupAuxBasis(std::string aux_basis_name) {
100 if (this->QMAtoms().size() == 0) {
101 throw std::runtime_error("Can't setup Aux AOBasis without atoms");
102 }
103 BasisSet bs;
104 bs.Load(aux_basis_name);
105 auxbasis_.Fill(bs, this->QMAtoms());
106}
107
108/*
109 * Returns the density matrix relative to the ground state, for the full density
110 * use DensityMatrixFull
111 */
112Eigen::MatrixXd Orbitals::DensityMatrixWithoutGS(const QMState& state) const {
113 if (this->isOpenShell()) {
114 throw std::runtime_error(
115 "DensityMatrixWithoutGS not implemented for open-shell systems.");
116 }
117 if (state.Type().isExciton()) {
118 std::array<Eigen::MatrixXd, 2> DMAT = DensityMatrixExcitedState(state);
119 return DMAT[1] - DMAT[0];
120 } else if (state.Type().isKSState() || state.Type().isPQPState()) {
121 return DensityMatrixKSstate(state);
122 } else if (state.Type() == QMStateType::DQPstate) {
123 Eigen::MatrixXd DMATQP = DensityMatrixQuasiParticle(state);
124 if (state.StateIdx() > getHomo()) {
125 return DMATQP;
126 } else {
127 return -DMATQP;
128 }
129 } else {
130 throw std::runtime_error(
131 "DensityMatrixWithoutGS does not yet implement QMStateType:" +
132 state.Type().ToLongString());
133 }
134}
135
136/*
137 * Returns the density matrix with the ground state density, for the partial
138 * density relative to the ground state use DensityMatrixWithoutGS
139 */
140Eigen::MatrixXd Orbitals::DensityMatrixFull(const QMState& state) const {
141 if (state.isTransition()) {
142 return this->TransitionDensityMatrix(state);
143 }
144 Eigen::MatrixXd result = this->DensityMatrixGroundState();
145
146 if (getCalculationType() != "NoEmbedding") {
147 result += getInactiveDensity();
148 }
149 if (state.Type().isExciton()) {
150 std::array<Eigen::MatrixXd, 2> DMAT = DensityMatrixExcitedState(state);
151 result = result - DMAT[0] + DMAT[1]; // Ground state + hole_contribution +
152 // electron contribution
153 } else if (state.Type() == QMStateType::DQPstate) {
154 Eigen::MatrixXd DMATQP = DensityMatrixQuasiParticle(state);
155 if (state.StateIdx() > getHomo()) {
156 result += DMATQP;
157 } else {
158 result -= DMATQP;
159 }
160 } else if (state.Type() == QMStateType::KSstate ||
161 state.Type() == QMStateType::PQPstate) {
162 Eigen::MatrixXd DMATKS = DensityMatrixKSstate(state);
163 if (state.StateIdx() <= getHomo()) {
164 result -= DMATKS;
165 } else {
166 result += DMATKS;
167 }
168 } else if (state.Type() == QMStateType::Hole ||
169 state.Type() == QMStateType::Electron) {
170 if (!this->isOpenShell()) {
171 throw std::runtime_error("QMStateType:" + state.Type().ToLongString() +
172 " requires an openshell calculation");
173 }
174 } else if (state.Type() != QMStateType::Gstate) {
175 throw std::runtime_error(
176 "DensityMatrixFull does not yet implement QMStateType:" +
177 state.Type().ToLongString());
178 }
179 return result;
180}
181
182// Determine ground state density matrix
183Eigen::MatrixXd Orbitals::DensityMatrixGroundState() const {
184 if (!hasMOs()) {
185 throw std::runtime_error("Orbitals file does not contain MO coefficients");
186 }
187 Eigen::MatrixXd occstates = mos_.eigenvectors().leftCols(occupied_levels_);
188 Eigen::MatrixXd dmatGS = occstates * occstates.transpose();
189 if (this->isOpenShell()) {
190 Eigen::MatrixXd occstates_beta =
192 dmatGS += occstates_beta * occstates_beta.transpose();
193 } else {
194 dmatGS *= 2.0;
195 }
196 return dmatGS;
197}
198// Density matrix for a single KS orbital
199Eigen::MatrixXd Orbitals::DensityMatrixKSstate(const QMState& state) const {
200 if (this->isOpenShell()) {
201 throw std::runtime_error(
202 "DensityMatrixKSstate not implemented for open-shell systems.");
203 }
204 if (!hasMOs()) {
205 throw std::runtime_error("Orbitals file does not contain MO coefficients");
206 }
207 if (state.Type() != QMStateType::KSstate &&
208 state.Type() != QMStateType::PQPstate) {
209 throw std::runtime_error("State:" + state.ToString() +
210 " is not a Kohn Sham state");
211 }
212 Eigen::VectorXd KSstate = mos_.eigenvectors().col(state.StateIdx());
213 Eigen::MatrixXd dmatKS = KSstate * KSstate.transpose();
214 return dmatKS;
215}
216
218 if (!hasQPdiag()) {
219 throw std::runtime_error("Orbitals file does not contain QP coefficients");
220 }
221 return mos_.eigenvectors().middleCols(qpmin_, qpmax_ - qpmin_ + 1) *
223}
224
225// Determine QuasiParticle Density Matrix
227 const QMState& state) const {
228 if (this->isOpenShell()) {
229 throw std::runtime_error(
230 "DensityMatrixQuasiParticle not implemented for open-shell systems.");
231 }
232 if (state.Type() != QMStateType::DQPstate) {
233 throw std::runtime_error("State:" + state.ToString() +
234 " is not a quasiparticle state");
235 }
236 Eigen::MatrixXd lambda = CalculateQParticleAORepresentation();
237 Eigen::MatrixXd dmatQP = lambda.col(state.StateIdx() - qpmin_) *
238 lambda.col(state.StateIdx() - qpmin_).transpose();
239 return dmatQP;
240}
241
242Eigen::Vector3d Orbitals::CalcElDipole(const QMState& state) const {
243 Eigen::Vector3d nuclei_dip = Eigen::Vector3d::Zero();
244 if (!state.isTransition()) {
245 for (const QMAtom& atom : atoms_) {
246 nuclei_dip += (atom.getPos() - atoms_.getPos()) * atom.getNuccharge();
247 }
248 }
249 AOBasis basis = getDftBasis();
250 AODipole dipole;
251 dipole.setCenter(atoms_.getPos());
252 dipole.Fill(basis);
253
254 Eigen::MatrixXd dmat = this->DensityMatrixFull(state);
255 Eigen::Vector3d electronic_dip;
256 for (Index i = 0; i < 3; ++i) {
257 electronic_dip(i) = dmat.cwiseProduct(dipole.Matrix()[i]).sum();
258 }
259 return nuclei_dip - electronic_dip;
260}
261
262Eigen::MatrixXd Orbitals::TransitionDensityMatrix(const QMState& state) const {
263 if (this->isOpenShell()) {
264 throw std::runtime_error(
265 "TransitionDensityMatrix not implemented for open-shell systems.");
266 }
267 if (state.Type() != QMStateType::Singlet) {
268 throw std::runtime_error(
269 "Spin type not known for transition density matrix. Available only for "
270 "singlet");
271 }
272 const Eigen::MatrixXd& BSECoefs = BSE_singlet_.eigenvectors();
273 if (BSECoefs.cols() < state.StateIdx() + 1 || BSECoefs.rows() < 2) {
274 throw std::runtime_error("Orbitals object has no information about state:" +
275 state.ToString());
276 }
277
278 // The Transition dipole is sqrt2 bigger because of the spin, the excited
279 // state is a linear combination of 2 slater determinants, where either alpha
280 // or beta spin electron is excited
281
282 /*Trying to implement D_{alpha,beta}=
283 * sqrt2*sum_{i}^{occ}sum_{j}^{virt}{BSEcoef(i,j)*MOcoef(alpha,i)*MOcoef(beta,j)}
284 */
285 // c stands for conduction band and thus virtual orbitals
286 // v stand for valence band and thus occupied orbitals
287
288 Eigen::VectorXd coeffs = BSECoefs.col(state.StateIdx());
289
290 if (!useTDA_) {
291 coeffs += BSE_singlet_.eigenvectors2().col(state.StateIdx());
292 }
293 coeffs *= std::sqrt(2.0);
294 auto occlevels = mos_.eigenvectors().middleCols(bse_vmin_, bse_vtotal_);
295 auto virtlevels = mos_.eigenvectors().middleCols(bse_cmin_, bse_ctotal_);
296 Eigen::Map<const Eigen::MatrixXd> mat(coeffs.data(), bse_ctotal_,
298
299 return occlevels * mat.transpose() * virtlevels.transpose();
300}
301
302std::array<Eigen::MatrixXd, 2> Orbitals::DensityMatrixExcitedState(
303 const QMState& state) const {
304 if (this->isOpenShell()) {
305 throw std::runtime_error(
306 "DensityMatrixExcitedState not implemented for open-shell systems.");
307 }
308 std::array<Eigen::MatrixXd, 2> dmat = DensityMatrixExcitedState_R(state);
309 if (!useTDA_) {
310 std::array<Eigen::MatrixXd, 2> dmat_AR =
312 dmat[0] -= dmat_AR[0];
313 dmat[1] -= dmat_AR[1];
314 }
315 return dmat;
316}
317
318// Excited state density matrix
319
320std::array<Eigen::MatrixXd, 2> Orbitals::DensityMatrixExcitedState_R(
321 const QMState& state) const {
322 if (!state.Type().isExciton()) {
323 throw std::runtime_error(
324 "Spin type not known for density matrix. Available are singlet and "
325 "triplet");
326 }
327
328 const Eigen::MatrixXd& BSECoefs = (state.Type() == QMStateType::Singlet)
331 if (BSECoefs.cols() < state.StateIdx() + 1 || BSECoefs.rows() < 2) {
332 throw std::runtime_error("Orbitals object has no information about state:" +
333 state.ToString());
334 }
335 /******
336 *
337 * Density matrix for GW-BSE based excitations
338 *
339 * - electron contribution
340 * D_ab = \sum{vc} \sum{c'} A_{vc}A_{vc'} mo_a(c)mo_b(c')
341 *
342 * - hole contribution
343 * D_ab = \sum{vc} \sum{v'} A_{vc}A_{v'c} mo_a(v)mo_b(v')
344 *
345 */
346
347 Eigen::VectorXd coeffs = BSECoefs.col(state.StateIdx());
348
349 std::array<Eigen::MatrixXd, 2> dmatEX;
350 // hole part as matrix products
351 Eigen::MatrixXd occlevels =
352 mos_.eigenvectors().middleCols(bse_vmin_, bse_vtotal_);
353 dmatEX[0] = occlevels * CalcAuxMat_vv(coeffs) * occlevels.transpose();
354
355 // electron part as matrix products
356 Eigen::MatrixXd virtlevels =
357 mos_.eigenvectors().middleCols(bse_cmin_, bse_ctotal_);
358 dmatEX[1] = virtlevels * CalcAuxMat_cc(coeffs) * virtlevels.transpose();
359
360 return dmatEX;
361}
362
363Eigen::MatrixXd Orbitals::CalcAuxMat_vv(const Eigen::VectorXd& coeffs) const {
364 const Eigen::Map<const Eigen::MatrixXd> mat(coeffs.data(), bse_ctotal_,
366 return mat.transpose() * mat;
367}
368
369Eigen::MatrixXd Orbitals::CalcAuxMat_cc(const Eigen::VectorXd& coeffs) const {
370 const Eigen::Map<const Eigen::MatrixXd> mat(coeffs.data(), bse_ctotal_,
372 return mat * mat.transpose();
373}
374
375std::array<Eigen::MatrixXd, 2> Orbitals::DensityMatrixExcitedState_AR(
376 const QMState& state) const {
377
378 if (!state.Type().isExciton()) {
379 throw std::runtime_error(
380 "Spin type not known for density matrix. Available are singlet and "
381 "triplet");
382 }
383
384 const Eigen::MatrixXd& BSECoefs_AR = (state.Type() == QMStateType::Singlet)
387 if (BSECoefs_AR.cols() < state.StateIdx() + 1 || BSECoefs_AR.rows() < 2) {
388 throw std::runtime_error("Orbitals object has no information about state:" +
389 state.ToString());
390 }
391 /******
392 *
393 * Density matrix for GW-BSE based excitations
394 *
395 * - electron contribution
396 * D_ab = \sum{vc} \sum{v'} B_{vc}B_{v'c} mo_a(v)mo_b(v')
397 *
398 * - hole contribution
399 * D_ab = \sum{vc} \sum{c'} B_{vc}B_{vc'} mo_a(c)mo_b(c')
400 *
401 *
402 * more efficient:
403 *
404 * - electron contribution
405 * D_ab = \sum{v} \sum{v'} mo_a(v)mo_b(v') [ \sum{c} B_{vc}B_{v'c} ]
406 * = \sum{v} \sum{v'} mo_a(v)mo_b(v') B_{vv'}
407 *
408 * - hole contribution
409 * D_ab = \sum{c} \sum{c'} mo_a(c)mo_b(c') [ \sum{v} B_{vc}B_{vc'} ]
410 * = \sum{c} \sum{c'} mo_a(c)mo_b(c') B_{cc'}
411 *
412 */
413
414 Eigen::VectorXd coeffs = BSECoefs_AR.col(state.StateIdx());
415
416 std::array<Eigen::MatrixXd, 2> dmatAR;
417 Eigen::MatrixXd virtlevels =
418 mos_.eigenvectors().middleCols(bse_cmin_, bse_ctotal_);
419 dmatAR[0] = virtlevels * CalcAuxMat_cc(coeffs) * virtlevels.transpose();
420 // electron part as matrix products
421 Eigen::MatrixXd occlevels =
422 mos_.eigenvectors().middleCols(bse_vmin_, bse_vtotal_);
423 dmatAR[1] = occlevels * CalcAuxMat_vv(coeffs) * occlevels.transpose();
424
425 return dmatAR;
426}
427
428Eigen::VectorXd Orbitals::Oscillatorstrengths() const {
429
430 Index size = Index(transition_dipoles_.size());
431 if (size > BSE_singlet_.eigenvalues().size()) {
432 size = BSE_singlet_.eigenvalues().size();
433 }
434 Eigen::VectorXd oscs = Eigen::VectorXd::Zero(size);
435 for (Index i = 0; i < size; ++i) {
436 oscs(i) = transition_dipoles_[i].squaredNorm() * 2.0 / 3.0 *
438 }
439 return oscs;
440}
441
442double Orbitals::getTotalStateEnergy(const QMState& state) const {
443 double total_energy = getDFTTotalEnergy();
444 if (state.Type() == QMStateType::Gstate) {
445 return total_energy;
446 }
447 total_energy += getExcitedStateEnergy(state);
448 return total_energy;
449}
450
451double Orbitals::getExcitedStateEnergy(const QMState& state) const {
452
453 double omega = 0.0;
454 if (state.isTransition()) {
455 throw std::runtime_error(
456 "Total Energy does not exist for transition state");
457 }
458
459 if (state.Type() == QMStateType::Singlet) {
460 if (BSE_singlet_.eigenvalues().size() < state.StateIdx() + 1) {
461 throw std::runtime_error("Orbitals::getTotalEnergy You want " +
462 state.ToString() +
463 " which has not been calculated");
464 }
465 omega = BSE_singlet_.eigenvalues()[state.StateIdx()];
466 } else if (state.Type() == QMStateType::Triplet) {
467 if (BSE_triplet_.eigenvalues().size() < state.StateIdx() + 1) {
468 throw std::runtime_error("Orbitals::getTotalEnergy You want " +
469 state.ToString() +
470 " which has not been calculated");
471 }
472 omega = BSE_triplet_.eigenvalues()[state.StateIdx()];
473 } else if (state.Type() == QMStateType::DQPstate) {
474 if (QPdiag_.eigenvalues().size() < state.StateIdx() + 1 - getGWAmin()) {
475 throw std::runtime_error("Orbitals::getTotalEnergy You want " +
476 state.ToString() +
477 " which has not been calculated");
478 }
479 return QPdiag_.eigenvalues()[state.StateIdx() - getGWAmin()];
480 } else if (state.Type() == QMStateType::KSstate) {
481 if (mos_.eigenvalues().size() < state.StateIdx() + 1) {
482 throw std::runtime_error("Orbitals::getTotalEnergy You want " +
483 state.ToString() +
484 " which has not been calculated");
485 }
486 return mos_.eigenvalues()[state.StateIdx()];
487 } else if (state.Type() == QMStateType::PQPstate) {
488 if (this->QPpert_energies_.rows() < state.StateIdx() + 1 - getGWAmin()) {
489 throw std::runtime_error("Orbitals::getTotalEnergy You want " +
490 state.ToString() +
491 " which has not been calculated");
492 }
493 return QPpert_energies_(state.StateIdx() - getGWAmin(), 3);
494 } else if (state.Type() == QMStateType::LMOstate) {
495 if (lmos_energies_.size() < state.StateIdx() + 1) {
496 throw std::runtime_error(
497 "Orbitals::getTotalEnergy You want " + state.ToString() +
498 " which is a LMO for virtual orbitals. Not implemented.");
499 }
500 return lmos_energies_(state.StateIdx());
501 } else {
502 throw std::runtime_error(
503 "GetTotalEnergy only knows states:singlet,triplet,KS,DQP,PQP,LMOs");
504 }
505 return omega; // e.g. hartree
506}
507
508std::array<Eigen::MatrixXd, 3> Orbitals::CalcFreeTransition_Dipoles() const {
509 const Eigen::MatrixXd& dft_orbitals = mos_.eigenvectors();
510 AOBasis basis = getDftBasis();
511 // Testing electric dipole AOMatrix
512 AODipole dft_dipole;
513 dft_dipole.Fill(basis);
514
515 // now transition dipole elements for free interlevel transitions
516 std::array<Eigen::MatrixXd, 3> interlevel_dipoles;
517
518 Eigen::MatrixXd empty = dft_orbitals.middleCols(bse_cmin_, bse_ctotal_);
519 Eigen::MatrixXd occ = dft_orbitals.middleCols(bse_vmin_, bse_vtotal_);
520 for (Index i = 0; i < 3; i++) {
521 interlevel_dipoles[i] = empty.transpose() * dft_dipole.Matrix()[i] * occ;
522 }
523 return interlevel_dipoles;
524}
525
527 std::array<Eigen::MatrixXd, 3> interlevel_dipoles =
529 Index numofstates = BSE_singlet_.eigenvalues().size();
530 transition_dipoles_.resize(0);
531 transition_dipoles_.reserve(numofstates);
532 const double sqrt2 = std::sqrt(2.0);
533 for (Index i_exc = 0; i_exc < numofstates; i_exc++) {
534
535 Eigen::VectorXd coeffs = BSE_singlet_.eigenvectors().col(i_exc);
536 if (!useTDA_) {
537 coeffs += BSE_singlet_.eigenvectors2().col(i_exc);
538 }
539 Eigen::Map<Eigen::MatrixXd> mat(coeffs.data(), bse_ctotal_, bse_vtotal_);
540 Eigen::Vector3d tdipole = Eigen::Vector3d::Zero();
541 for (Index i = 0; i < 3; i++) {
542 tdipole[i] = mat.cwiseProduct(interlevel_dipoles[i]).sum();
543 }
544 // The Transition dipole is sqrt2 bigger because of the spin, the
545 // excited state is a linear combination of 2 slater determinants,
546 // where either alpha or beta spin electron is excited
547 transition_dipoles_.push_back(-sqrt2 * tdipole); //- because electrons are
548 // negatively charged
549 }
550}
551
553 std::vector<Index> sort_index = SortEnergies();
554 tools::EigenSystem MO_copy = mos_;
555 Index size = mos_.eigenvalues().size();
556 for (Index i = 0; i < size; ++i) {
557 mos_.eigenvalues()(i) = MO_copy.eigenvalues()(sort_index[i]);
558 }
559 for (Index i = 0; i < size; ++i) {
560 mos_.eigenvectors().col(i) = MO_copy.eigenvectors().col(sort_index[i]);
561 }
562}
563
572 const Orbitals& orbitalsB) {
573
574 // constructing the direct product orbA x orbB
575 Index basisA = orbitalsA.getBasisSetSize();
576 Index basisB = orbitalsB.getBasisSetSize();
577
578 Index electronsA = orbitalsA.getNumberOfAlphaElectrons();
579 Index electronsB = orbitalsB.getNumberOfAlphaElectrons();
580
581 mos_.eigenvectors() = Eigen::MatrixXd::Zero(basisA + basisB, basisA + basisB);
582
583 // AxB = | A 0 | // A = [EA, EB] //
584 // | 0 B | // //
585 if (orbitalsA.getDFTbasisName() != orbitalsB.getDFTbasisName()) {
586 throw std::runtime_error("Basissets of Orbitals A and B differ " +
587 orbitalsA.getDFTbasisName() + ":" +
588 orbitalsB.getDFTbasisName());
589 }
590 this->SetupDftBasis(orbitalsA.getDFTbasisName());
591 if (orbitalsA.getECPName() != orbitalsB.getECPName()) {
592 throw std::runtime_error("ECPs of Orbitals A and B differ " +
593 orbitalsA.getECPName() + ":" +
594 orbitalsB.getECPName());
595 }
596 this->setECPName(orbitalsA.getECPName());
597 this->setNumberOfOccupiedLevels(electronsA + electronsB);
598 this->setNumberOfAlphaElectrons(electronsA + electronsB);
599
600 mos_.eigenvectors().topLeftCorner(basisA, basisA) =
601 orbitalsA.MOs().eigenvectors();
602 mos_.eigenvectors().bottomRightCorner(basisB, basisB) =
603 orbitalsB.MOs().eigenvectors();
604
605 mos_.eigenvalues().resize(basisA + basisB);
606
607 mos_.eigenvalues().head(basisA) = orbitalsA.MOs().eigenvalues();
608 mos_.eigenvalues().tail(basisB) = orbitalsB.MOs().eigenvalues();
609
611
612 return;
613}
614
615void Orbitals::WriteToCpt(const std::string& filename) const {
617 WriteToCpt(cpf);
618}
619
621 CheckpointWriter writer = f.getWriter("/QMdata");
622 WriteToCpt(writer);
623 WriteBasisSetsToCpt(writer);
624}
625
627 CheckpointWriter dftWriter = w.openChild("dft");
628 dftbasis_.WriteToCpt(dftWriter);
629 CheckpointWriter auxWriter = w.openChild("aux");
630 auxbasis_.WriteToCpt(auxWriter);
631}
632
634 w(votca::tools::ToolsVersionStr(), "XTPVersion");
635 w(orbitals_version(), "version");
636 w(occupied_levels_, "occupied_levels");
637 w(occupied_levels_beta_, "occupied_levels_beta");
638 w(number_alpha_electrons_, "number_alpha_electrons");
639 w(number_beta_electrons_, "number_beta_electrons");
640 w(total_charge_, "charge");
641 w(total_spin_, "spin");
642
643 w(mos_, "mos");
644 w(mos_beta_, "mos_beta");
645 w(occupations_, "occupations");
646 w(active_electrons_, "active_electrons");
647 w(mos_embedding_, "mos_embedding");
648 w(lmos_, "LMOs");
649 w(lmos_energies_, "LMOs_energies");
650 w(inactivedensity_, "inactivedensity");
651 w(expandedMOs_, "TruncMOsFullBasis");
652
653 CheckpointWriter molgroup = w.openChild("qmmolecule");
654 atoms_.WriteToCpt(molgroup);
655
656 w(qm_energy_, "qm_energy");
657 w(qm_package_, "qm_package");
658
659 w(rpamin_, "rpamin");
660 w(rpamax_, "rpamax");
661 w(qpmin_, "qpmin");
662 w(qpmax_, "qpmax");
663 w(bse_vmin_, "bse_vmin");
664 w(bse_cmax_, "bse_cmax");
665 w(functionalname_, "XCFunctional");
666 w(grid_quality_, "XC_grid_quality");
667 w(ScaHFX_, "ScaHFX");
668
669 w(useTDA_, "useTDA");
670 w(ECP_, "ECP");
671
672 w(rpa_inputenergies_, "RPA_inputenergies");
673 w(QPpert_energies_, "QPpert_energies");
674
675 w(QPdiag_, "QPdiag");
676
677 w(BSE_singlet_, "BSE_singlet");
678
679 w(transition_dipoles_, "transition_dipoles");
680
681 w(BSE_triplet_, "BSE_triplet");
682
683 w(use_Hqp_offdiag_, "use_Hqp_offdiag");
684
685 w(BSE_singlet_energies_dynamic_, "BSE_singlet_dynamic");
686
687 w(BSE_triplet_energies_dynamic_, "BSE_triplet_dynamic");
688
689 w(CalcType_, "CalcType");
690}
691
692void Orbitals::ReadFromCpt(const std::string& filename) {
694 ReadFromCpt(cpf);
695}
696
698 CheckpointReader reader = f.getReader("/QMdata");
699 ReadFromCpt(reader);
700 ReadBasisSetsFromCpt(reader);
701}
702
704 CheckpointReader dftReader = r.openChild("dft");
705 dftbasis_.ReadFromCpt(dftReader);
706 CheckpointReader auxReader = r.openChild("aux");
707 auxbasis_.ReadFromCpt(auxReader);
708}
709
711 r(occupied_levels_, "occupied_levels");
712 r(number_alpha_electrons_, "number_alpha_electrons");
713
714 int version;
715 r(version, "version");
716 // Read qmatoms
717 CheckpointReader molgroup = r.openChild("qmmolecule");
718 atoms_.ReadFromCpt(molgroup);
719
720 r(qm_energy_, "qm_energy");
721 r(qm_package_, "qm_package");
722 try {
723 r(lmos_, "LMOs");
724 r(lmos_energies_, "LMOs_energies");
725 } catch (std::runtime_error& e) {
726 ;
727 }
728
729 r(version, "version");
730 r(mos_, "mos");
731 r(mos_embedding_, "mos_embedding");
732 r(active_electrons_, "active_electrons");
733 r(inactivedensity_, "inactivedensity");
734 r(CalcType_, "CalcType");
735 r(expandedMOs_, "TruncMOsFullBasis");
736
737 // spin info available from version 6 or higher
738 if (version > 5) {
739 r(occupied_levels_beta_, "occupied_levels_beta");
740 r(number_beta_electrons_, "number_beta_electrons");
741 r(total_charge_, "charge");
742 r(total_spin_, "spin");
743 r(mos_beta_, "mos_beta");
744 r(occupations_, "occupations");
745 }
746
747 if (version < 3) {
748 // clang-format off
749 std::array<Index, 49> votcaOrder_old = {
750 0, // s
751 0, -1, 1, // p
752 0, -1, 1, -2, 2, // d
753 0, -1, 1, -2, 2, -3, 3, // f
754 0, -1, 1, -2, 2, -3, 3, -4, 4, // g
755 0, -1, 1, -2, 2, -3, 3, -4, 4,-5,5, // h
756 0, -1, 1, -2, 2, -3, 3, -4, 4,-5,5,-6,6 // i
757 };
758 // clang-format on
759
760 std::array<Index, 49> multiplier;
761 multiplier.fill(1);
762 OrbReorder ord(votcaOrder_old, multiplier);
763 ord.reorderOrbitals(mos_.eigenvectors(), this->getDftBasis());
764 }
765
766 if (version < 5) { // we need to construct the basissets, NB. can only be
767 // done after reading the atoms.
768 std::string dft_basis_name;
769 std::string aux_basis_name;
770 r(dft_basis_name, "dftbasis");
771 r(aux_basis_name, "auxbasis");
772 this->SetupDftBasis(dft_basis_name);
773 this->SetupAuxBasis(aux_basis_name);
774 }
775
776 r(rpamin_, "rpamin");
777 r(rpamax_, "rpamax");
778 r(qpmin_, "qpmin");
779 r(qpmax_, "qpmax");
780 r(bse_vmin_, "bse_vmin");
781 r(bse_cmax_, "bse_cmax");
783 try {
784 r(functionalname_, "XCFunctional");
785 r(grid_quality_, "XC_grid_quality");
786 } catch (std::runtime_error& e) {
787 grid_quality_ = "medium";
788 }
789 r(ScaHFX_, "ScaHFX");
790 r(useTDA_, "useTDA");
791 r(ECP_, "ECP");
792
793 r(rpa_inputenergies_, "RPA_inputenergies");
794
795 r(QPpert_energies_, "QPpert_energies");
796 r(QPdiag_, "QPdiag");
797
798 r(BSE_singlet_, "BSE_singlet");
799
800 r(transition_dipoles_, "transition_dipoles");
801
802 r(BSE_triplet_, "BSE_triplet");
803
804 r(use_Hqp_offdiag_, "use_Hqp_offdiag");
805
806 if (version > 1) {
807 r(BSE_singlet_energies_dynamic_, "BSE_singlet_dynamic");
808
809 r(BSE_triplet_energies_dynamic_, "BSE_triplet_dynamic");
810 }
811}
812} // namespace xtp
813} // namespace votca
const Eigen::MatrixXd & eigenvectors2() const
Definition eigensystem.h:36
const Eigen::VectorXd & eigenvalues() const
Definition eigensystem.h:30
const Eigen::MatrixXd & eigenvectors() const
Definition eigensystem.h:33
Container to hold Basisfunctions for all atoms.
Definition aobasis.h:42
void Fill(const BasisSet &bs, const QMMolecule &atoms)
Definition aobasis.cc:85
void WriteToCpt(CheckpointWriter &w) const
Definition aobasis.cc:141
void ReadFromCpt(CheckpointReader &r)
Definition aobasis.cc:163
void setCenter(const Eigen::Vector3d &r)
Definition aomatrix.h:94
const std::array< Eigen::MatrixXd, 3 > & Matrix() const
Definition aomatrix.h:92
void Fill(const AOBasis &aobasis) final
virtual void WriteToCpt(CheckpointWriter &w) const
virtual void ReadFromCpt(CheckpointReader &r)
const Eigen::Vector3d & getPos() const
void Load(const std::string &name)
Definition basisset.cc:149
CheckpointReader getReader()
CheckpointWriter getWriter()
CheckpointReader openChild(const std::string &childName) const
CheckpointWriter openChild(const std::string &childName) const
void reorderOrbitals(Eigen::MatrixXd &moCoefficients, const AOBasis &basis)
Definition orbreorder.cc:74
container for molecular orbitals
Definition orbitals.h:46
Index number_beta_electrons_
Definition orbitals.h:449
void CalcCoupledTransition_Dipoles()
Definition orbitals.cc:526
bool hasQPdiag() const
Definition orbitals.h:314
Eigen::MatrixXd occupations_
Definition orbitals.h:457
Eigen::VectorXd rpa_inputenergies_
Definition orbitals.h:497
Index getHomo() const
Definition orbitals.h:68
void ReadBasisSetsFromCpt(CheckpointReader r)
Definition orbitals.cc:703
Eigen::MatrixXd TransitionDensityMatrix(const QMState &state) const
Definition orbitals.cc:262
double getDFTTotalEnergy() const
Definition orbitals.h:193
Eigen::MatrixXd CalculateQParticleAORepresentation() const
Definition orbitals.cc:217
std::array< Eigen::MatrixXd, 2 > DensityMatrixExcitedState_R(const QMState &state) const
Definition orbitals.cc:320
Eigen::VectorXd lmos_energies_
Definition orbitals.h:462
tools::EigenSystem BSE_singlet_
Definition orbitals.h:504
void PrepareDimerGuess(const Orbitals &orbitalsA, const Orbitals &orbitalsB)
Guess for a dimer based on monomer orbitals.
Definition orbitals.cc:571
tools::EigenSystem mos_beta_
Definition orbitals.h:456
std::string grid_quality_
Definition orbitals.h:494
bool hasMOs() const
Definition orbitals.h:117
double getTotalStateEnergy(const QMState &state) const
Definition orbitals.cc:442
Eigen::VectorXd BSE_triplet_energies_dynamic_
Definition orbitals.h:510
std::vector< Index > CheckDegeneracy(Index level, double energy_difference) const
Definition orbitals.cc:47
Eigen::MatrixXd inactivedensity_
Definition orbitals.h:464
Index getNumberOfAlphaElectrons() const
Definition orbitals.h:93
std::string getCalculationType() const
Definition orbitals.h:159
std::array< Eigen::MatrixXd, 3 > CalcFreeTransition_Dipoles() const
Definition orbitals.cc:508
Eigen::MatrixXd CalcAuxMat_cc(const Eigen::VectorXd &coeffs) const
Definition orbitals.cc:369
Eigen::MatrixXd expandedMOs_
Definition orbitals.h:465
void setNumberOfAlphaElectrons(Index electrons)
Definition orbitals.h:96
Eigen::VectorXd Oscillatorstrengths() const
Definition orbitals.cc:428
std::vector< Eigen::Vector3d > transition_dipoles_
Definition orbitals.h:505
static constexpr int orbitals_version()
Definition orbitals.h:519
std::string functionalname_
Definition orbitals.h:493
Eigen::MatrixXd lmos_
Definition orbitals.h:461
Eigen::MatrixXd DensityMatrixWithoutGS(const QMState &state) const
Definition orbitals.cc:112
void WriteBasisSetsToCpt(CheckpointWriter w) const
Definition orbitals.cc:626
Eigen::MatrixXd DensityMatrixFull(const QMState &state) const
Definition orbitals.cc:140
Eigen::MatrixXd CalcAuxMat_vv(const Eigen::VectorXd &coeffs) const
Definition orbitals.cc:363
void SetupAuxBasis(std::string aux_basis_name)
Definition orbitals.cc:99
std::string qm_package_
Definition orbitals.h:495
tools::EigenSystem BSE_triplet_
Definition orbitals.h:506
void setBSEindices(Index vmin, Index cmax)
Definition orbitals.h:273
const Eigen::MatrixXd & getInactiveDensity() const
Definition orbitals.h:424
std::vector< Index > SortEnergies()
Definition orbitals.cc:72
std::array< Eigen::MatrixXd, 2 > DensityMatrixExcitedState_AR(const QMState &state) const
Definition orbitals.cc:375
double getExcitedStateEnergy(const QMState &state) const
Definition orbitals.cc:451
void setECPName(const std::string &ECP)
Definition orbitals.h:106
void setNumberOfOccupiedLevels(Index occupied_levels)
Definition orbitals.h:78
Index occupied_levels_beta_
Definition orbitals.h:447
tools::EigenSystem mos_
Definition orbitals.h:455
tools::EigenSystem QPdiag_
Definition orbitals.h:502
Eigen::MatrixXd DensityMatrixKSstate(const QMState &state) const
Definition orbitals.cc:199
Eigen::MatrixXd DensityMatrixQuasiParticle(const QMState &state) const
Definition orbitals.cc:226
Index getBasisSetSize() const
Definition orbitals.h:64
Eigen::VectorXd BSE_singlet_energies_dynamic_
Definition orbitals.h:509
Index getGWAmin() const
Definition orbitals.h:249
const tools::EigenSystem & MOs() const
Definition orbitals.h:122
Eigen::MatrixXd DensityMatrixGroundState() const
Definition orbitals.cc:183
std::string CalcType_
Definition orbitals.h:453
const QMMolecule & QMAtoms() const
Definition orbitals.h:172
tools::EigenSystem mos_embedding_
Definition orbitals.h:459
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:692
Eigen::VectorXd QPpert_energies_
Definition orbitals.h:499
void WriteToCpt(const std::string &filename) const
Definition orbitals.cc:615
const std::string & getECPName() const
Definition orbitals.h:104
const std::string & getDFTbasisName() const
Definition orbitals.h:202
void SetupDftBasis(std::string basis_name)
Definition orbitals.cc:90
std::array< Eigen::MatrixXd, 2 > DensityMatrixExcitedState(const QMState &state) const
Definition orbitals.cc:302
bool isOpenShell() const
Definition orbitals.h:168
std::string ECP_
Definition orbitals.h:450
Index number_alpha_electrons_
Definition orbitals.h:448
Eigen::Vector3d CalcElDipole(const QMState &state) const
Definition orbitals.cc:242
const AOBasis & getDftBasis() const
Definition orbitals.h:208
QMMolecule atoms_
Definition orbitals.h:467
container for QM atoms
Definition qmatom.h:37
std::string ToLongString() const
Definition qmstate.cc:69
bool isKSState() const
Definition qmstate.h:89
bool isPQPState() const
Definition qmstate.h:91
bool isExciton() const
Definition qmstate.h:71
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
Definition qmstate.h:132
std::string ToString() const
Definition qmstate.cc:146
Index StateIdx() const
Definition qmstate.h:154
bool isTransition() const
Definition qmstate.h:153
const QMStateType & Type() const
Definition qmstate.h:151
const std::string & ToolsVersionStr()
Definition version.cc:33
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26