source: src/Fragmentation/Exporters/SphericalPointDistribution.hpp@ 42c742

Last change on this file since 42c742 was 42c742, checked in by Frederik Heber <heber@…>, 11 years ago

Added getConnections() to SphericalPointDistribution.

  • we use tesselation in order to extract the connection information between nearest neighboring points from the BoundaryLines of the tesselation. The triangles are ideal as they assure that no point lies within a triangle, hence all these points may be safely combined.
  • functions reside in extra module as with get().
  • added extensive unit tests.
  • TESTS: Removed XFAIL from SphericalPointDistributionUnitTest.
  • Property mode set to 100644
File size: 8.6 KB
Line 
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>
21#include <map>
22#include <set>
23#include <vector>
24
25#include "LinearAlgebra/Vector.hpp"
26
27class SphericalPointDistributionTest;
28
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.) :
46 Bondlength(_Bondlength),
47 SQRT_3(sqrt(3.0))
48 {}
49
50 //!> typedef for the list of points
51 typedef std::list<Vector> Polygon_t;
52 //!> typedef for the list of points with integral weights
53 typedef std::list<std::pair<Vector, int> > WeightedPolygon_t;
54 //!> typedef for a sorted list of indices
55 typedef std::set<unsigned int> IndexSet_t;
56 //!> typedef for the adjacency list of a polygon
57 typedef std::map<unsigned int, IndexSet_t > adjacency_t;
58
59 /** General getter function for the distribution of points on the surface.
60 *
61 * \warn this function needs to be specialized!
62 *
63 * \return Polygon_t with points on the surface centered at (0,0,0)
64 */
65 template <int N> Polygon_t get()
66 {
67 ASSERT(0, "SphericalPointDistribution::get() - not specialized for "+toString(N)+".");
68 }
69
70 template <int N> adjacency_t getConnections()
71 {
72 ASSERT(0, "SphericalPointDistribution::getConnections() - not specialized for "+toString(N)+".");
73 }
74
75 /** Matches a given spherical distribution with another containing more
76 * points.
77 *
78 * The idea is to produce a matching from all points in \a _polygon to those
79 * in \a _newpolygon in such a way that their distance difference is minimal.
80 * As we just look at numbers of points determined by valency, i.e.
81 * independent of the number of atoms, we simply go through each of the possible
82 * mappings. We stop when the L1 error is below a certain \a threshold,
83 * otherwise we pick the matching with the lowest L2 error.
84 *
85 * This is a helper to determine points where to best insert saturation
86 * hydrogens.
87 *
88 * \param _polygon current occupied positions
89 * \param _newpolygon ideal distribution to match best with current occupied
90 * positions
91 * \return remaining vacant positions relative to \a _polygon
92 */
93 static Polygon_t matchSphericalPointDistributions(
94 const WeightedPolygon_t &_polygon,
95 Polygon_t &_newpolygon
96 );
97
98 //!> default radius of the spherical distribution
99 const double Bondlength;
100 //!> precalculated value for root of 3
101 const double SQRT_3;
102 //!> threshold for L1 error below which matching is immediately acceptable
103 static const double L1THRESHOLD;
104 //!> threshold for L2 error below which matching is acceptable
105 static const double L2THRESHOLD;
106
107 //!> typedef for a full rotation specification consisting of axis and angle.
108 typedef std::pair<Vector, double> Rotation_t;
109
110 //!> typedef for a list of indices (of points in a polygon)
111 typedef std::list<unsigned int> IndexList_t;
112 //!> typedef enumerating possibly multiple points accumulated as one point
113 typedef std::list< IndexList_t > IndexTupleList_t;
114 //!> typedef for a vector of indices
115 typedef std::vector<unsigned int> IndexArray_t;
116 //!> typedef for a Vector of positions
117 typedef std::vector<Vector> VectorArray_t;
118 //!> typedef for a Vector of positions with weights
119 typedef std::vector< std::pair<Vector, int> > WeightedVectorArray_t;
120 //!> typedef for a vector of degrees (or integral weights)
121 typedef std::vector<unsigned int> WeightsArray_t;
122
123 //!> amplitude up to which deviations in checks of rotations are tolerated
124 static const double warn_amplitude;
125
126 struct PolygonWithIndices
127 {
128 //!> array with points
129 VectorArray_t polygon;
130 //!> list with indices for the above points, defining subset
131 IndexList_t indices;
132 };
133
134 static Vector calculateCenterOfMinimumDistance(
135 const SphericalPointDistribution::VectorArray_t &_positions,
136 const SphericalPointDistribution::IndexList_t &_indices);
137
138private:
139 //!> grant unit tests access to private parts
140 friend class SphericalPointDistributionTest;
141
142 static std::pair<double, double> calculateErrorOfMatching(
143 const VectorArray_t &_old,
144 const VectorArray_t &_new,
145 const IndexTupleList_t &_Matching);
146
147 static Polygon_t removeMatchingPoints(
148 const PolygonWithIndices &_points);
149
150 struct MatchingControlStructure {
151 bool foundflag;
152 double bestL2;
153 IndexTupleList_t bestmatching;
154 VectorArray_t oldpoints;
155 VectorArray_t newpoints;
156 WeightsArray_t weights;
157 };
158
159 static void recurseMatchings(
160 MatchingControlStructure &_MCS,
161 IndexTupleList_t &_matching,
162 IndexList_t _indices,
163 WeightsArray_t &_remainingweights,
164 WeightsArray_t::iterator _remainiter,
165 const unsigned int _matchingsize
166 );
167
168 static IndexList_t findBestMatching(
169 const WeightedPolygon_t &_polygon,
170 Polygon_t &_newpolygon
171 );
172
173 static IndexList_t joinPoints(
174 Polygon_t &_newpolygon,
175 const VectorArray_t &_newpoints,
176 const IndexTupleList_t &_bestmatching
177 );
178
179 static Rotation_t findPlaneAligningRotation(
180 const PolygonWithIndices &_referencepositions,
181 const PolygonWithIndices &_currentpositions
182 );
183
184 static Rotation_t findPointAligningRotation(
185 const PolygonWithIndices &remainingold,
186 const PolygonWithIndices &remainingnew);
187};
188
189// declare specializations
190
191template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<0>();
192template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<1>();
193template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<2>();
194template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<3>();
195template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<4>();
196template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<5>();
197template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<6>();
198template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<7>();
199template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<8>();
200template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<9>();
201template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<10>();
202template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<11>();
203template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<12>();
204template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<14>();
205
206template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<0>();
207template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<1>();
208template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<2>();
209template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<3>();
210template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<4>();
211template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<5>();
212template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<6>();
213template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<7>();
214template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<8>();
215template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<9>();
216template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<10>();
217template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<11>();
218template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<12>();
219template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<14>();
220
221#endif /* SPHERICALPOINTDISTRIBUTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.