source: src/LinkedCell/LinkedCell_Controller.cpp@ 8c31865

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

LinkedCell_Controller::getView() now needs a PointCloud set.

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