source: src/Fragmentation/Exporters/SphericalPointDistribution.hpp@ 4492f1

Last change on this file since 4492f1 was 4492f1, checked in by Frederik Heber <heber@…>, 9 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.
  • Property mode set to 100644
File size: 8.2 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 {}
48
49 //!> typedef for the list of points
50 typedef std::list<Vector> Polygon_t;
51 //!> typedef for the list of points with integral weights
52 typedef std::list<std::pair<Vector, int> > WeightedPolygon_t;
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;
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 */
64 template <int N> Polygon_t get() const
65 {
66 ASSERT(0, "SphericalPointDistribution::get() - not specialized for "+toString(N)+".");
67 }
68
69 template <int N> adjacency_t getConnections()
70 {
71 ASSERT(0, "SphericalPointDistribution::getConnections() - not specialized for "+toString(N)+".");
72 }
73
74 /** Matches a given spherical distribution with another containing more
75 * points.
76 *
77 * This is a helper to determine points where to best insert saturation
78 * hydrogens.
79 *
80 * \param _polygon current occupied positions
81 * \param _newpolygon ideal distribution to match best with current occupied
82 * positions
83 * \return remaining vacant positions relative to \a _polygon
84 */
85 static Polygon_t matchSphericalPointDistributions(
86 const WeightedPolygon_t &_polygon,
87 Polygon_t &_newpolygon
88 );
89
90 //!> default radius of the spherical distribution
91 const double Bondlength;
92 //!> precalculated value for root of 3
93 static const double SQRT_3;
94 //!> threshold for L1 error below which matching is immediately acceptable
95 static const double L1THRESHOLD;
96 //!> threshold for L2 error below which matching is acceptable
97 static const double L2THRESHOLD;
98
99 //!> typedef for a full rotation specification consisting of axis and angle.
100 typedef std::pair<Vector, double> Rotation_t;
101
102 //!> typedef for a list of indices (of points in a polygon)
103 typedef std::list<unsigned int> IndexList_t;
104 //!> typedef enumerating possibly multiple points accumulated as one point
105 typedef std::list< IndexList_t > IndexTupleList_t;
106 //!> typedef for a vector of indices
107 typedef std::vector<unsigned int> IndexArray_t;
108 //!> typedef for a Vector of positions
109 typedef std::vector<Vector> VectorArray_t;
110 //!> typedef for a Vector of positions with weights
111 typedef std::vector< std::pair<Vector, int> > WeightedVectorArray_t;
112 //!> typedef for a vector of degrees (or integral weights)
113 typedef std::vector<unsigned int> WeightsArray_t;
114
115 //!> amplitude up to which deviations in checks of rotations are tolerated
116 static const double warn_amplitude;
117
118 struct PolygonWithIndices
119 {
120 //!> array with points
121 VectorArray_t polygon;
122 //!> list with indices for the above points, defining subset
123 IndexList_t indices;
124 };
125
126 static Vector calculateCenterOfMinimumDistance(
127 const SphericalPointDistribution::VectorArray_t &_positions,
128 const SphericalPointDistribution::IndexList_t &_indices);
129
130private:
131 //!> grant unit tests access to private parts
132 friend class SphericalPointDistributionTest;
133
134 static std::pair<double, double> calculateErrorOfMatching(
135 const VectorArray_t &_old,
136 const VectorArray_t &_new,
137 const IndexTupleList_t &_Matching);
138
139 static Polygon_t removeMatchingPoints(
140 const PolygonWithIndices &_points);
141
142 struct MatchingControlStructure {
143 bool foundflag;
144 double bestL2;
145 IndexTupleList_t bestmatching;
146 VectorArray_t oldpoints;
147 VectorArray_t newpoints;
148 WeightsArray_t weights;
149 };
150
151 static void recurseMatchings(
152 MatchingControlStructure &_MCS,
153 IndexTupleList_t &_matching,
154 IndexList_t _indices,
155 WeightsArray_t &_remainingweights,
156 WeightsArray_t::iterator _remainiter,
157 const unsigned int _matchingsize
158 );
159
160 static IndexList_t findBestMatching(
161 const WeightedPolygon_t &_polygon,
162 Polygon_t &_newpolygon
163 );
164
165 static IndexList_t joinPoints(
166 Polygon_t &_newpolygon,
167 const VectorArray_t &_newpoints,
168 const IndexTupleList_t &_bestmatching
169 );
170
171 static Rotation_t findPlaneAligningRotation(
172 const PolygonWithIndices &_referencepositions,
173 const PolygonWithIndices &_currentpositions
174 );
175
176 static Rotation_t findPointAligningRotation(
177 const PolygonWithIndices &remainingold,
178 const PolygonWithIndices &remainingnew);
179};
180
181// declare specializations
182
183template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<0>() const;
184template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<1>() const;
185template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<2>() const;
186template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<3>() const;
187template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<4>() const;
188template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<5>() const;
189template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<6>() const;
190template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<7>() const;
191template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<8>() const;
192template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<9>() const;
193template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<10>() const;
194template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<11>() const;
195template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<12>() const;
196template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<14>() const;
197
198template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<0>();
199template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<1>();
200template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<2>();
201template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<3>();
202template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<4>();
203template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<5>();
204template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<6>();
205template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<7>();
206template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<8>();
207template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<9>();
208template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<10>();
209template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<11>();
210template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<12>();
211template <> SphericalPointDistribution::adjacency_t SphericalPointDistribution::getConnections<14>();
212
213#endif /* SPHERICALPOINTDISTRIBUTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.