source: src/Filling/Inserter/RandomInserter.cpp@ 48ab414

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 48ab414 was 48ab414, checked in by Frederik Heber <heber@…>, 13 years ago

Implemented working RandomInserter.

  • we copy&paste most of the routines from boundary.cpp use in the filler functions there. This is to eventually remove these from boundary.cpp.
  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * RandomInserter.cpp
10 *
11 * Created on: Feb 21, 2012
12 * Author: heber
13 */
14
15
16// include config.h
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "CodePatterns/MemDebug.hpp"
22
23#include "RandomInserter.hpp"
24
25#include <algorithm>
26
27#include "Atom/atom.hpp"
28#include "CodePatterns/Log.hpp"
29#include "LinearAlgebra/RealSpaceMatrix.hpp"
30#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
31#include "RandomNumbers/RandomNumberGenerator.hpp"
32
33
34size_t RandomInserter::Max_Attempts = 10;
35
36/** Sets given 3x3 matrix to a random rotation matrix.
37 *
38 * @param a matrix to set
39 */
40inline void setRandomRotation(RealSpaceMatrix &a)
41{
42 double phi[NDIM];
43 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
44 const double rng_min = random.min();
45 const double rng_max = random.max();
46
47 for (int i=0;i<NDIM;i++) {
48 phi[i] = (random()/(rng_max-rng_min))*(2.*M_PI);
49 LOG(4, "DEBUG: Random angle is " << phi[i] << ".");
50 }
51
52 a.setRotation(phi);
53}
54
55/** Constructor for class RandomInserter.
56 *
57 * @param _MaxAtomComponent maximum component for random atom translations
58 * @param _MaxMoleculeComponent maximum component for random molecule translations
59 * @param _DoRandomRotation whether to do random rotations
60 */
61RandomInserter::RandomInserter(
62 const double _MaxAtomComponent,
63 const double _MaxMoleculeComponent,
64 const bool _DoRandomRotation) :
65 random(RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator()),
66 rng_min(random.min()),
67 rng_max(random.max()),
68 MaxAtomComponent(_MaxAtomComponent),
69 MaxMoleculeComponent(_MaxMoleculeComponent),
70 DoRandomRotation(_DoRandomRotation)
71{}
72
73/** Destructor for class RandomInserter.
74 *
75 */
76RandomInserter::~RandomInserter()
77{}
78
79/** Checks whether all atoms currently are inside the cluster's shape.
80 *
81 * @param cluster cluster to check
82 * @return true - all atoms are inside cluster's shape, false - else
83 */
84bool RandomInserter::AreClustersAtomsInside(ClusterInterface::Cluster_impl cluster) const
85{
86 ClusterInterface::atomIdSet atoms = cluster->getAtomIds();
87 bool status = true;
88
89 for (ClusterInterface::atomIdSet::const_iterator iter = atoms.begin();
90 iter != atoms.end();
91 ++iter)
92 status = status && cluster->isInside(*iter);
93
94 return status;
95}
96
97/** Perform the given random translations and rotations on a cluster.
98 *
99 * @param cluster cluster to translate and rotate
100 * @param Rotations random rotation matrix
101 * @param RandomAtomTranslations vector with random translation for each atom in cluster
102 * @param RandomMoleculeTranslation vector with random translation for cluster
103 * @param offset vector with offset for cluster
104 */
105void RandomInserter::doTranslation(
106 ClusterInterface::Cluster_impl cluster,
107 const RealSpaceMatrix &Rotations,
108 const std::vector<Vector> &RandomAtomTranslations,
109 const Vector &RandomMoleculeTranslation) const
110{
111 AtomIdSet atoms = cluster->getAtoms();
112
113 ASSERT( atoms.size() <= RandomAtomTranslations.size(),
114 "RandomInserter::doTranslation() - insufficient random atom translations given.");
115
116 cluster->transform(Rotations);
117 cluster->translate(RandomMoleculeTranslation);
118 AtomIdSet::iterator miter = atoms.begin();
119 std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
120 for(;miter != atoms.end(); ++miter, ++aiter)
121 (*miter)->setPosition((*miter)->getPosition() + *aiter);
122}
123
124/** Undos a given random translations and rotations on a cluster.
125 *
126 * @param cluster cluster to translate and rotate
127 * @param Rotations random rotation matrix
128 * @param RandomAtomTranslations vector with random translation for each atom in cluster
129 * @param RandomMoleculeTranslations vector with random translation for cluster
130 * @param offset vector with offset for cluster
131 */
132void RandomInserter::undoTranslation(
133 ClusterInterface::Cluster_impl cluster,
134 const RealSpaceMatrix &Rotations,
135 const std::vector<Vector> &RandomAtomTranslations,
136 const Vector &RandomMoleculeTranslation) const
137{
138 AtomIdSet atoms = cluster->getAtoms();
139 ASSERT( atoms.size() <= RandomAtomTranslations.size(),
140 "RandomInserter::doTranslation() - insufficient random atom translations given.");
141
142 // get inverse rotation
143 RealSpaceMatrix inverseRotations = Rotations.invert();
144
145 AtomIdSet::iterator miter = atoms.begin();
146 std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
147 for(;miter != atoms.end(); ++miter, ++aiter) {
148 (*miter)->setPosition((*miter)->getPosition() - *aiter);
149 }
150 cluster->translate(zeroVec-RandomMoleculeTranslation);
151 cluster->transform(inverseRotations);
152}
153
154/** Creates a random vector
155 *
156 * @param range range of components, i.e. \f$ v[i] \in [0,range)\f$
157 * @param offset offset for each component
158 * @return \a range * rnd() + \a offset
159 */
160Vector RandomInserter::getRandomVector(const double range, const double offset) const
161{
162 Vector returnVector;
163 for (size_t i=0; i<NDIM; ++i)
164 returnVector[i] = (range*random()/((rng_max-rng_min)/2.)) + offset;
165 return returnVector;
166}
167
168/** Inserter operator that randomly translates and rotates the Cluster.
169 *
170 * \note we assume that clusters are always cloned at origin.
171 *
172 * @param offset
173 * @return true - random translations and rotations did not violate bounding shape, false - else
174 */
175bool RandomInserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const
176{
177 // calculate center
178 AtomIdSet atoms = cluster->getAtoms();
179 Vector center;
180 center.Zero();
181 for(AtomIdSet::iterator miter = atoms.begin();miter != atoms.end(); ++miter)
182 center += (*miter)->getPosition();
183 center *= 1./atoms.size();
184
185 // shift cluster to center
186 cluster->translate(zeroVec-center);
187
188 size_t attempt = 0;
189 for (;attempt < Max_Attempts; ++attempt) {
190 // generate random rotation matrix
191 RealSpaceMatrix Rotations;
192 if (DoRandomRotation)
193 setRandomRotation(Rotations);
194 else
195 Rotations.setIdentity();
196
197 // generate random molecule translation vector
198 Vector RandomMoleculeTranslation(getRandomVector(MaxMoleculeComponent, -MaxMoleculeComponent));
199
200 // generate random atom translation vector
201 std::vector<Vector> RandomAtomTranslations(atoms.size(), zeroVec);
202 std::generate_n(RandomAtomTranslations.begin(), atoms.size(),
203 boost::bind(&RandomInserter::getRandomVector, boost::cref(this), MaxAtomComponent, -MaxAtomComponent));
204
205 // apply!
206 doTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
207
208 // ... and check
209 if (!AreClustersAtomsInside(cluster)) {
210 undoTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
211 } else {
212 break;
213 }
214 }
215
216 // and move to final position
217 cluster->translate(offset+center);
218
219 return attempt != Max_Attempts;
220}
Note: See TracBrowser for help on using the repository browser.