Ignore:
Timestamp:
Apr 28, 2021, 10:02:49 PM (5 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
Candidate_v1.7.0, stable
Children:
e0e77e
Parents:
87c1cc
git-author:
Frederik Heber <frederik.heber@…> (04/17/21 09:41:33)
git-committer:
Frederik Heber <frederik.heber@…> (04/28/21 22:02:49)
Message:

SaturateAction may use outer shell information.

  • when considering the outer shell, then we look at both occupied and unoccupied orbitals. The ideal polygon will be created for the number of all orbitals, but only the unoccupied will be allowed to be taken by either present bonds or saturation hydrogens.
  • SphericalPointDistribution allows to occupy less than present points.
  • I have tested this manually by adding oxygen, saturation, adding carbon, saturating again, then turning oxygen into nitrogen and saturating. Results were always exactly as hoped for.
  • DOCU: Added note to action in userguide.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/AtomAction/SaturateAction.cpp

    r87c1cc r2390e6  
    8686    const BondList& ListOfBonds = _atom->getListOfBonds();
    8787    SphericalPointDistribution PointSphere(typical_distance);
     88    int num_orbitals_outer_shell;
     89    int num_unoccupied_orbitals;
     90    if (params.useOuterShell.get()) {
     91      /*
     92       * Number of valence electrons (getValence()) + number of unoccupied
     93       * orbitals (getNoValenceOrbitals()) is the number of electrons able
     94       * to fit into the outer shell. Hence, half the number gives the number
     95       * of orbitals in the outer shell
     96       */
     97      num_orbitals_outer_shell =
     98          (((int)_atom->getType()->getValence())+_atom->getType()->getNoValenceOrbitals())/2;
     99      num_unoccupied_orbitals = _atom->getType()->getNoValenceOrbitals();
     100    } else {
     101      /**
     102       * Here, same number of points on the polyhedra and available ones.
     103       */
     104      num_orbitals_outer_shell = num_unoccupied_orbitals = _atom->getType()->getNoValenceOrbitals();
     105    }
    88106    if (ListOfBonds.size() == 0) {
    89       vacant_positions = PointSphere.getSimplePolygon(_atom->getType()->getNoValenceOrbitals());
     107      vacant_positions = PointSphere.getSimplePolygon(num_orbitals_outer_shell);
     108
     109      // if less available then present in the ideal polygon, remove some
     110      if (num_unoccupied_orbitals < vacant_positions.size())
     111        vacant_positions.resize(num_unoccupied_orbitals);
     112
    90113      LOG(3, "DEBUG: Using ideal positions as " << vacant_positions);
    91114    } else {
    92       // get ideal polygon and currently occupied positions
    93       const SphericalPointDistribution::Polygon_t ideal_positions =
    94           PointSphere.getSimplePolygon(_atom->getType()->getNoValenceOrbitals());
    95       LOG(3, "DEBUG: ideal positions are " << ideal_positions);
    96115      SphericalPointDistribution::WeightedPolygon_t current_positions;
    97116      for (BondList::const_iterator bonditer = ListOfBonds.begin();
     
    104123      LOG(3, "DEBUG: current occupied positions are " << current_positions);
    105124
     125      // get ideal polygon and currently occupied positions
     126      const SphericalPointDistribution::Polygon_t ideal_positions =
     127          PointSphere.getSimplePolygon(num_orbitals_outer_shell);
     128      LOG(3, "DEBUG: ideal positions are " << ideal_positions);
     129
    106130      // find the best matching rotated polygon
    107131      vacant_positions = PointSphere.getRemainingPoints(
    108132          current_positions,
    109           _atom->getType()->getNoValenceOrbitals());
     133          num_orbitals_outer_shell,
     134          num_unoccupied_orbitals);
    110135      LOG(3, "DEBUG: Resulting vacant positions are " << vacant_positions);
    111136
Note: See TracChangeset for help on using the changeset viewer.