votca 2025.1-dev
Loading...
Searching...
No Matches
neighborlist.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2025 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 {
85 classical_pairs++;
86 }
87 } else {
88 top.NBList()[i]->setType(QMPair::Hopping);
89 }
90 } // Type 3 Exciton_classical approx
91 return classical_pairs;
92}
93
95
96 double min = top.getBox().diagonal().minCoeff();
97
98 std::vector<Segment*> segs;
99 for (Segment& seg : top.Segments()) {
100 if (useConstantCutoff_ || InVector(included_segments_, seg.getType())) {
101 segs.push_back(&seg);
102 seg.getApproxSize();
103 }
104 }
105 std::cout << std::endl;
106 std::cout << "Evaluating " << segs.size() << " segments for neighborlist. ";
107 if ((top.Segments().size() - segs.size()) != 0) {
108 std::cout << top.Segments().size() - segs.size()
109 << " segments are not taken into account as specified"
110 << std::endl;
111 } else {
112 std::cout << std::endl;
113 }
114 if (!useConstantCutoff_) {
115 std::cout << "The following segments are used in the neigborlist creation"
116 << std::endl;
117 std::cout << "\t" << std::flush;
118 for (const std::string& st : included_segments_) {
119 std::cout << " " << st;
120 }
121 std::cout << std::endl;
122 }
123
124 std::cout << "\r ... ... Evaluating " << std::flush;
125 std::vector<std::string> skippedpairs;
126
127 top.NBList().Cleanup();
128
129 boost::timer::progress_display progress(segs.size());
130 // cache approx sizes
131 std::vector<double> approxsize = std::vector<double>(segs.size(), 0.0);
132#pragma omp parallel for
133 for (Index i = 0; i < Index(segs.size()); i++) {
134 approxsize[i] = segs[i]->getApproxSize();
135 }
136#pragma omp parallel for schedule(guided)
137 for (Index i = 0; i < Index(segs.size()); i++) {
138 const Segment* seg1 = segs[i];
139 double cutoff = constantCutoff_;
140 for (Index j = i + 1; j < Index(segs.size()); j++) {
141 const Segment* seg2 = segs[j];
142 if (!useConstantCutoff_) {
143 try {
144 cutoff = cutoffs_.at(seg1->getType()).at(seg2->getType());
145 } catch (const std::exception&) {
146 std::string pairstring = seg1->getType() + "/" + seg2->getType();
147 if (!InVector(skippedpairs, pairstring)) {
148#pragma omp critical
149 if (!InVector(skippedpairs, pairstring)) { // nedded because other
150 // thread may have
151 // pushed back in the
152 // meantime.
153 skippedpairs.push_back(pairstring);
154 }
155 }
156 continue;
157 }
158 }
159
160 if (cutoff > 0.5 * min) {
161 throw std::runtime_error(
162 (boost::format("Cutoff is larger than half the box size. Maximum "
163 "allowed cutoff is %1$1.1f (nm)") %
164 (tools::conv::bohr2nm * 0.5 * min))
165 .str());
166 }
167 double cutoff2 = cutoff * cutoff;
168 Eigen::Vector3d segdistance =
169 top.PbShortestConnect(seg1->getPos(), seg2->getPos());
170 double segdistance2 = segdistance.squaredNorm();
171 double outside = cutoff + approxsize[i] + approxsize[j];
172
173 if (segdistance2 < cutoff2) {
174#pragma omp critical
175 {
176 top.NBList().Add(*seg1, *seg2, segdistance);
177 }
178
179 } else if (segdistance2 > (outside * outside)) {
180 continue;
181 } else {
182 double R = top.GetShortestDist(*seg1, *seg2);
183 if ((R * R) < cutoff2) {
184#pragma omp critical
185 {
186 top.NBList().Add(*seg1, *seg2, segdistance);
187 }
188 }
189 }
190 } /* exit loop seg2 */
191#pragma omp critical
192 {
193 ++progress;
194 }
195 } /* exit loop seg1 */
196
197 if (skippedpairs.size() > 0) {
198 std::cout << "WARNING: No cut-off specified for segment pairs of type "
199 << std::endl;
200 for (const std::string& st : skippedpairs) {
201 std::cout << st << std::endl;
202 }
203 std::cout << "pairs were skipped" << std::endl;
204 }
205
206 std::cout << std::endl
207 << " ... ... Created " << top.NBList().size() << " direct pairs.";
208 if (useExcitonCutoff_) {
209 std::cout << std::endl
210 << " ... ... Determining classical pairs " << std::endl;
211 Index classical_pairs = DetClassicalPairs(top);
212 std::cout << " ... ... Found " << classical_pairs << " classical pairs "
213 << std::endl;
214 }
215
216 // sort qmpairs by seg1id and then by seg2id then reindex the pair id
217 // according to that.
218 top.NBList().sortAndReindex([](QMPair* a, QMPair* b) {
219 if (a->Seg1()->getId() != b->Seg1()->getId()) {
220 return a->Seg1()->getId() < b->Seg1()->getId();
221 }
222 return a->Seg2()->getId() < b->Seg2()->getId();
223 });
224
225 return true;
226}
227} // namespace xtp
228} // 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
Charge transport classes.
Definition ERIs.h:28
bool InVector(const std::vector< std::string > &vec, const std::string &word)
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26