source: src/analysis_correlation.cpp@ 67c92b

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 67c92b was ea430a, checked in by Frederik Heber <heber@…>, 14 years ago

Initial versions of DipoleAngularCorrelation().

  • no implementation yet, just function signatures.
  • Property mode set to 100644
File size: 25.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * analysis.cpp
10 *
11 * Created on: Oct 13, 2009
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 <iostream>
23#include <iomanip>
24
25#include "BoundaryTriangleSet.hpp"
26#include "analysis_correlation.hpp"
27#include "element.hpp"
28#include "CodePatterns/Info.hpp"
29#include "CodePatterns/Log.hpp"
30#include "Formula.hpp"
31#include "molecule.hpp"
32#include "tesselation.hpp"
33#include "tesselationhelpers.hpp"
34#include "triangleintersectionlist.hpp"
35#include "LinearAlgebra/Vector.hpp"
36#include "LinearAlgebra/RealSpaceMatrix.hpp"
37#include "CodePatterns/Verbose.hpp"
38#include "World.hpp"
39#include "Box.hpp"
40
41/** Calculates the dipole angular correlation for given molecule type.
42 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
43 * \param *molecules vector of molecules
44 * \param &elements vector of elements to correlate
45 * \return Map of doubles with values the pair of the two atoms.
46 */
47DipoleAngularCorrelationMap *DipoleAngularCorrelation(std::vector<molecule *> &molecules, const Formula &formula)
48{
49 Info FunctionInfo(__func__);
50 DipoleAngularCorrelationMap *outmap = NULL;
51// double distance = 0.;
52// Box &domain = World::getInstance().getDomain();
53//
54// if (molecules.empty()) {
55// DoeLog(1) && (eLog()<< Verbose(1) <<"No molecule given." << endl);
56// return outmap;
57// }
58// for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
59// (*MolWalker)->doCountAtoms();
60//
61// // create all possible pairs of elements
62// set <pair<const element *,const element *> > PairsOfElements;
63// if (elements.size() >= 2) {
64// for (vector<const element *>::const_iterator type1 = elements.begin(); type1 != elements.end(); ++type1)
65// for (vector<const element *>::const_iterator type2 = elements.begin(); type2 != elements.end(); ++type2)
66// if (type1 != type2) {
67// PairsOfElements.insert( make_pair(*type1,*type2) );
68// DoLog(1) && (Log() << Verbose(1) << "Creating element pair " << *(*type1) << " and " << *(*type2) << "." << endl);
69// }
70// } else if (elements.size() == 1) { // one to all are valid
71// const element *elemental = *elements.begin();
72// PairsOfElements.insert( pair<const element *,const element*>(elemental,0) );
73// PairsOfElements.insert( pair<const element *,const element*>(0,elemental) );
74// } else { // all elements valid
75// PairsOfElements.insert( pair<element *, element*>((element *)NULL, (element *)NULL) );
76// }
77//
78// outmap = new PairCorrelationMap;
79// for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++){
80// DoLog(2) && (Log()<< Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
81// for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
82// DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
83// for (std::vector<molecule *>::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules.end(); MolOtherWalker++){
84// DoLog(2) && (Log() << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl);
85// for (molecule::const_iterator runner = (*MolOtherWalker)->begin(); runner != (*MolOtherWalker)->end(); ++runner) {
86// DoLog(3) && (Log() << Verbose(3) << "Current otheratom is " << **runner << "." << endl);
87// if ((*iter)->getId() < (*runner)->getId()){
88// for (set <pair<const element *, const element *> >::iterator PairRunner = PairsOfElements.begin(); PairRunner != PairsOfElements.end(); ++PairRunner)
89// if ((PairRunner->first == (**iter).getType()) && (PairRunner->second == (**runner).getType())) {
90// distance = domain.periodicDistance((*iter)->getPosition(),(*runner)->getPosition());
91// //Log() << Verbose(1) <<"Inserting " << *(*iter) << " and " << *(*runner) << endl;
92// outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> ((*iter), (*runner)) ) );
93// }
94// }
95// }
96// }
97// }
98// }
99 return outmap;
100};
101
102
103/** Calculates the pair correlation between given elements.
104 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
105 * \param *molecules vector of molecules
106 * \param &elements vector of elements to correlate
107 * \return Map of doubles with values the pair of the two atoms.
108 */
109PairCorrelationMap *PairCorrelation(std::vector<molecule *> &molecules, const std::vector<const element *> &elements)
110{
111 Info FunctionInfo(__func__);
112 PairCorrelationMap *outmap = NULL;
113 double distance = 0.;
114 Box &domain = World::getInstance().getDomain();
115
116 if (molecules.empty()) {
117 DoeLog(1) && (eLog()<< Verbose(1) <<"No molecule given." << endl);
118 return outmap;
119 }
120 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
121 (*MolWalker)->doCountAtoms();
122
123 // create all possible pairs of elements
124 set <pair<const element *,const element *> > PairsOfElements;
125 if (elements.size() >= 2) {
126 for (vector<const element *>::const_iterator type1 = elements.begin(); type1 != elements.end(); ++type1)
127 for (vector<const element *>::const_iterator type2 = elements.begin(); type2 != elements.end(); ++type2)
128 if (type1 != type2) {
129 PairsOfElements.insert( make_pair(*type1,*type2) );
130 DoLog(1) && (Log() << Verbose(1) << "Creating element pair " << *(*type1) << " and " << *(*type2) << "." << endl);
131 }
132 } else if (elements.size() == 1) { // one to all are valid
133 const element *elemental = *elements.begin();
134 PairsOfElements.insert( pair<const element *,const element*>(elemental,0) );
135 PairsOfElements.insert( pair<const element *,const element*>(0,elemental) );
136 } else { // all elements valid
137 PairsOfElements.insert( pair<element *, element*>((element *)NULL, (element *)NULL) );
138 }
139
140 outmap = new PairCorrelationMap;
141 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++){
142 DoLog(2) && (Log()<< Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
143 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
144 DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
145 for (std::vector<molecule *>::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules.end(); MolOtherWalker++){
146 DoLog(2) && (Log() << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl);
147 for (molecule::const_iterator runner = (*MolOtherWalker)->begin(); runner != (*MolOtherWalker)->end(); ++runner) {
148 DoLog(3) && (Log() << Verbose(3) << "Current otheratom is " << **runner << "." << endl);
149 if ((*iter)->getId() < (*runner)->getId()){
150 for (set <pair<const element *, const element *> >::iterator PairRunner = PairsOfElements.begin(); PairRunner != PairsOfElements.end(); ++PairRunner)
151 if ((PairRunner->first == (**iter).getType()) && (PairRunner->second == (**runner).getType())) {
152 distance = domain.periodicDistance((*iter)->getPosition(),(*runner)->getPosition());
153 //Log() << Verbose(1) <<"Inserting " << *(*iter) << " and " << *(*runner) << endl;
154 outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> ((*iter), (*runner)) ) );
155 }
156 }
157 }
158 }
159 }
160 }
161 return outmap;
162};
163
164/** Calculates the pair correlation between given elements.
165 * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
166 * \param *molecules list of molecules structure
167 * \param &elements vector of elements to correlate
168 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
169 * \return Map of doubles with values the pair of the two atoms.
170 */
171PairCorrelationMap *PeriodicPairCorrelation(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const int ranges[NDIM] )
172{
173 Info FunctionInfo(__func__);
174 PairCorrelationMap *outmap = NULL;
175 double distance = 0.;
176 int n[NDIM];
177 Vector checkX;
178 Vector periodicX;
179 int Othern[NDIM];
180 Vector checkOtherX;
181 Vector periodicOtherX;
182
183 if (molecules.empty()) {
184 DoeLog(1) && (eLog()<< Verbose(1) <<"No molecule given." << endl);
185 return outmap;
186 }
187 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
188 (*MolWalker)->doCountAtoms();
189
190 // create all possible pairs of elements
191 set <pair<const element *,const element *> > PairsOfElements;
192 if (elements.size() >= 2) {
193 for (vector<const element *>::const_iterator type1 = elements.begin(); type1 != elements.end(); ++type1)
194 for (vector<const element *>::const_iterator type2 = elements.begin(); type2 != elements.end(); ++type2)
195 if (type1 != type2) {
196 PairsOfElements.insert( make_pair(*type1,*type2) );
197 DoLog(1) && (Log() << Verbose(1) << "Creating element pair " << *(*type1) << " and " << *(*type2) << "." << endl);
198 }
199 } else if (elements.size() == 1) { // one to all are valid
200 const element *elemental = *elements.begin();
201 PairsOfElements.insert( pair<const element *,const element*>(elemental,0) );
202 PairsOfElements.insert( pair<const element *,const element*>(0,elemental) );
203 } else { // all elements valid
204 PairsOfElements.insert( pair<element *, element*>((element *)NULL, (element *)NULL) );
205 }
206
207 outmap = new PairCorrelationMap;
208 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++){
209 RealSpaceMatrix FullMatrix = World::getInstance().getDomain().getM();
210 RealSpaceMatrix FullInverseMatrix = World::getInstance().getDomain().getMinv();
211 DoLog(2) && (Log()<< Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
212 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
213 DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
214 periodicX = FullInverseMatrix * ((*iter)->getPosition()); // x now in [0,1)^3
215 // go through every range in xyz and get distance
216 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
217 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
218 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
219 checkX = FullMatrix * (Vector(n[0], n[1], n[2]) + periodicX);
220 for (std::vector<molecule *>::const_iterator MolOtherWalker = MolWalker; MolOtherWalker != molecules.end(); MolOtherWalker++){
221 DoLog(2) && (Log() << Verbose(2) << "Current other molecule is " << *MolOtherWalker << "." << endl);
222 for (molecule::const_iterator runner = (*MolOtherWalker)->begin(); runner != (*MolOtherWalker)->end(); ++runner) {
223 DoLog(3) && (Log() << Verbose(3) << "Current otheratom is " << **runner << "." << endl);
224 if ((*iter)->getId() < (*runner)->getId()){
225 for (set <pair<const element *,const element *> >::iterator PairRunner = PairsOfElements.begin(); PairRunner != PairsOfElements.end(); ++PairRunner)
226 if ((PairRunner->first == (**iter).getType()) && (PairRunner->second == (**runner).getType())) {
227 periodicOtherX = FullInverseMatrix * ((*runner)->getPosition()); // x now in [0,1)^3
228 // go through every range in xyz and get distance
229 for (Othern[0]=-ranges[0]; Othern[0] <= ranges[0]; Othern[0]++)
230 for (Othern[1]=-ranges[1]; Othern[1] <= ranges[1]; Othern[1]++)
231 for (Othern[2]=-ranges[2]; Othern[2] <= ranges[2]; Othern[2]++) {
232 checkOtherX = FullMatrix * (Vector(Othern[0], Othern[1], Othern[2]) + periodicOtherX);
233 distance = checkX.distance(checkOtherX);
234 //Log() << Verbose(1) <<"Inserting " << *(*iter) << " and " << *(*runner) << endl;
235 outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> ((*iter), (*runner)) ) );
236 }
237 }
238 }
239 }
240 }
241 }
242 }
243 }
244
245 return outmap;
246};
247
248/** Calculates the distance (pair) correlation between a given element and a point.
249 * \param *molecules list of molecules structure
250 * \param &elements vector of elements to correlate with point
251 * \param *point vector to the correlation point
252 * \return Map of dobules with values as pairs of atom and the vector
253 */
254CorrelationToPointMap *CorrelationToPoint(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Vector *point )
255{
256 Info FunctionInfo(__func__);
257 CorrelationToPointMap *outmap = NULL;
258 double distance = 0.;
259 Box &domain = World::getInstance().getDomain();
260
261 if (molecules.empty()) {
262 DoLog(1) && (Log() << Verbose(1) <<"No molecule given." << endl);
263 return outmap;
264 }
265 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
266 (*MolWalker)->doCountAtoms();
267 outmap = new CorrelationToPointMap;
268 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++) {
269 DoLog(2) && (Log() << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
270 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
271 DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
272 for (vector<const element *>::const_iterator type = elements.begin(); type != elements.end(); ++type)
273 if ((*type == NULL) || ((*iter)->getType() == *type)) {
274 distance = domain.periodicDistance((*iter)->getPosition(),*point);
275 DoLog(4) && (Log() << Verbose(4) << "Current distance is " << distance << "." << endl);
276 outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> ((*iter), point) ) );
277 }
278 }
279 }
280
281 return outmap;
282};
283
284/** Calculates the distance (pair) correlation between a given element, all its periodic images and a point.
285 * \param *molecules list of molecules structure
286 * \param &elements vector of elements to correlate to point
287 * \param *point vector to the correlation point
288 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
289 * \return Map of dobules with values as pairs of atom and the vector
290 */
291CorrelationToPointMap *PeriodicCorrelationToPoint(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Vector *point, const int ranges[NDIM] )
292{
293 Info FunctionInfo(__func__);
294 CorrelationToPointMap *outmap = NULL;
295 double distance = 0.;
296 int n[NDIM];
297 Vector periodicX;
298 Vector checkX;
299
300 if (molecules.empty()) {
301 DoLog(1) && (Log() << Verbose(1) <<"No molecule given." << endl);
302 return outmap;
303 }
304 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
305 (*MolWalker)->doCountAtoms();
306 outmap = new CorrelationToPointMap;
307 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++) {
308 RealSpaceMatrix FullMatrix = World::getInstance().getDomain().getM();
309 RealSpaceMatrix FullInverseMatrix = World::getInstance().getDomain().getMinv();
310 DoLog(2) && (Log() << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
311 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
312 DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
313 for (vector<const element *>::const_iterator type = elements.begin(); type != elements.end(); ++type)
314 if ((*type == NULL) || ((*iter)->getType() == *type)) {
315 periodicX = FullInverseMatrix * ((*iter)->getPosition()); // x now in [0,1)^3
316 // go through every range in xyz and get distance
317 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
318 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
319 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
320 checkX = FullMatrix * (Vector(n[0], n[1], n[2]) + periodicX);
321 distance = checkX.distance(*point);
322 DoLog(4) && (Log() << Verbose(4) << "Current distance is " << distance << "." << endl);
323 outmap->insert ( pair<double, pair<atom *, const Vector*> >(distance, pair<atom *, const Vector*> (*iter, point) ) );
324 }
325 }
326 }
327 }
328
329 return outmap;
330};
331
332/** Calculates the distance (pair) correlation between a given element and a surface.
333 * \param *molecules list of molecules structure
334 * \param &elements vector of elements to correlate to surface
335 * \param *Surface pointer to Tesselation class surface
336 * \param *LC LinkedCell structure to quickly find neighbouring atoms
337 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
338 */
339CorrelationToSurfaceMap *CorrelationToSurface(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Tesselation * const Surface, const LinkedCell *LC )
340{
341 Info FunctionInfo(__func__);
342 CorrelationToSurfaceMap *outmap = NULL;
343 double distance = 0;
344 class BoundaryTriangleSet *triangle = NULL;
345 Vector centroid;
346
347 if ((Surface == NULL) || (LC == NULL) || (molecules.empty())) {
348 DoeLog(1) && (eLog()<< Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl);
349 return outmap;
350 }
351 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
352 (*MolWalker)->doCountAtoms();
353 outmap = new CorrelationToSurfaceMap;
354 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++) {
355 DoLog(2) && (Log() << Verbose(2) << "Current molecule is " << (*MolWalker)->name << "." << endl);
356 if ((*MolWalker)->empty())
357 DoLog(2) && (2) && (Log() << Verbose(2) << "\t is empty." << endl);
358 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
359 DoLog(3) && (Log() << Verbose(3) << "\tCurrent atom is " << *(*iter) << "." << endl);
360 for (vector<const element *>::const_iterator type = elements.begin(); type != elements.end(); ++type)
361 if ((*type == NULL) || ((*iter)->getType() == *type)) {
362 TriangleIntersectionList Intersections((*iter)->getPosition(),Surface,LC);
363 distance = Intersections.GetSmallestDistance();
364 triangle = Intersections.GetClosestTriangle();
365 outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> ((*iter), triangle) ) );
366 }
367 }
368 }
369
370 return outmap;
371};
372
373/** Calculates the distance (pair) correlation between a given element, all its periodic images and and a surface.
374 * Note that we also put all periodic images found in the cells given by [ -ranges[i], ranges[i] ] and i=0,...,NDIM-1.
375 * I.e. We multiply the atom::node with the inverse of the domain matrix, i.e. transform it to \f$[0,0^3\f$, then add per
376 * axis an integer from [ -ranges[i], ranges[i] ] onto it and multiply with the domain matrix to bring it back into
377 * the real space. Then, we Tesselation::FindClosestTriangleToPoint() and DistanceToTrianglePlane().
378 * \param *molecules list of molecules structure
379 * \param &elements vector of elements to correlate to surface
380 * \param *Surface pointer to Tesselation class surface
381 * \param *LC LinkedCell structure to quickly find neighbouring atoms
382 * \param ranges[NDIM] interval boundaries for the periodic images to scan also
383 * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
384 */
385CorrelationToSurfaceMap *PeriodicCorrelationToSurface(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Tesselation * const Surface, const LinkedCell *LC, const int ranges[NDIM] )
386{
387 Info FunctionInfo(__func__);
388 CorrelationToSurfaceMap *outmap = NULL;
389 double distance = 0;
390 class BoundaryTriangleSet *triangle = NULL;
391 Vector centroid;
392 int n[NDIM];
393 Vector periodicX;
394 Vector checkX;
395
396 if ((Surface == NULL) || (LC == NULL) || (molecules.empty())) {
397 DoLog(1) && (Log() << Verbose(1) <<"No Tesselation, no LinkedCell or no molecule given." << endl);
398 return outmap;
399 }
400 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++)
401 (*MolWalker)->doCountAtoms();
402 outmap = new CorrelationToSurfaceMap;
403 double ShortestDistance = 0.;
404 BoundaryTriangleSet *ShortestTriangle = NULL;
405 for (std::vector<molecule *>::const_iterator MolWalker = molecules.begin(); MolWalker != molecules.end(); MolWalker++) {
406 RealSpaceMatrix FullMatrix = World::getInstance().getDomain().getM();
407 RealSpaceMatrix FullInverseMatrix = World::getInstance().getDomain().getMinv();
408 DoLog(2) && (Log() << Verbose(2) << "Current molecule is " << *MolWalker << "." << endl);
409 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
410 DoLog(3) && (Log() << Verbose(3) << "Current atom is " << **iter << "." << endl);
411 for (vector<const element *>::const_iterator type = elements.begin(); type != elements.end(); ++type)
412 if ((*type == NULL) || ((*iter)->getType() == *type)) {
413 periodicX = FullInverseMatrix * ((*iter)->getPosition()); // x now in [0,1)^3
414 // go through every range in xyz and get distance
415 ShortestDistance = -1.;
416 for (n[0]=-ranges[0]; n[0] <= ranges[0]; n[0]++)
417 for (n[1]=-ranges[1]; n[1] <= ranges[1]; n[1]++)
418 for (n[2]=-ranges[2]; n[2] <= ranges[2]; n[2]++) {
419 checkX = FullMatrix * (Vector(n[0], n[1], n[2]) + periodicX);
420 TriangleIntersectionList Intersections(checkX,Surface,LC);
421 distance = Intersections.GetSmallestDistance();
422 triangle = Intersections.GetClosestTriangle();
423 if ((ShortestDistance == -1.) || (distance < ShortestDistance)) {
424 ShortestDistance = distance;
425 ShortestTriangle = triangle;
426 }
427 }
428 // insert
429 outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(ShortestDistance, pair<atom *, BoundaryTriangleSet*> (*iter, ShortestTriangle) ) );
430 //Log() << Verbose(1) << "INFO: Inserting " << Walker << " with distance " << ShortestDistance << " to " << *ShortestTriangle << "." << endl;
431 }
432 }
433 }
434
435 return outmap;
436};
437
438/** Returns the index of the bin for a given value.
439 * \param value value whose bin to look for
440 * \param BinWidth width of bin
441 * \param BinStart first bin
442 */
443int GetBin ( const double value, const double BinWidth, const double BinStart )
444{
445 Info FunctionInfo(__func__);
446 int bin =(int) (floor((value - BinStart)/BinWidth));
447 return (bin);
448};
449
450
451/** Prints correlation (double, int) pairs to file.
452 * \param *file file to write to
453 * \param *map map to write
454 */
455void OutputCorrelation( ofstream * const file, const BinPairMap * const map )
456{
457 Info FunctionInfo(__func__);
458 *file << "BinStart\tCount" << endl;
459 for (BinPairMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
460 *file << setprecision(8) << runner->first << "\t" << runner->second << endl;
461 }
462};
463
464/** Prints correlation (double, (atom*,atom*) ) pairs to file.
465 * \param *file file to write to
466 * \param *map map to write
467 */
468void OutputPairCorrelation( ofstream * const file, const PairCorrelationMap * const map )
469{
470 Info FunctionInfo(__func__);
471 *file << "BinStart\tAtom1\tAtom2" << endl;
472 for (PairCorrelationMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
473 *file << setprecision(8) << runner->first << "\t" << *(runner->second.first) << "\t" << *(runner->second.second) << endl;
474 }
475};
476
477/** Prints correlation (double, int) pairs to file.
478 * \param *file file to write to
479 * \param *map map to write
480 */
481void OutputCorrelationToPoint( ofstream * const file, const CorrelationToPointMap * const map )
482{
483 Info FunctionInfo(__func__);
484 *file << "BinStart\tAtom::x[i]-point.x[i]" << endl;
485 for (CorrelationToPointMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
486 *file << runner->first;
487 for (int i=0;i<NDIM;i++)
488 *file << "\t" << setprecision(8) << (runner->second.first->at(i) - runner->second.second->at(i));
489 *file << endl;
490 }
491};
492
493/** Prints correlation (double, int) pairs to file.
494 * \param *file file to write to
495 * \param *map map to write
496 */
497void OutputCorrelationToSurface( ofstream * const file, const CorrelationToSurfaceMap * const map )
498{
499 Info FunctionInfo(__func__);
500 *file << "BinStart\tTriangle" << endl;
501 if (!map->empty())
502 for (CorrelationToSurfaceMap::const_iterator runner = map->begin(); runner != map->end(); ++runner) {
503 *file << setprecision(8) << runner->first << "\t";
504 *file << *(runner->second.first) << "\t";
505 *file << *(runner->second.second) << endl;
506 }
507};
508
Note: See TracBrowser for help on using the repository browser.