1#include "PAHGeometry.h" 
    3PAHGeometry::PAHGeometry() : _mass(0.0), _dimensions(3, {2.0, 0.0, 0.0}) {
 
    7PAHGeometry::PAHGeometry(
const std::vector<Atom> &atoms)
 
    8    : _atoms(atoms.cbegin(), atoms.cend()), _mass(0.0),
 
    9      _dimensions(3, {2.0, 0.0, 0.0}) {
 
   11  for (
const auto &atom : _atoms) {
 
   13    _mass += atom.getMass();
 
   17void PAHGeometry::diagonalize() {
 
   19  double x_com = 0, y_com = 0, z_com = 0, m_tot = 0;
 
   21  for (
const auto &atom : _atoms) {
 
   23    if (atom.getType() == 12 || atom.getType() == 26)
 
   26    x_com += atom.getMass() * atom.getX();
 
   27    y_com += atom.getMass() * atom.getY();
 
   28    z_com += atom.getMass() * atom.getZ();
 
   29    m_tot += atom.getMass();
 
   36  for (
auto &atom : _atoms) {
 
   38    atom.setX(atom.getX() - x_com);
 
   39    atom.setY(atom.getY() - y_com);
 
   40    atom.setZ(atom.getZ() - z_com);
 
   43  double I[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
 
   45  for (
const auto &atom : _atoms) {
 
   47    if (atom.getType() == 12 || atom.getType() == 26)
 
   50    I[0][0] += atom.getMass() *
 
   51               (atom.getY() * atom.getY() + atom.getZ() * atom.getZ());
 
   52    I[1][1] += atom.getMass() *
 
   53               (atom.getX() * atom.getX() + atom.getZ() * atom.getZ());
 
   54    I[2][2] += atom.getMass() *
 
   55               (atom.getX() * atom.getX() + atom.getY() * atom.getY());
 
   77  double v[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}},
 
   78         b[3] = {I[0][0], I[1][1], I[2][2]}, *d = b, f[3] = {0.0, 0.0, 0.0};
 
   82  double sm, tresh, g, h, t, theta, c, s, tau;
 
   84  for (
size_t run = 0; run < 50; run++) {
 
   86    sm = fabs(I[0][1]) + fabs(I[0][2]) + fabs(I[1][2]);
 
   92      tresh = 0.2 * sm / 9.0;
 
   96    for (
size_t ip = 0; ip < 2; ip++) {
 
   97      for (
size_t iq = ip + 1; iq < 3; iq++) {
 
   98        g = 100.0 * fabs(I[ip][iq]);
 
   99        if (run > 4 && fabs(d[ip]) + g == fabs(d[ip]) &&
 
  100            fabs(d[iq]) + g == fabs(d[iq]))
 
  102        else if (fabs(I[ip][iq]) > tresh) {
 
  104          if (fabs(h) + g == fabs(h))
 
  107            theta = 0.5 * h / I[ip][iq];
 
  108            t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
 
  113          c = 1.0 / sqrt(1.0 + t * t);
 
  123          for (
size_t j = 0; j <= ip - 1; j++) {
 
  126            I[j][ip] = g - s * (h + g * tau);
 
  127            I[j][iq] = h + s * (g - h * tau);
 
  130          for (
size_t j = ip + 1; j <= iq - 1; j++) {
 
  133            I[ip][j] = g - s * (h + g * tau);
 
  134            I[j][iq] = h + s * (g - h * tau);
 
  137          for (
size_t j = iq + 1; j < 3; j++) {
 
  140            I[ip][j] = g - s * (h + g * tau);
 
  141            I[iq][j] = h + s * (g - h * tau);
 
  144          for (
size_t j = 0; j < 3; j++) {
 
  147            v[j][ip] = g - s * (h + g * tau);
 
  148            v[j][iq] = h + s * (g - h * tau);
 
  155    for (
size_t ip = 0; ip < 3; ip++) {
 
  166  for (
size_t i = 0; i < 3; i++) {
 
  168    for (j = i + 1; j < 3; j++) {
 
  176      for (j = 0; j < 3; j++) {
 
  186  for (
auto &atom : _atoms) {
 
  188    x = atom.getX() * v[0][0] + atom.getY() * v[0][1] + atom.getZ() * v[0][2];
 
  189    y = atom.getX() * v[1][0] + atom.getY() * v[1][1] + atom.getZ() * v[1][2];
 
  190    z = atom.getX() * v[2][0] + atom.getY() * v[2][1] + atom.getZ() * v[2][2];
 
  198std::vector<std::vector<int>> &PAHGeometry::getBonds() {
 
  200  if (_bonds.size() > 0) {
 
  211  for (
const auto &atom1 : _atoms) {
 
  215    for (
const auto &atom2 : _atoms) {
 
  217      double d = sqrt(pow(atom1.getX() - atom2.getX(), 2) +
 
  218                      pow(atom1.getY() - atom2.getY(), 2));
 
  220      if (d > 0 && d < 1.6) {
 
  227    _bonds.push_back(ls);
 
  232  for (
auto &bond : _bonds) {
 
  234    for (
const auto &b : bond) {
 
  236      _bonds[b].erase(_bonds[b].begin());