/*
* Copyright 2009-2018 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 <votca/xtp/qmstate.h>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <regex>
#include <boost/lexical_cast.hpp>
#include <iostream>
namespace votca {
namespace xtp {
int QMStateType::ToSegIndex()const {
if (_type == QMStateType::Singlet) {
return 2;
} else if (_type == QMStateType::Triplet) {
return 3;
} else if (_type == QMStateType::Hole) {
return 1;
} else if (_type == QMStateType::Electron) {
return -1;
} else if (_type == QMStateType::Gstate) {
return 0;
} else {
throw std::runtime_error("For state " + this->ToString() + " no conversion to segment exists");
}
return 0;
}
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{
int 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{
int 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;
}
int 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){
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);
}
int index=boost::lexical_cast<int>(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 && _type!=QMStateType::Electron && _type!=QMStateType::Hole){
_index=DetermineIndex(rest);
}else{
_index=-1;
}
}
}
}