source: src/Filling/Inserter/RandomInserter.cpp@ 70f2a1

Action_Thermostats Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps
Last change on this file since 70f2a1 was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

  • MemDebug clashes with various allocation operators that use a specific placement in memory. It is so far not possible to wrap new/delete fully. Hence, we stop this effort which so far has forced us to put ever more includes (with clashes) into MemDebug and thereby bloat compilation time.
  • MemDebug does not add that much usefulness which is not also provided by valgrind.
  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * RandomInserter.cpp
25 *
26 * Created on: Feb 21, 2012
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36//#include "CodePatterns/MemDebug.hpp"
37
38#include "RandomInserter.hpp"
39
40#include <algorithm>
41
42#include "Atom/atom.hpp"
43#include "CodePatterns/Log.hpp"
44#include "LinearAlgebra/RealSpaceMatrix.hpp"
45#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
46#include "RandomNumbers/RandomNumberGenerator.hpp"
47
48
49size_t RandomInserter::Max_Attempts = 10;
50
51/** Sets given 3x3 matrix to a random rotation matrix.
52 *
53 * @param a matrix to set
54 */
55inline void setRandomRotation(RealSpaceMatrix &a)
56{
57 double phi[NDIM];
58 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
59 const double rng_min = random.min();
60 const double rng_max = random.max();
61
62 for (int i=0;i<NDIM;i++) {
63 phi[i] = (random()/(rng_max-rng_min))*(2.*M_PI);
64 LOG(4, "DEBUG: Random angle is " << phi[i] << ".");
65 }
66
67 a.setRotation(phi);
68}
69
70/** Constructor for class RandomInserter.
71 *
72 * @param _MaxAtomComponent maximum component for random atom translations
73 * @param _MaxMoleculeComponent maximum component for random molecule translations
74 * @param _DoRandomRotation whether to do random rotations
75 */
76RandomInserter::RandomInserter(
77 const double _MaxAtomComponent,
78 const double _MaxMoleculeComponent,
79 const bool _DoRandomRotation) :
80 random(RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator()),
81 rng_min(random.min()),
82 rng_max(random.max()),
83 MaxAtomComponent(_MaxAtomComponent),
84 MaxMoleculeComponent(_MaxMoleculeComponent),
85 DoRandomRotation(_DoRandomRotation)
86{}
87
88/** Destructor for class RandomInserter.
89 *
90 */
91RandomInserter::~RandomInserter()
92{}
93
94/** Checks whether all atoms currently are inside the cluster's shape.
95 *
96 * @param cluster cluster to check
97 * @return true - all atoms are inside cluster's shape, false - else
98 */
99bool RandomInserter::AreClustersAtomsInside(ClusterInterface::Cluster_impl cluster) const
100{
101 ClusterInterface::atomIdSet atoms = cluster->getAtomIds();
102 bool status = true;
103
104 for (ClusterInterface::atomIdSet::const_iterator iter = atoms.begin();
105 iter != atoms.end();
106 ++iter)
107 status = status && cluster->isInside(*iter);
108
109 return status;
110}
111
112/** Perform the given random translations and rotations on a cluster.
113 *
114 * @param cluster cluster to translate and rotate
115 * @param Rotations random rotation matrix
116 * @param RandomAtomTranslations vector with random translation for each atom in cluster
117 * @param RandomMoleculeTranslation vector with random translation for cluster
118 * @param offset vector with offset for cluster
119 */
120void RandomInserter::doTranslation(
121 ClusterInterface::Cluster_impl cluster,
122 const RealSpaceMatrix &Rotations,
123 const std::vector<Vector> &RandomAtomTranslations,
124 const Vector &RandomMoleculeTranslation) const
125{
126 AtomIdSet atoms = cluster->getAtoms();
127
128 ASSERT( atoms.size() <= RandomAtomTranslations.size(),
129 "RandomInserter::doTranslation() - insufficient random atom translations given.");
130
131 cluster->transform(Rotations);
132 cluster->translate(RandomMoleculeTranslation);
133 AtomIdSet::iterator miter = atoms.begin();
134 std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
135 for(;miter != atoms.end(); ++miter, ++aiter)
136 (*miter)->setPosition((*miter)->getPosition() + *aiter);
137 ASSERT( aiter == RandomAtomTranslations.end(),
138 "RandomInserter::doTranslation() - there are more RandomAtomTranslations than atoms?");
139}
140
141/** Undos a given random translations and rotations on a cluster.
142 *
143 * @param cluster cluster to translate and rotate
144 * @param Rotations random rotation matrix
145 * @param RandomAtomTranslations vector with random translation for each atom in cluster
146 * @param RandomMoleculeTranslations vector with random translation for cluster
147 * @param offset vector with offset for cluster
148 */
149void RandomInserter::undoTranslation(
150 ClusterInterface::Cluster_impl cluster,
151 const RealSpaceMatrix &Rotations,
152 const std::vector<Vector> &RandomAtomTranslations,
153 const Vector &RandomMoleculeTranslation) const
154{
155 AtomIdSet atoms = cluster->getAtoms();
156 ASSERT( atoms.size() <= RandomAtomTranslations.size(),
157 "RandomInserter::doTranslation() - insufficient random atom translations given.");
158
159 // get inverse rotation
160 RealSpaceMatrix inverseRotations = Rotations.invert();
161
162 AtomIdSet::iterator miter = atoms.begin();
163 std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
164 for(;miter != atoms.end(); ++miter, ++aiter) {
165 (*miter)->setPosition((*miter)->getPosition() - *aiter);
166 }
167 ASSERT( aiter == RandomAtomTranslations.end(),
168 "RandomInserter::undoTranslation() - there are more RandomAtomTranslations than atoms?");
169 cluster->translate(zeroVec-RandomMoleculeTranslation);
170 cluster->transform(inverseRotations);
171}
172
173/** Creates a random vector
174 *
175 * @param range range of components, i.e. \f$ v[i] \in [0,range)\f$
176 * @param offset offset for each component
177 * @return \a range * rnd() + \a offset
178 */
179Vector RandomInserter::getRandomVector(const double range, const double offset) const
180{
181 Vector returnVector;
182 for (size_t i=0; i<NDIM; ++i)
183 returnVector[i] = range*(random()/((rng_max-rng_min)/2.)) + offset;
184 LOG(2, "DEBUG: Generated random vector is " << returnVector << ".");
185 return returnVector;
186}
187
188/** Inserter operator that randomly translates and rotates the Cluster.
189 *
190 * \note we assume that clusters are always cloned at origin.
191 *
192 * @param offset
193 * @return true - random translations and rotations did not violate bounding shape, false - else
194 */
195bool RandomInserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const
196{
197 // calculate center
198 AtomIdSet atoms = cluster->getAtoms();
199 Vector center;
200 center.Zero();
201 for(AtomIdSet::iterator miter = atoms.begin();miter != atoms.end(); ++miter)
202 center += (*miter)->getPosition();
203 center *= 1./atoms.size();
204
205 // shift cluster to center
206 cluster->translate(zeroVec-center);
207
208 size_t attempt = 0;
209 for (;attempt < Max_Attempts; ++attempt) {
210 // generate random rotation matrix
211 RealSpaceMatrix Rotations;
212 if (DoRandomRotation)
213 setRandomRotation(Rotations);
214 else
215 Rotations.setIdentity();
216
217 // generate random molecule translation vector
218 Vector RandomMoleculeTranslation(getRandomVector(MaxMoleculeComponent, -MaxMoleculeComponent));
219
220 // generate random atom translation vector
221 std::vector<Vector> RandomAtomTranslations(atoms.size(), zeroVec);
222 std::generate_n(RandomAtomTranslations.begin(), atoms.size(),
223 boost::bind(&RandomInserter::getRandomVector, boost::cref(this), MaxAtomComponent, -MaxAtomComponent));
224
225 // apply!
226// LOG(2, "DEBUG: cluster before doTranslation(): " << *cluster << ".");
227 doTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
228// LOG(2, "DEBUG: cluster after doTranslation(): " << *cluster << ".");
229
230 // ... and check
231 if (!AreClustersAtomsInside(cluster)) {
232 undoTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
233// LOG(2, "DEBUG: cluster after undoTranslation(): " << *cluster << ".");
234 } else {
235 break;
236 }
237 }
238
239 // and move to final position
240 cluster->translate(offset+center);
241
242 return attempt != Max_Attempts;
243}
Note: See TracBrowser for help on using the repository browser.