votca 2024.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 boost::format;
21using std::flush;
22
23namespace votca {
24namespace xtp {
25
27
30 log_.setCommonPreface("\n...");
31
32 tools::Property options = user_options;
33
34 // getting diabatization method and checking validity
35 method_ = options.get(".method").as<std::string>();
36 if (method_ == "er") {
37 XTP_LOG(Log::error, log_) << "Method : Edminston-Rudenberg" << flush;
38 } else if (method_ == "gmh") {
39 XTP_LOG(Log::error, log_) << "Method : Generalized Mulliken-Hush" << flush;
40 } else if (method_ == "fcd") {
41 XTP_LOG(Log::error, log_) << "Method : Fragment Charge Difference" << flush;
42 } else {
43 throw std::runtime_error("Diabatization method unknown!");
44 }
45
46 // getting orbfiles
47 orbfile1_ = options.get(".orb_file").as<std::string>();
48 // checking if this is QMMM
49 if (options.exists(".orb_file2")) {
50 orbfile2_ = options.get(".orb_file2").as<std::string>();
51 E1_ = options.get(".E1").as<double>();
52 E2_ = options.get(".E2").as<double>();
53 isQMMM_ = true;
54 } else {
56 isQMMM_ = false;
57 }
58
59 // getting state options and checking validity
60 state_idx_1_ = options.get(".state_idx_1").as<Index>();
61 state_idx_2_ = options.get(".state_idx_2").as<Index>();
62 qmtype_ = options.get(".qmtype").as<std::string>();
63 XTP_LOG(Log::error, log_) << "Type : " << qmtype_ << flush;
64
65 if (state_idx_1_ < 1) {
66 throw std::runtime_error("State idx 1 must start from 1.");
67 } else {
68 XTP_LOG(Log::error, log_) << "State 1 : " << state_idx_1_ << flush;
69 }
70
71 if (state_idx_2_ < 1) {
72 throw std::runtime_error("State idx 2 must start from 1.");
73 } else {
74 XTP_LOG(Log::error, log_) << "State 2 : " << state_idx_2_ << flush;
75 }
76
77 useRI_ = options.get(".use_RI").as<bool>();
78
79 if (options.exists(".fragments")) {
80 std::vector<tools::Property*> prop_region =
81 options.Select("fragments.fragment");
82 Index index = 0;
83 for (tools::Property* prop : prop_region) {
84 std::string indices = prop->get("indices").as<std::string>();
85 fragments_.push_back(QMFragment<BSE_Population>(index, indices));
86 index++;
87 }
88 }
89
90 XTP_LOG(Log::error, log_) << flush;
91}
92
94
96
97 // set logger
99 // log_.setReportLevel(Log::error);
101 log_.setCommonPreface("\n...");
102
104 << TimeStamp() << " Reading from orbitals from files: " << orbfile1_
105 << " and " << orbfile2_ << flush;
106
107 // Get orbitals objects
108 Orbitals orbitals1;
109 Orbitals orbitals2;
110
111 orbitals1.ReadFromCpt(orbfile1_);
112 orbitals2.ReadFromCpt(orbfile2_);
113
114 if (orbitals1.getTDAApprox()) {
116 << TimeStamp() << " " << orbfile1_ << " was done with TDA." << flush;
117 }
118 if (orbitals2.getTDAApprox()) {
120 << TimeStamp() << " " << orbfile2_ << " was done with TDA. " << flush;
121 }
122
123 double QMMM_correction;
124 double J;
125 double J_QMMM;
126 double E1ad = 0.0;
127 double E2ad = 0.0;
128
129 if (method_ == "er") {
130 ERDiabatization ERDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
134
135 // Calculate optimal mixing angle
136 double angle = ERDiabatization.Calculate_angle();
137
138 // Calculate the diabatic Hamiltonian
139 std::pair<Eigen::VectorXd, Eigen::MatrixXd> rotate_H =
141 E1ad = rotate_H.first(0);
142 E2ad = rotate_H.first(1);
143 Eigen::MatrixXd& diabatic_H = rotate_H.second;
144
145 // Printing Output
146 if (!isQMMM_) {
148 << format("Diabatic Energy 1: %1$+1.12f eV") %
149 (diabatic_H(0, 0) * votca::tools::conv::hrt2ev)
150 << flush;
152 << format("Diabatic Energy 2: %1$+1.12f eV") %
153 (diabatic_H(1, 1) * votca::tools::conv::hrt2ev)
154 << flush;
155 E1_ = E1ad;
156 E2_ = E2ad;
157 }
158
159 QMMM_correction = (E2_ - E1_) / (E2ad - E1ad);
160 J = diabatic_H(1, 0) * votca::tools::conv::hrt2ev;
161 J_QMMM = J * QMMM_correction;
162
163 if (std::abs(diabatic_H(1, 0) - diabatic_H(0, 1)) >
164 1e-4 * std::abs(diabatic_H(1, 0))) {
165 XTP_LOG(Log::error, log_) << "Different offdiagonal "
166 << diabatic_H(0, 1) * votca::tools::conv::hrt2ev
167 << " --- Check carefully!" << flush;
168 }
169 } else if (method_ == "gmh") {
170
171 GMHDiabatization GMHDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
173
175 std::pair<double, double> coupling = GMHDiabatization.calculate_coupling();
176
177 double J_unproj = coupling.first * votca::tools::conv::hrt2ev;
178 J = coupling.second * votca::tools::conv::hrt2ev;
179
181 << format("Unprojected diabatic Coupling: %1$+1.12f eV") % (J_unproj)
182 << flush;
183 std::pair<double, double> Ead = GMHDiabatization.adiabatic_energies();
184
185 E1ad = Ead.first;
186 E2ad = Ead.second;
187
188 if (isQMMM_) {
189 QMMM_correction = (E2_ - E1_) / (Ead.second - Ead.first);
190 J_QMMM = J * QMMM_correction;
191 }
192
193 } else if (method_ == "fcd") {
194
195 // check if fragments are empty
196 if (fragments_.size() == 0) {
197 throw std::runtime_error("Fragments are undefined in FCD!");
198 }
199
200 FCDDiabatization FCDDiabatization(orbitals1, orbitals2, &log_, state_idx_1_,
202
204
206 std::pair<double, double> Ead = FCDDiabatization.adiabatic_energies();
207 E1ad = Ead.first;
208 E2ad = Ead.second;
209 if (isQMMM_) {
210 QMMM_correction = (E2_ - E1_) / (Ead.second - Ead.first);
211 J_QMMM = J * QMMM_correction;
212 }
213 }
214
215 // print output
217 << format("Internal adiabatic energies: %1$+1.12f eV and %2$+1.12f eV") %
220 << flush;
221
223 << format("Diabatic Coupling: %1$+1.12f eV ") % (J) << flush;
224 if (isQMMM_) {
225
227 << format("QMMM adiabatic energies: %1$+1.12f eV and %2$+1.12f eV") %
230 << flush;
231
233 << format("QMMM correction factor: %1$+1.12f ") % (QMMM_correction)
234 << flush;
236 << format("Diabatic Coupling with QMMM: %1$+1.12f eV ") % (J_QMMM)
237 << flush;
238 }
239
240 return true;
241}
242} // namespace xtp
243} // 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()
void setReportLevel(Log::Level ReportLevel)
Definition logger.h:185
void setMultithreading(bool maverick)
Definition logger.h:186
void setCommonPreface(const std::string &preface)
Definition logger.h:198
container for molecular orbitals
Definition orbitals.h:46
bool getTDAApprox() const
Definition orbitals.h:269
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:692
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
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
static Level current_level
Definition globals.h:30