source: src/LinkedCell/LinkedCell_Controller.cpp@ 029870

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 029870 was fe8253, checked in by Frederik Heber <heber@…>, 13 years ago

Added first reasonable heuristic, and added required implementation for Controller.

  • LinkedCell_Controller::getBestModel() nows contains some more advanced heuristics.
  • extended unit test on all of the added parts.
  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2011 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * LinkedCell_Controller.cpp
10 *
11 * Created on: Nov 15, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include "Box.hpp"
23#include "CodePatterns/Assert.hpp"
24#include "CodePatterns/Range.hpp"
25#include "LinkedCell_Controller.hpp"
26#include "LinkedCell_Model.hpp"
27#include "LinkedCell_View.hpp"
28
29
30using namespace LinkedCell;
31
32double LinkedCell_Controller::lower_threshold = 1.;
33double LinkedCell_Controller::upper_threshold = 20.;
34
35/** Constructor of class LinkedCell_Controller.
36 *
37 */
38LinkedCell_Controller::LinkedCell_Controller(const Box &_domain) :
39 domain(_domain)
40{
41 /// Check that upper_threshold fits within half the box.
42 Vector diagonal(1.,1.,1.);
43 diagonal.Scale(upper_threshold);
44 Vector diagonal_transformed = domain.getMinv() * diagonal;
45 double max_factor = 1.;
46 for (size_t i=0; i<NDIM; ++i)
47 if (diagonal_transformed.at(i) > 1./max_factor)
48 max_factor = 1./diagonal_transformed.at(i);
49 upper_threshold *= max_factor;
50
51 /// Check that lower_threshold is still lower, if not set to half times upper_threshold.
52 if (lower_threshold > upper_threshold)
53 lower_threshold = 0.5*upper_threshold;
54}
55
56/** Destructor of class LinkedCell_Controller.
57 *
58 * Here, we free all LinkedCell_Model instances again.
59 *
60 */
61LinkedCell_Controller::~LinkedCell_Controller()
62{
63 /// we free all LinkedCell_Model instances again.
64 for(MapEdgelengthModel::iterator iter = ModelsMap.begin();
65 !ModelsMap.empty(); iter = ModelsMap.begin()) {
66 delete iter->second;
67 ModelsMap.erase(iter);
68 }
69}
70
71/** Internal function to obtain the range within which an model is suitable.
72 *
73 * \note We use statics lower_threshold and upper_threshold as min and max
74 * boundaries.
75 *
76 * @param distance desired egde length
77 * @return range within which model edge length is acceptable
78 */
79const range<double> LinkedCell_Controller::getHeuristicRange(const double distance) const
80{
81 const double lower = 0.5*distance < lower_threshold ? lower_threshold : 0.5*distance;
82 const double upper = 2.*distance > upper_threshold ? upper_threshold : 2.*distance;
83 range<double> HeuristicInterval(lower, upper);
84 return HeuristicInterval;
85}
86
87/** Internal function to decide whether a suitable model is present or not.
88 *
89 * Here, the heuristic for deciding whether a new linked cell structure has to
90 * be constructed or not is implemented. The current heuristic is as follows:
91 * -# the best model should have at least half the desired length (such
92 * that most we have to look two neighbor shells wide and not one).
93 * -# the best model should have at most twice the desired length but
94 * no less than 1 angstroem.
95 *
96 * \note Dealing out a pointer is here (hopefully) safe because the function is
97 * internal and we - inside this class - know what we are doing.
98 *
99 * @param distance edge length of the requested linked cell structure
100 * @return NULL - there is no fitting LinkedCell_Model, else - pointer to instance
101 */
102const LinkedCell_Model *LinkedCell_Controller::getBestModel(double distance) const
103{
104 /// Bound distance to be within [lower_threshold, upper_threshold).
105 /// Note that we need to stay away from upper boundary a bit,
106 /// otherwise the distance will end up outside of the interval.
107 if (distance < lower_threshold)
108 distance = lower_threshold;
109 if (distance > upper_threshold)
110 distance = upper_threshold - std::numeric_limits<double>::round_error();
111
112 /// Look for all models within [0.5 distance, 2. distance).
113 MapEdgelengthModel::const_iterator bestmatch = ModelsMap.end();
114 if (!ModelsMap.empty()) {
115 for(MapEdgelengthModel::const_iterator iter = ModelsMap.begin();
116 iter != ModelsMap.end(); ++iter) {
117 // check that we are truely within range
118 range<double> HeuristicInterval(getHeuristicRange(iter->first));
119 if (HeuristicInterval.isInRange(distance)) {
120 // if it's the first match or a closer one, pick
121 if ((bestmatch == ModelsMap.end())
122 || (fabs(bestmatch->first - distance) > fabs(iter->first - distance)))
123 bestmatch = iter;
124 }
125 }
126 }
127
128 /// Return best match or NULL if none found.
129 if (bestmatch != ModelsMap.end())
130 return bestmatch->second;
131 else
132 return NULL;
133}
134
135/** Internal function to insert a new model and check for valid insertion.
136 *
137 * @param distance edge length of new model
138 * @param instance pointer to model
139 */
140void LinkedCell_Controller::insertNewModel(const double edgelength, LinkedCell_Model*& instance)
141{
142 std::pair< MapEdgelengthModel::iterator, bool> inserter =
143 ModelsMap.insert( std::make_pair(edgelength, instance) );
144 ASSERT(inserter.second,
145 "LinkedCell_Controller::getView() - LinkedCell_Model instance with distance "
146 +toString(edgelength)+" already present.");
147}
148
149/** Returns the a suitable LinkedCell_Model contained in a LinkedCell_View
150 * for the requested \a distance.
151 *
152 * \sa getBestModel()
153 *
154 * @param distance edge length of the requested linked cell structure
155 * @return LinkedCell_View wrapping the best LinkedCell_Model
156 */
157LinkedCell_View LinkedCell_Controller::getView(const double distance)
158{
159 /// Look for best instance.
160 const LinkedCell_Model *LCModel_best = getBestModel(distance);
161
162 /// Construct new instance if none found,
163 if (LCModel_best == NULL) {
164 LinkedCell_Model *LCModel_new = new LinkedCell_Model(distance, domain);
165 insertNewModel(distance, LCModel_new);
166 LinkedCell_View view(const_cast<const LinkedCell_Model &>(*LCModel_new));
167 return view;
168 } else {
169 /// else construct interface and return.
170 LinkedCell_View view(*LCModel_best);
171 return view;
172 }
173}
Note: See TracBrowser for help on using the repository browser.