votca 2024.2-dev
Loading...
Searching...
No Matches
neighborlist.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18// Third party includes
19#include <boost/format.hpp>
20#include <boost/timer/progress_display.hpp>
21
22// Local private VOTCA includes
23#include "neighborlist.h"
24
25namespace votca {
26namespace xtp {
27
28bool InVector(const std::vector<std::string>& vec, const std::string& word) {
29 return std::find(vec.begin(), vec.end(), word) != vec.end();
30}
31
33
34 if (options.exists(".segmentpairs")) {
35 useConstantCutoff_ = false;
36 std::vector<const tools::Property*> segs =
37 options.Select(".segmentpairs.pair");
38 for (const tools::Property* segprop : segs) {
39 useConstantCutoff_ = false;
40 std::vector<std::string> names =
41 segprop->get("type").as<std::vector<std::string>>();
42 double cutoff =
43 segprop->get("cutoff").as<double>() * tools::conv::nm2bohr;
44
45 if (names.size() != 2) {
46 throw std::runtime_error(
47 "ERROR: Faulty pair definition for cut-off's: Need two segment "
48 "names "
49 "separated by a space");
50 }
51 cutoffs_[names[0]][names[1]] = cutoff;
52 cutoffs_[names[1]][names[0]] = cutoff;
53 if (!InVector(included_segments_, names[0])) {
54 included_segments_.push_back(names[0]);
55 }
56 if (!InVector(included_segments_, names[1])) {
57 included_segments_.push_back(names[1]);
58 }
59 }
60 } else {
61 useConstantCutoff_ = true;
63 options.get(".constant").as<double>() * tools::conv::nm2bohr;
64 }
65
66 if (options.exists(".exciton_cutoff")) {
67 useExcitonCutoff_ = true;
69 options.get(".exciton_cutoff").as<double>() * tools::conv::nm2bohr;
70 } else {
71 useExcitonCutoff_ = false;
72 }
73}
74
76 Index classical_pairs = 0;
77#pragma omp parallel for
78 for (Index i = 0; i < top.NBList().size(); i++) {
79 const Segment* seg1 = top.NBList()[i]->Seg1();
80 const Segment* seg2 = top.NBList()[i]->Seg2();
81 if (top.GetShortestDist(*seg1, *seg2) > excitonqmCutoff_) {
82 top.NBList()[i]->setType(QMPair::Excitoncl);
83#pragma omp critical
84 { classical_pairs++; }
85 } else {
86 top.NBList()[i]->setType(QMPair::Hopping);
87 }
88 } // Type 3 Exciton_classical approx
89 return classical_pairs;
90}
91
93
94 double min = top.getBox().diagonal().minCoeff();
95
96 std::vector<Segment*> segs;
97 for (Segment& seg : top.Segments()) {
98 if (useConstantCutoff_ || InVector(included_segments_, seg.getType())) {
99 segs.push_back(&seg);
100 seg.getApproxSize();
101 }
102 }
103 std::cout << std::endl;
104 std::cout << "Evaluating " << segs.size() << " segments for neighborlist. ";
105 if ((top.Segments().size() - segs.size()) != 0) {
106 std::cout << top.Segments().size() - segs.size()
107 << " segments are not taken into account as specified"
108 << std::endl;
109 } else {
110 std::cout << std::endl;
111 }
112 if (!useConstantCutoff_) {
113 std::cout << "The following segments are used in the neigborlist creation"
114 << std::endl;
115 std::cout << "\t" << std::flush;
116 for (const std::string& st : included_segments_) {
117 std::cout << " " << st;
118 }
119 std::cout << std::endl;
120 }
121
122 std::cout << "\r ... ... Evaluating " << std::flush;
123 std::vector<std::string> skippedpairs;
124
125 top.NBList().Cleanup();
126
127 boost::timer::progress_display progress(segs.size());
128 // cache approx sizes
129 std::vector<double> approxsize = std::vector<double>(segs.size(), 0.0);
130#pragma omp parallel for
131 for (Index i = 0; i < Index(segs.size()); i++) {
132 approxsize[i] = segs[i]->getApproxSize();
133 }
134#pragma omp parallel for schedule(guided)
135 for (Index i = 0; i < Index(segs.size()); i++) {
136 const Segment* seg1 = segs[i];
137 double cutoff = constantCutoff_;
138 for (Index j = i + 1; j < Index(segs.size()); j++) {
139 const Segment* seg2 = segs[j];
140 if (!useConstantCutoff_) {
141 try {
142 cutoff = cutoffs_.at(seg1->getType()).at(seg2->getType());
143 } catch (const std::exception&) {
144 std::string pairstring = seg1->getType() + "/" + seg2->getType();
145 if (!InVector(skippedpairs, pairstring)) {
146#pragma omp critical
147 if (!InVector(skippedpairs, pairstring)) { // nedded because other
148 // thread may have
149 // pushed back in the
150 // meantime.
151 skippedpairs.push_back(pairstring);
152 }
153 }
154 continue;
155 }
156 }
157
158 if (cutoff > 0.5 * min) {
159 throw std::runtime_error(
160 (boost::format("Cutoff is larger than half the box size. Maximum "
161 "allowed cutoff is %1$1.1f (nm)") %
162 (tools::conv::bohr2nm * 0.5 * min))
163 .str());
164 }
165 double cutoff2 = cutoff * cutoff;
166 Eigen::Vector3d segdistance =
167 top.PbShortestConnect(seg1->getPos(), seg2->getPos());
168 double segdistance2 = segdistance.squaredNorm();
169 double outside = cutoff + approxsize[i] + approxsize[j];
170
171 if (segdistance2 < cutoff2) {
172#pragma omp critical
173 { top.NBList().Add(*seg1, *seg2, segdistance); }
174
175 } else if (segdistance2 > (outside * outside)) {
176 continue;
177 } else {
178 double R = top.GetShortestDist(*seg1, *seg2);
179 if ((R * R) < cutoff2) {
180#pragma omp critical
181 { top.NBList().Add(*seg1, *seg2, segdistance); }
182 }
183 }
184 } /* exit loop seg2 */
185#pragma omp critical
186 { ++progress; }
187 } /* exit loop seg1 */
188
189 if (skippedpairs.size() > 0) {
190 std::cout << "WARNING: No cut-off specified for segment pairs of type "
191 << std::endl;
192 for (const std::string& st : skippedpairs) {
193 std::cout << st << std::endl;
194 }
195 std::cout << "pairs were skipped" << std::endl;
196 }
197
198 std::cout << std::endl
199 << " ... ... Created " << top.NBList().size() << " direct pairs.";
200 if (useExcitonCutoff_) {
201 std::cout << std::endl
202 << " ... ... Determining classical pairs " << std::endl;
203 Index classical_pairs = DetClassicalPairs(top);
204 std::cout << " ... ... Found " << classical_pairs << " classical pairs "
205 << std::endl;
206 }
207
208 // sort qmpairs by seg1id and then by seg2id then reindex the pair id
209 // according to that.
210 top.NBList().sortAndReindex([](QMPair* a, QMPair* b) {
211 if (a->Seg1()->getId() != b->Seg1()->getId()) {
212 return a->Seg1()->getId() < b->Seg1()->getId();
213 }
214 return a->Seg2()->getId() < b->Seg2()->getId();
215 });
216
217 return true;
218}
219} // namespace xtp
220} // namespace votca
Index size() const
Definition pairlist.h:53
class to manage program options with xml serialization functionality
Definition property.h:55
Property & get(const std::string &key)
get existing property
Definition property.cc:79
bool exists(const std::string &key) const
check whether property exists
Definition property.cc:122
T as() const
return value as type
Definition property.h:283
std::vector< Property * > Select(const std::string &filter)
select property based on a filter
Definition property.cc:185
const std::string & getType() const
const Eigen::Vector3d & getPos() const
std::vector< std::string > included_segments_
Index DetClassicalPairs(Topology &top)
std::map< std::string, std::map< std::string, double > > cutoffs_
bool Evaluate(Topology &top)
void ParseOptions(const tools::Property &user_options)
void sortAndReindex(Compare comp)
Definition qmnblist.h:57
QMPair & Add(const Segment &seg1, const Segment &seg2, const Eigen::Vector3d &r)
Definition qmnblist.cc:27
const Segment * Seg2() const
Definition qmpair.h:124
const Segment * Seg1() const
Definition qmpair.h:123
Container for segments and box and atoms.
Definition topology.h:41
Eigen::Vector3d PbShortestConnect(const Eigen::Vector3d &r1, const Eigen::Vector3d &r2) const
Definition topology.cc:129
std::vector< Segment > & Segments()
Definition topology.h:58
const Eigen::Matrix3d & getBox() const
Definition topology.h:64
QMNBList & NBList()
Definition topology.h:70
double GetShortestDist(const Segment &seg1, const Segment &seg2) const
Definition topology.cc:134
const double bohr2nm
Definition constants.h:46
const double nm2bohr
Definition constants.h:47
bool InVector(const std::vector< std::string > &vec, const std::string &word)
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26