votca 2025.1-dev
Loading...
Searching...
No Matches
diabatization.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2022 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#include "diabatization.h"
19
20using std::flush;
21
22namespace votca {
23namespace xtp {
24
26
27 log_.setReportLevel(Log::current_level);
28 log_.setMultithreading(true);
29 log_.setCommonPreface("\n...");
30
31 tools::Property options = user_options;
32
33 // getting diabatization method and checking validity
34 method_ = options.get(".method").as<std::string>();
35 if (method_ == "er") {
36 XTP_LOG(Log::error, log_) << "Method : Edminston-Rudenberg" << flush;
37 } else if (method_ == "gmh") {
38 XTP_LOG(Log::error, log_) << "Method : Generalized Mulliken-Hush" << flush;
39 } else if (method_ == "fcd") {
40 XTP_LOG(Log::error, log_) << "Method : Fragment Charge Difference" << flush;
41 } else {
42 throw std::runtime_error("Diabatization method unknown!");
43 }
44
45 // getting orbfiles
46 orbfile1_ = options.get(".orb_file").as<std::string>();
47 // checking if this is QMMM
48 if (options.exists(".orb_file2")) {
49 orbfile2_ = options.get(".orb_file2").as<std::string>();
50 E1_ = options.get(".E1").as<double>();
51 E2_ = options.get(".E2").as<double>();
52 isQMMM_ = true;
53 } else {
55 isQMMM_ = false;
56 }
57
58 // getting state options and checking validity
59 state_idx_1_ = options.get(".state_idx_1").as<Index>();
60 state_idx_2_ = options.get(".state_idx_2").as<Index>();
61 qmtype_ = options.get(".qmtype").as<std::string>();
62 XTP_LOG(Log::error, log_) << "Type : " << qmtype_ << flush;
63
64 if (state_idx_1_ < 1) {
65 throw std::runtime_error("State idx 1 must start from 1.");
66 } else {
67 XTP_LOG(Log::error, log_) << "State 1 : " << state_idx_1_ << flush;
68 }
69
70 if (state_idx_2_ < 1) {
71 throw std::runtime_error("State idx 2 must start from 1.");
72 } else {
73 XTP_LOG(Log::error, log_) << "State 2 : " << state_idx_2_ << flush;
74 }
75
76 useRI_ = options.get(".use_RI").as<bool>();
77
78 if (options.exists(".fragments")) {
79 std::vector<tools::Property*> prop_region =
80 options.Select("fragments.fragment");
81 Index index = 0;
82 for (tools::Property* prop : prop_region) {
83 std::string indices = prop->get("indices").as<std::string>();
84 fragments_.push_back(QMFragment<BSE_Population>(index, indices));
85 index++;
86 }
87 }
88
89 XTP_LOG(Log::error, log_) << flush;
90}
91
93
95
96 // set logger
97 log_.setReportLevel(Log::current_level);
98 // log_.setReportLevel(Log::error);
99 log_.setMultithreading(true);
100 log_.setCommonPreface("\n...");
101
103 << TimeStamp() << " Reading from orbitals from files: " << orbfile1_
104 << " and " << orbfile2_ << flush;
105
106 // Get orbitals objects
107 Orbitals orbitals1;
108 Orbitals orbitals2;
109
110 orbitals1.ReadFromCpt(orbfile1_);
111 orbitals2.ReadFromCpt(orbfile2_);
112
113 if (orbitals1.getTDAApprox()) {
115 << TimeStamp() << " " << orbfile1_ << " was done with TDA." << flush;
116 }
117 if (orbitals2.getTDAApprox()) {
119 << TimeStamp() << " " << orbfile2_ << " was done with TDA. " << flush;
120 }
121
122 double QMMM_correction;
123 double J;
124 double J_QMMM;
125 double E1ad = 0.0;
126 double E2ad = 0.0;
127
128 if (method_ == "er") {
129 ERDiabatization ERDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
133
134 // Calculate optimal mixing angle
135 double angle = ERDiabatization.Calculate_angle();
136
137 // Calculate the diabatic Hamiltonian
138 std::pair<Eigen::VectorXd, Eigen::MatrixXd> rotate_H =
140 E1ad = rotate_H.first(0);
141 E2ad = rotate_H.first(1);
142 Eigen::MatrixXd& diabatic_H = rotate_H.second;
143
144 // Printing Output
145 if (!isQMMM_) {
147 << boost::format("Diabatic Energy 1: %1$+1.12f eV") %
148 (diabatic_H(0, 0) * votca::tools::conv::hrt2ev)
149 << flush;
151 << boost::format("Diabatic Energy 2: %1$+1.12f eV") %
152 (diabatic_H(1, 1) * votca::tools::conv::hrt2ev)
153 << flush;
154 E1_ = E1ad;
155 E2_ = E2ad;
156 }
157
158 QMMM_correction = (E2_ - E1_) / (E2ad - E1ad);
159 J = diabatic_H(1, 0) * votca::tools::conv::hrt2ev;
160 J_QMMM = J * QMMM_correction;
161
162 if (std::abs(diabatic_H(1, 0) - diabatic_H(0, 1)) >
163 1e-4 * std::abs(diabatic_H(1, 0))) {
164 XTP_LOG(Log::error, log_) << "Different offdiagonal "
165 << diabatic_H(0, 1) * votca::tools::conv::hrt2ev
166 << " --- Check carefully!" << flush;
167 }
168 } else if (method_ == "gmh") {
169
170 GMHDiabatization GMHDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
172
174 std::pair<double, double> coupling = GMHDiabatization.calculate_coupling();
175
176 double J_unproj = coupling.first * votca::tools::conv::hrt2ev;
177 J = coupling.second * votca::tools::conv::hrt2ev;
178
180 << boost::format("Unprojected diabatic Coupling: %1$+1.12f eV") % (J_unproj)
181 << flush;
182 std::pair<double, double> Ead = GMHDiabatization.adiabatic_energies();
183
184 E1ad = Ead.first;
185 E2ad = Ead.second;
186
187 if (isQMMM_) {
188 QMMM_correction = (E2_ - E1_) / (Ead.second - Ead.first);
189 J_QMMM = J * QMMM_correction;
190 }
191
192 } else if (method_ == "fcd") {
193
194 // check if fragments are empty
195 if (fragments_.size() == 0) {
196 throw std::runtime_error("Fragments are undefined in FCD!");
197 }
198
199 FCDDiabatization FCDDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
201
203
205 std::pair<double, double> Ead = FCDDiabatization.adiabatic_energies();
206 E1ad = Ead.first;
207 E2ad = Ead.second;
208 if (isQMMM_) {
209 QMMM_correction = (E2_ - E1_) / (Ead.second - Ead.first);
210 J_QMMM = J * QMMM_correction;
211 }
212 }
213
214 // print output
216 << boost::format("Internal adiabatic energies: %1$+1.12f eV and %2$+1.12f eV") %
219 << flush;
220
222 << boost::format("Diabatic Coupling: %1$+1.12f eV ") % (J) << flush;
223 if (isQMMM_) {
224
226 << boost::format("QMMM adiabatic energies: %1$+1.12f eV and %2$+1.12f eV") %
229 << flush;
230
232 << boost::format("QMMM correction factor: %1$+1.12f ") % (QMMM_correction)
233 << flush;
235 << boost::format("Diabatic Coupling with QMMM: %1$+1.12f eV ") % (J_QMMM)
236 << flush;
237 }
238
239 return true;
240}
241} // namespace xtp
242} // namespace votca
class to manage program options with xml serialization functionality
Definition property.h:55
Property & get(const std::string &key)
get existing property
Definition property.cc:79
bool exists(const std::string &key) const
check whether property exists
Definition property.cc:122
T as() const
return value as type
Definition property.h:283
std::vector< Property * > Select(const std::string &filter)
select property based on a filter
Definition property.cc:185
void ParseOptions(const tools::Property &user_options) final
std::vector< QMFragment< BSE_Population > > fragments_
std::pair< Eigen::VectorXd, Eigen::MatrixXd > Calculate_diabatic_H(const double angle) const
const std::pair< double, double > adiabatic_energies()
std::pair< double, double > calculate_coupling()
const std::pair< double, double > adiabatic_energies()
container for molecular orbitals
Definition orbitals.h:46
bool getTDAApprox() const
Definition orbitals.h:269
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:695
Timestamp returns the current time as a string Example: cout << TimeStamp()
Definition logger.h:224
#define XTP_LOG(level, log)
Definition logger.h:40
const double hrt2ev
Definition constants.h:53
void setMaxThreads(Index)
Definition eigen.h:158
Charge transport classes.
Definition ERIs.h:28
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
static Level current_level
Definition globals.h:30