/*
* Copyright 2009-2019 The VOTCA Development Team
* (http://www.votca.org)
*
* Licensed under the Apache License, Version 2.0 (the "License")
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <regex>
#include <votca/xtp/qmstate.h>
namespace votca {
namespace xtp {
std::string QMStateType::ToString() const {
std::string identifier = "";
switch (_type) {
case QMStateType::Singlet:
identifier = "s";
break;
case QMStateType::Triplet:
identifier = "t";
break;
case QMStateType::PQPstate:
identifier = "pqp";
break;
case QMStateType::DQPstate:
identifier = "dqp";
break;
case QMStateType::KSstate:
identifier = "ks";
break;
case QMStateType::Gstate:
identifier = "n";
break;
case QMStateType::Hole:
identifier = "h";
break;
case QMStateType::Electron:
identifier = "e";
break;
}
return identifier;
}
std::string QMStateType::ToLongString() const {
std::string identifier = "";
switch (_type) {
case QMStateType::Singlet:
identifier = "singlet";
break;
case QMStateType::Triplet:
identifier = "triplet";
break;
case QMStateType::PQPstate:
identifier = "pert-qparticle";
break;
case QMStateType::DQPstate:
identifier = "diag-qparticle";
break;
case QMStateType::KSstate:
identifier = "Kohn-Sham-orbital";
break;
case QMStateType::Gstate:
identifier = "groundstate";
break;
case QMStateType::Hole:
identifier = "hole";
break;
case QMStateType::Electron:
identifier = "electron";
break;
}
return identifier;
}
void QMStateType::FromString(const std::string& statetypestring) {
std::string lower = boost::algorithm::to_lower_copy(statetypestring);
boost::trim(lower);
if (lower == "s" || lower == "singlet") {
_type = QMStateType::Singlet;
} else if (lower == "t" || lower == "triplet") {
_type = QMStateType::Triplet;
} else if (lower == "pqp" || lower == "pert-qparticle") {
_type = QMStateType::PQPstate;
} else if (lower == "dqp" || lower == "diag-qparticle" || lower == "qpdiag") {
_type = QMStateType::DQPstate;
} else if (lower == "ks" || lower == "kohn-sham-orbital") {
_type = QMStateType::KSstate;
} else if (lower == "n" || lower == "groundstate" || lower == "gs") {
_type = QMStateType::Gstate;
} else if (lower == "h" || lower == "hole") {
_type = QMStateType::Hole;
} else if (lower == "e" || lower == "electron") {
_type = QMStateType::Electron;
} else {
throw std::runtime_error("Statetype:" + statetypestring +
" not recognized");
}
}
std::string QMState::ToLongString() const {
Index index = _index;
if (_type == QMStateType::Singlet || _type == QMStateType::Triplet) {
index++;
} else if (_type == QMStateType::Gstate || _type == QMStateType::Electron ||
_type == QMStateType::Hole) {
return _type.ToLongString();
}
std::string result =
_type.ToLongString() + (boost::format(" %i") % index).str();
if (_transition) {
result = "Groundstate to " + result;
}
return result;
}
std::string QMState::ToString() const {
Index index = _index;
if (_type == QMStateType::Singlet || _type == QMStateType::Triplet) {
index++;
} else if (_type == QMStateType::Gstate || _type == QMStateType::Electron ||
_type == QMStateType::Hole) {
return _type.ToString();
}
std::string result = _type.ToString() + (boost::format("%i") % index).str();
if (_transition) {
result = "n2" + result;
}
return result;
}
Index QMState::DetermineIndex(const std::string& statestring) {
std::smatch search;
std::regex reg("[0-9]+");
bool found_integer = std::regex_search(statestring, search, reg);
if (!found_integer) {
if (_type == QMStateType::Hole || _type == QMStateType::Electron) {
return 0;
}
throw std::runtime_error("Found no index in string: " + statestring);
}
if (search.size() > 1) {
throw std::runtime_error("Found more than 1 index in string: " +
statestring);
}
Index index = boost::lexical_cast<Index>(search.str(0));
if (_type.isExciton() || _type == QMStateType::Electron ||
_type == QMStateType::Hole) {
index--;
}
return index;
}
QMStateType QMState::DetermineType(const std::string& statestring) {
std::regex reg("[^0-9]+");
std::smatch search;
bool found_typestring = std::regex_search(statestring, search, reg);
if (!found_typestring) {
throw std::runtime_error("Found no type in string: " + statestring);
}
if (search.size() > 1) {
throw std::runtime_error("Found more than one type in string: " +
statestring);
}
QMStateType type;
type.FromString(search.str(0));
return type;
}
void QMState::FromString(const std::string& statestring) {
std::string lower = boost::algorithm::to_lower_copy(statestring);
boost::trim(lower);
std::string rest;
if (boost::starts_with(lower, "n2")) {
_transition = true;
rest = lower.substr(2);
} else if (boost::starts_with(lower, "groundstate to")) {
_transition = true;
rest = lower.substr(14);
} else {
rest = lower;
_transition = false;
}
boost::trim(rest);
_type = DetermineType(rest);
if (_type != QMStateType::Singlet && _transition == true) {
throw std::runtime_error("Transition states only exist for singlets.");
}
if (_type == QMStateType::Gstate) {
_index = -1;
} else {
_index = DetermineIndex(rest);
}
}
} // namespace xtp
} // namespace votca