Codebase list votca-xtp / b08fa64d-b91e-48a0-b185-c4ba9579a74a/main src / libxtp / qmstate.cc
b08fa64d-b91e-48a0-b185-c4ba9579a74a/main

Tree @b08fa64d-b91e-48a0-b185-c4ba9579a74a/main (Download .tar.gz)

qmstate.cc @b08fa64d-b91e-48a0-b185-c4ba9579a74a/mainraw · history · blame

/*
 *            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