votca 2024.1-dev
Loading...
Searching...
No Matches
spectrum.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 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// Third party includes
21#include <boost/math/constants/constants.hpp>
22
23// VOTCA includes
25
26// Local VOTCA includes
27#include <votca/xtp/orbitals.h>
28
29// Local private VOTCA includes
30#include "spectrum.h"
31
32namespace votca {
33namespace xtp {
34
36
37 // orbitals file or pure DFT output
38 orbfile_ = options.ifExistsReturnElseReturnDefault<std::string>(
39 ".input", job_name_ + ".orb");
40
41 output_file_ = options.ifExistsReturnElseReturnDefault<std::string>(
42 ".output", job_name_ + "_spectrum.dat");
43
44 n_pt_ = options.get(".points").as<Index>();
45 lower_ = options.get(".lower").as<double>();
46 upper_ = options.get(".upper").as<double>();
47 fwhm_ = options.get(".fwhm").as<double>();
48
49 spectrum_type_ = options.get(".type").as<std::string>();
50 minexc_ = options.get(".minexc").as<Index>();
51 maxexc_ = options.get(".maxexc").as<Index>();
52 shiftby_ = options.get(".shift").as<double>();
53}
54
58
59 log_.setCommonPreface("\n... ...");
60
62 << "Calculating absorption spectrum plot " << orbfile_ << std::flush;
63
64 Orbitals orbitals;
65 // load the QM data from serialized orbitals object
67 << " Loading QM data from " << orbfile_ << std::flush;
68 orbitals.ReadFromCpt(orbfile_);
69
70 // check if orbitals contains singlet energies and transition dipoles
71 if (!orbitals.hasBSESinglets()) {
72 throw std::runtime_error(
73 "BSE singlet energies not stored in QM data file!");
74 }
75
76 if (!orbitals.hasTransitionDipoles()) {
77 throw std::runtime_error(
78 "BSE transition dipoles not stored in QM data file!");
79 }
80
81 const Eigen::VectorXd BSESingletEnergies =
83 const std::vector<Eigen::Vector3d>& TransitionDipoles =
84 orbitals.TransitionDipoles();
85 Eigen::VectorXd osc = orbitals.Oscillatorstrengths();
86
87 if (maxexc_ > Index(TransitionDipoles.size())) {
88 maxexc_ = Index(TransitionDipoles.size()) - 1;
89 }
90
91 Index n_exc = maxexc_ - minexc_ + 1;
93 << " Considering " << n_exc << " excitation with max energy "
94 << BSESingletEnergies(maxexc_) << " eV / min wave length "
95 << evtonm(BSESingletEnergies[maxexc_ - 1]) << " nm" << std::flush;
96
97 /*
98 *
99 * For a single excitation, broaden by Lineshape function L(v-W)
100 * eps(v) = f * L(v-W)
101 *
102 * where
103 * v: energy
104 * f: oscillator strength in dipole-length gauge
105 * W: excitation energy
106 *
107 * Lineshape function depend on FWHM and can be
108 *
109 * Gaussian
110 * L(v-W) = 1/(sqrt(2pi)sigma) * exp(-0.5 (v-W)^2/sigma^2
111 *
112 *
113 * with sigma: derived from FWHM (FWHM/2.3548)
114 *
115 * Lorentzian
116 * L(v-W) = 1/pi * 0.5 FWHM/( (v-w)^2 + 0.25*FWHM^2 )
117 *
118 * Full spectrum is superposition of individual spectra.
119 *
120 * Alternatively, one can calculate the imaginary part of the
121 * frequency-dependent dielectric function
122 *
123 * IM(eps(v)) ~ 1/v^2 * W^2 * |td|^2 * L(v-W)
124 * = 1/v^2 * W * f * L(v-W)
125 *
126 *
127 */
128
129 std::ofstream ofs(output_file_, std::ofstream::out);
130
131 if (spectrum_type_ == "energy") {
132 ofs << "# E(eV) epsGaussian IM(eps)Gaussian epsLorentz "
133 "Im(esp)Lorentz\n";
134 for (Index i_pt = 0; i_pt <= n_pt_; i_pt++) {
135
136 double e = (lower_ + double(i_pt) * (upper_ - lower_) / double(n_pt_));
137
138 double eps_Gaussian = 0.0;
139 double imeps_Gaussian = 0.0;
140 double eps_Lorentzian = 0.0;
141 double imeps_Lorentzian = 0.0;
142
143 for (Index i_exc = minexc_; i_exc <= maxexc_; i_exc++) {
144 eps_Gaussian +=
145 osc[i_exc] *
146 Gaussian(e, BSESingletEnergies(i_exc) + shiftby_, fwhm_);
147 imeps_Gaussian += osc[i_exc] * BSESingletEnergies(i_exc) *
148 Gaussian(e, BSESingletEnergies(i_exc), fwhm_);
149 eps_Lorentzian +=
150 osc[i_exc] * Lorentzian(e, BSESingletEnergies(i_exc), fwhm_);
151 imeps_Lorentzian += osc[i_exc] * BSESingletEnergies(i_exc) *
152 Lorentzian(e, BSESingletEnergies(i_exc), fwhm_);
153 }
154
155 ofs << e << " " << eps_Gaussian << " " << imeps_Gaussian << " "
156 << eps_Lorentzian << " " << imeps_Lorentzian << std::endl;
157 }
158
160 << " Spectrum in energy range from " << lower_ << " to " << upper_
161 << " eV and with broadening of FWHM " << fwhm_
162 << " eV written to file " << output_file_ << std::flush;
163 }
164
165 if (spectrum_type_ == "wavelength") {
166
167 ofs << "# lambda(nm) epsGaussian IM(eps)Gaussian epsLorentz "
168 "Im(esp)Lorentz\n";
169 for (Index i_pt = 0; i_pt <= n_pt_; i_pt++) {
170
171 double lambda =
172 (lower_ + double(i_pt) * (upper_ - lower_) / double(n_pt_));
173 double eps_Gaussian = 0.0;
174 double imeps_Gaussian = 0.0;
175 double eps_Lorentzian = 0.0;
176 double imeps_Lorentzian = 0.0;
177
178 for (Index i_exc = minexc_; i_exc <= maxexc_; i_exc++) {
179 double exc_lambda = nmtoev(BSESingletEnergies(i_exc) + shiftby_);
180 eps_Gaussian += osc[i_exc] * Gaussian(lambda, exc_lambda, fwhm_);
181 imeps_Gaussian +=
182 osc[i_exc] * exc_lambda * Gaussian(lambda, exc_lambda, fwhm_);
183 eps_Lorentzian += osc[i_exc] * Lorentzian(lambda, exc_lambda, fwhm_);
184 imeps_Lorentzian +=
185 osc[i_exc] * exc_lambda * Lorentzian(lambda, exc_lambda, fwhm_);
186 }
187
188 ofs << lambda << " " << eps_Gaussian << " " << imeps_Gaussian
189 << " " << eps_Lorentzian << " " << imeps_Lorentzian << std::endl;
190 }
192 << " Spectrum in wavelength range from " << lower_ << " to " << upper_
193 << " nm and with broadening of FWHM " << fwhm_
194 << " nm written to file " << output_file_ << std::flush;
195 }
196
197 ofs.close();
198 return true;
199}
200
201double Spectrum::Lorentzian(double x, double center, double fwhm) {
202 return 0.5 * fwhm / (std::pow(x - center, 2) + 0.25 * fwhm * fwhm) /
203 boost::math::constants::pi<double>();
204}
205
206double Spectrum::Gaussian(double x, double center, double fwhm) {
207 // FWHM = 2*sqrt(2 ln2) sigma = 2.3548 sigma
208 double sigma = fwhm / 2.3548;
209 return std::exp(-0.5 * std::pow((x - center) / sigma, 2)) / sigma /
210 sqrt(2.0 * boost::math::constants::pi<double>());
211}
212
213double Spectrum::evtonm(double eV) { return 1241.0 / eV; }
214
215double Spectrum::evtoinvcm(double eV) { return 8065.73 * eV; }
216
217double Spectrum::nmtoinvcm(double nm) { return 1241.0 * 8065.73 / nm; }
218
219double Spectrum::invcmtonm(double invcm) { return 1.0e7 / invcm; }
220
221double Spectrum::nmtoev(double nm) { return 1241.0 / nm; }
222
223} // namespace xtp
224} // namespace votca
const Eigen::VectorXd & eigenvalues() const
Definition eigensystem.h:30
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
T as() const
return value as type
Definition property.h:283
T ifExistsReturnElseReturnDefault(const std::string &key, T defaultvalue) const
Definition property.h:321
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
const tools::EigenSystem & BSESinglets() const
Definition orbitals.h:334
bool hasBSESinglets() const
Definition orbitals.h:330
Eigen::VectorXd Oscillatorstrengths() const
Definition orbitals.cc:428
bool hasTransitionDipoles() const
Definition orbitals.h:365
const std::vector< Eigen::Vector3d > & TransitionDipoles() const
Definition orbitals.h:369
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:692
std::string job_name_
Definition qmtool.h:50
double Lorentzian(double x, double center, double fwhm)
Definition spectrum.cc:201
double invcmtonm(double invcm)
Definition spectrum.cc:219
std::string spectrum_type_
Definition spectrum.h:70
double evtoinvcm(double eV)
Definition spectrum.cc:215
double nmtoinvcm(double nm)
Definition spectrum.cc:217
double Gaussian(double x, double center, double fwhm)
Definition spectrum.cc:206
std::string output_file_
Definition spectrum.h:50
void ParseOptions(const tools::Property &user_options)
Definition spectrum.cc:35
double nmtoev(double nm)
Definition spectrum.cc:221
std::string orbfile_
Definition spectrum.h:49
double evtonm(double eV)
Definition spectrum.cc:213
#define XTP_LOG(level, log)
Definition logger.h:40
const double hrt2ev
Definition constants.h:53
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