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 // Standard includes
21 #include <regex>
22
23 // Third party includes
24 #include <boost/algorithm/string.hpp>
25 #include <boost/format.hpp>
26 #include <boost/lexical_cast.hpp>
27 #include <boost/regex.hpp>
28
29 // Local VOTCA includes
30 #include "votca/xtp/qmstate.h"
31
32 namespace votca {
33 namespace xtp {
34
ToString() const35 std::string QMStateType::ToString() const {
36 std::string identifier = "";
37 switch (type_) {
38 case QMStateType::Singlet:
39 identifier = "s";
40 break;
41 case QMStateType::Triplet:
42 identifier = "t";
43 break;
44 case QMStateType::PQPstate:
45 identifier = "pqp";
46 break;
47 case QMStateType::DQPstate:
48 identifier = "dqp";
49 break;
50 case QMStateType::KSstate:
51 identifier = "ks";
52 break;
53 case QMStateType::Gstate:
54 identifier = "n";
55 break;
56 case QMStateType::Hole:
57 identifier = "h";
58 break;
59 case QMStateType::Electron:
60 identifier = "e";
61 break;
62 }
63 return identifier;
64 }
65
ToLongString() const66 std::string QMStateType::ToLongString() const {
67 std::string identifier = "";
68 switch (type_) {
69 case QMStateType::Singlet:
70 identifier = "singlet";
71 break;
72 case QMStateType::Triplet:
73 identifier = "triplet";
74 break;
75 case QMStateType::PQPstate:
76 identifier = "pert-qparticle";
77 break;
78 case QMStateType::DQPstate:
79 identifier = "diag-qparticle";
80 break;
81 case QMStateType::KSstate:
82 identifier = "Kohn-Sham-orbital";
83 break;
84 case QMStateType::Gstate:
85 identifier = "groundstate";
86 break;
87 case QMStateType::Hole:
88 identifier = "hole";
89 break;
90 case QMStateType::Electron:
91 identifier = "electron";
92 break;
93 }
94 return identifier;
95 }
96
FromString(const std::string & statetypestring)97 void QMStateType::FromString(const std::string& statetypestring) {
98 std::string lower = boost::algorithm::to_lower_copy(statetypestring);
99 boost::trim(lower);
100 if (lower == "s" || lower == "singlet") {
101 type_ = QMStateType::Singlet;
102 } else if (lower == "t" || lower == "triplet") {
103 type_ = QMStateType::Triplet;
104 } else if (lower == "pqp" || lower == "pert-qparticle") {
105 type_ = QMStateType::PQPstate;
106 } else if (lower == "dqp" || lower == "diag-qparticle" || lower == "qpdiag") {
107 type_ = QMStateType::DQPstate;
108 } else if (lower == "ks" || lower == "kohn-sham-orbital") {
109 type_ = QMStateType::KSstate;
110 } else if (lower == "n" || lower == "groundstate" || lower == "gs") {
111 type_ = QMStateType::Gstate;
112 } else if (lower == "h" || lower == "hole") {
113 type_ = QMStateType::Hole;
114 } else if (lower == "e" || lower == "electron") {
115 type_ = QMStateType::Electron;
116 } else {
117 throw std::runtime_error("Statetype:" + statetypestring +
118 " not recognized");
119 }
120 }
121
ToLongString() const122 std::string QMState::ToLongString() const {
123 Index index = index_;
124 if (type_ == QMStateType::Singlet || type_ == QMStateType::Triplet) {
125 index++;
126 } else if (type_ == QMStateType::Gstate || type_ == QMStateType::Electron ||
127 type_ == QMStateType::Hole) {
128 return type_.ToLongString();
129 }
130 std::string result =
131 type_.ToLongString() + (boost::format(" %i") % index).str();
132 if (transition_) {
133 result = "Groundstate to " + result;
134 }
135 return result;
136 }
137
ToString() const138 std::string QMState::ToString() const {
139 Index index = index_;
140 if (type_ == QMStateType::Singlet || type_ == QMStateType::Triplet) {
141 index++;
142 } else if (type_ == QMStateType::Gstate || type_ == QMStateType::Electron ||
143 type_ == QMStateType::Hole) {
144 return type_.ToString();
145 }
146 std::string result = type_.ToString() + (boost::format("%i") % index).str();
147 if (transition_) {
148 result = "n2" + result;
149 }
150 return result;
151 }
152
DetermineIndex(const std::string & statestring)153 Index QMState::DetermineIndex(const std::string& statestring) {
154
155 std::smatch search;
156 std::regex reg("[0-9]+");
157
158 bool found_integer = std::regex_search(statestring, search, reg);
159 if (!found_integer) {
160
161 if (type_ == QMStateType::Hole || type_ == QMStateType::Electron) {
162 return 0;
163 }
164
165 throw std::runtime_error("Found no index in string: " + statestring);
166 }
167 if (search.size() > 1) {
168 throw std::runtime_error("Found more than 1 index in string: " +
169 statestring);
170 }
171
172 Index index = boost::lexical_cast<Index>(search.str(0));
173 if (type_.isExciton() || type_ == QMStateType::Electron ||
174 type_ == QMStateType::Hole) {
175 index--;
176 }
177 return index;
178 }
179
DetermineType(const std::string & statestring)180 QMStateType QMState::DetermineType(const std::string& statestring) {
181 std::regex reg("[^0-9]+");
182 std::smatch search;
183
184 bool found_typestring = std::regex_search(statestring, search, reg);
185 if (!found_typestring) {
186 throw std::runtime_error("Found no type in string: " + statestring);
187 }
188 if (search.size() > 1) {
189 throw std::runtime_error("Found more than one type in string: " +
190 statestring);
191 }
192 return QMStateType(search.str(0));
193 }
194
FromString(const std::string & statestring)195 void QMState::FromString(const std::string& statestring) {
196 std::string lower = boost::algorithm::to_lower_copy(statestring);
197 boost::trim(lower);
198 std::string rest;
199 if (boost::starts_with(lower, "n2")) {
200 transition_ = true;
201 rest = lower.substr(2);
202 } else if (boost::starts_with(lower, "groundstate to")) {
203 transition_ = true;
204 rest = lower.substr(14);
205 } else {
206 rest = lower;
207 transition_ = false;
208 }
209 boost::trim(rest);
210
211 type_ = DetermineType(rest);
212 if (type_ != QMStateType::Singlet && transition_ == true) {
213 throw std::runtime_error("Transition states only exist for singlets.");
214 }
215 if (type_ == QMStateType::Gstate) {
216 index_ = -1;
217 } else {
218 index_ = DetermineIndex(rest);
219 }
220 }
221
222 } // namespace xtp
223 } // namespace votca
224