source: src/Fragmentation/Exporters/SphericalPointDistribution.hpp@ fc38cb

Candidate_v1.7.0 stable
Last change on this file since fc38cb was 2390e6, checked in by Frederik Heber <frederik.heber@…>, 5 years ago

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.
  • Property mode set to 100644
File size: 9.1 KB
RevLine 
[e895f7]1/*
2 * SphericalPointDistribution.hpp
3 *
4 * Created on: May 29, 2014
5 * Author: heber
6 */
7
8
9#ifndef SPHERICALPOINTDISTRIBUTION_HPP_
10#define SPHERICALPOINTDISTRIBUTION_HPP_
11
12// include config.h
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17#include "CodePatterns/Assert.hpp"
18
19#include <cmath>
20#include <list>
[6393ff]21#include <map>
22#include <set>
23#include <vector>
[e895f7]24
25#include "LinearAlgebra/Vector.hpp"
26
[450adf]27class SphericalPointDistributionTest;
28
[e895f7]29/** contains getters for the VSEPR model for specific number of electrons.
30 *
31 * This struct contains specialized functions returning a list of Vectors
32 * (points in space) to match the VSEPR model for the given number of electrons.
33 *
34 * This is implemented via template specialization of the function get().
35 *
36 * These specializations are taken from the python script \b CreateVspeShapes.py
37 * by Christian Neuen, 07th May 2009.
38 */
39struct SphericalPointDistribution
40{
41 /** Cstor for SphericalPointDistribution, allows setting radius of sphere
42 *
43 * \param _BondLength desired radius of sphere
44 */
45 SphericalPointDistribution(const double _Bondlength = 1.) :
[0c42f2]46 Bondlength(_Bondlength)
[e895f7]47 {}
48
49 //!> typedef for the list of points
50 typedef std::list<Vector> Polygon_t;
[2199c2]51 //!> typedef for the list of points with integral weights
52 typedef std::list<std::pair<Vector, int> > WeightedPolygon_t;
[6393ff]53 //!> typedef for a sorted list of indices
54 typedef std::set<unsigned int> IndexSet_t;
55 //!> typedef for the adjacency list of a polygon
56 typedef std::map<unsigned int, IndexSet_t > adjacency_t;
[e895f7]57
58 /** General getter function for the distribution of points on the surface.
59 *
60 * \warn this function needs to be specialized!
61 *
62 * \return Polygon_t with points on the surface centered at (0,0,0)
63 */
[0c42f2]64 template <int N> Polygon_t get() const
[e895f7]65 {
66 ASSERT(0, "SphericalPointDistribution::get() - not specialized for "+toString(N)+".");
[0c42f2]67 return Polygon_t();
[e895f7]68 }
69
[6393ff]70 template <int N> adjacency_t getConnections()
71 {
72 ASSERT(0, "SphericalPointDistribution::getConnections() - not specialized for "+toString(N)+".");
73 return Polygon_t();
74 }
75
[3dadd5]76 /** Initializes the polygon with the given \a _NumberOfPoints.
77 *
78 * \param _NumberOfPoints number of points
79 */
80 Polygon_t getSimplePolygon(const int _NumberOfPoints) const;
81
[fe90ab]82 /** Returns vacant spots to fill to get a complete spherical point distribution from
83 * given points \a _polygon, containing then \a _N in total.
[64cafb2]84 *
85 * This is a helper to determine points where to best insert saturation
86 * hydrogens.
[e895f7]87 *
[fe90ab]88 * \param _polygon already filled places to match
[2390e6]89 * \param _num_spots number of nodes in the polyhedra (e.g., number of orbitals in outer shell)
90 * \param _num_spots_available nodes available (e.g., number of orbitals not fully occupied)
[e895f7]91 */
[2390e6]92 Polygon_t getRemainingPoints(
93 const WeightedPolygon_t &_polygon,
94 const int _num_spots,
95 const int _num_spots_available);
[64cafb2]96
[e895f7]97 //!> default radius of the spherical distribution
98 const double Bondlength;
99 //!> precalculated value for root of 3
[0c42f2]100 static const double SQRT_3;
[653cea]101 //!> threshold for L1 error below which matching is immediately acceptable
102 static const double L1THRESHOLD;
103 //!> threshold for L2 error below which matching is acceptable
104 static const double L2THRESHOLD;
[b67d89]105
[450adf]106 //!> typedef for a full rotation specification consisting of axis and angle.
[b67d89]107 typedef std::pair<Vector, double> Rotation_t;
108
[450adf]109 //!> typedef for a list of indices (of points in a polygon)
[b67d89]110 typedef std::list<unsigned int> IndexList_t;
[450adf]111 //!> typedef enumerating possibly multiple points accumulated as one point
112 typedef std::list< IndexList_t > IndexTupleList_t;
113 //!> typedef for a vector of indices
[b67d89]114 typedef std::vector<unsigned int> IndexArray_t;
[450adf]115 //!> typedef for a Vector of positions
[b67d89]116 typedef std::vector<Vector> VectorArray_t;
[450adf]117 //!> typedef for a Vector of positions with weights
118 typedef std::vector< std::pair<Vector, int> > WeightedVectorArray_t;
[653cea]119 //!> typedef for a vector of degrees (or integral weights)
120 typedef std::vector<unsigned int> WeightsArray_t;
[b67d89]121
122 //!> amplitude up to which deviations in checks of rotations are tolerated
123 static const double warn_amplitude;
124
[0983e6]125 struct PolygonWithIndices
126 {
127 //!> array with points
128 VectorArray_t polygon;
129 //!> list with indices for the above points, defining subset
130 IndexList_t indices;
131 };
132
[3678eb]133 static Vector calculateCenterOfMinimumDistance(
134 const SphericalPointDistribution::VectorArray_t &_positions,
135 const SphericalPointDistribution::IndexList_t &_indices);
136
[fe90ab]137private:
138 //!> points for the ideal distribution
139 Polygon_t points;
140 //!> connection information between these ideal points
141 adjacency_t adjacency;
142
143 /** Initialize inner status (points and adjacency) to desired number of
144 * points.
145 *
146 * \param _N number of points
147 */
148 void initSelf(const int _N);
149
[b67d89]150private:
[450adf]151 //!> grant unit tests access to private parts
152 friend class SphericalPointDistributionTest;
153
[b67d89]154 static std::pair<double, double> calculateErrorOfMatching(
[653cea]155 const VectorArray_t &_old,
156 const VectorArray_t &_new,
157 const IndexTupleList_t &_Matching);
[b67d89]158
159 static Polygon_t removeMatchingPoints(
[0983e6]160 const PolygonWithIndices &_points);
[b67d89]161
162 struct MatchingControlStructure {
[fe90ab]163 MatchingControlStructure(
164 const adjacency_t &_adjacency,
165 const VectorArray_t &_oldpoints,
166 const VectorArray_t &_newpoints,
167 const WeightsArray_t &_weights
168 );
[b67d89]169 bool foundflag;
170 double bestL2;
[fe90ab]171 const adjacency_t &adjacency;
172 const VectorArray_t oldpoints;
173 const VectorArray_t newpoints;
174 const WeightsArray_t weights;
[653cea]175 IndexTupleList_t bestmatching;
[b67d89]176 };
177
178 static void recurseMatchings(
179 MatchingControlStructure &_MCS,
[653cea]180 IndexTupleList_t &_matching,
[b67d89]181 IndexList_t _indices,
[653cea]182 WeightsArray_t &_remainingweights,
183 WeightsArray_t::iterator _remainiter,
184 const unsigned int _matchingsize
185 );
[b67d89]186
[fe90ab]187 IndexList_t findBestMatching(const WeightedPolygon_t &_polygon);
[450adf]188
189 static IndexList_t joinPoints(
190 Polygon_t &_newpolygon,
191 const VectorArray_t &_newpoints,
192 const IndexTupleList_t &_bestmatching
[b67d89]193 );
194
195 static Rotation_t findPlaneAligningRotation(
[0983e6]196 const PolygonWithIndices &_referencepositions,
197 const PolygonWithIndices &_currentpositions
[b67d89]198 );
199
200 static Rotation_t findPointAligningRotation(
[0983e6]201 const PolygonWithIndices &remainingold,
202 const PolygonWithIndices &remainingnew);
[e895f7]203};
204
[f54930]205// declare specializations
206
[0c42f2]207template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<0>() const;
208template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<1>() const;
209template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<2>() const;
210template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<3>() const;
211template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<4>() const;
212template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<5>() const;
213template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<6>() const;
214template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<7>() const;
215template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<8>() const;
216template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<9>() const;
217template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<10>() const;
218template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<11>() const;
219template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<12>() const;
220template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<14>() const;
[e895f7]221
[6393ff]222template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<0>();
223template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<1>();
224template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<2>();
225template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<3>();
226template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<4>();
227template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<5>();
228template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<6>();
229template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<7>();
230template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<8>();
231template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<9>();
232template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<10>();
233template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<11>();
234template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<12>();
235template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<14>();
236
[e895f7]237#endif /* SPHERICALPOINTDISTRIBUTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.