PSCF v1.4.0
EdgeIterator.tpp
1/*
2* PSCF - Polymer Self-Consistent Field
3*
4* Copyright 2015 - 2025, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8#include "EdgeIterator.h"
9#include <pscf/chem/PolymerSpecies.h>
10#include <pscf/chem/Edge.h>
11#include <util/containers/Pair.h>
12
13namespace Pscf {
14
15 /*
16 * Constructor
17 */
18 template <typename WT>
20 : currentVertexId_(-1),
21 targetVertexId_(-1),
22 polymerPtr_(&polymer)
23 {}
24
25 /*
26 * Destructor
27 */
28 template <typename WT>
31
32 /*
33 * Initialize iterator.
34 */
35 template <typename WT>
36 void EdgeIterator<WT>::begin(int sourceId, int targetId)
37 {
38 UTIL_CHECK(sourceId != targetId);
39 currentEdgeId_ = sourceId;
40 targetEdgeId_ = targetId;
41
42 // Identify ids for vertices of source edge
43 int s0 = polymerPtr_->edge(sourceId).vertexId(0);
44 int s1 = polymerPtr_->edge(sourceId).vertexId(1);
45
46 // Identify ids for vertices of target edge
47 int t0 = polymerPtr_->edge(targetId).vertexId(0);
48 int t1 = polymerPtr_->edge(targetId).vertexId(1);
49
50 // Paths from source vertices towards target vertices
51 Pair<int> p00, p01, p10, p11;
52 p00 = polymerPtr_->path(s0, t0);
53 p01 = polymerPtr_->path(s0, t1);
54 p10 = polymerPtr_->path(s1, t0);
55 p11 = polymerPtr_->path(s1, t1);
56 // Find paths that go through the source edge
57 if (p00[0] == currentEdgeId_) {
58 UTIL_CHECK(p01[0] == currentEdgeId_);
59 UTIL_CHECK(p10[0] != currentEdgeId_);
60 UTIL_CHECK(p11[0] != currentEdgeId_);
61 currentVertexId_ = s1;
62 currentDirectionId_ = 0;
63 } else
64 if (p10[0] == currentEdgeId_) {
65 UTIL_CHECK(p11[0] == currentEdgeId_);
66 UTIL_CHECK(p00[0] != currentEdgeId_);
67 UTIL_CHECK(p01[0] != currentEdgeId_);
68 currentVertexId_ = s0;
69 currentDirectionId_ = 1;
70 } else {
71 UTIL_THROW("Error in finding leading vertex for source");
72 }
73
74 // Paths from target vertices towards source vertices
75 p00 = polymerPtr_->path(t0, s0);
76 p01 = polymerPtr_->path(t0, s1);
77 p10 = polymerPtr_->path(t1, s0);
78 p11 = polymerPtr_->path(t1, s1);
79 // Find paths that go through the target edge
80 if (p00[0] == targetEdgeId_) {
81 UTIL_CHECK(p01[0] == targetEdgeId_);
82 UTIL_CHECK(p10[0] != targetEdgeId_);
83 UTIL_CHECK(p11[0] != targetEdgeId_);
84 targetVertexId_ = t0;
85 } else
86 if (p10[0] == targetEdgeId_) {
87 UTIL_CHECK(p11[0] == targetEdgeId_);
88 UTIL_CHECK(p00[0] != targetEdgeId_);
89 UTIL_CHECK(p01[0] != targetEdgeId_);
90 targetVertexId_ = t1;
91 } else {
92 UTIL_THROW("Error in finding target vertex");
93 }
94
95 }
96
97 /*
98 * Increment vertex - update current vertex to next one in path.
99 */
100 template <typename WT>
102 {
104 Pair<int> propId = polymerPtr_->path(currentVertexId_, targetVertexId_);
105 int edgeId = propId[0];
106 int dirId = propId[1];
107 UTIL_CHECK(edgeId >= 0);
108 UTIL_CHECK(edgeId < polymerPtr_->nBlock());
109 UTIL_CHECK(dirId >= 0);
110 UTIL_CHECK(dirId < 2);
111 Edge const & edge = polymerPtr_->edge(edgeId);
112 UTIL_CHECK(edge.vertexId(dirId) == currentVertexId_);
113 currentEdgeId_ = edgeId;
114 currentDirectionId_ = dirId;
115 if (dirId == 0) {
116 currentVertexId_ = edge.vertexId(1);
117 } else {
118 currentVertexId_ = edge.vertexId(0);
119 }
120 return *this;
121 }
122
123 /*
124 * Get the current edge id.
125 */
126 template <typename WT>
128 { return currentEdgeId_; }
129
130 /*
131 * Get the current direction id.
132 */
133 template <typename WT>
135 { return currentDirectionId_; }
136
137 /*
138 * Get the current vertex id.
139 */
140 template <typename WT>
142 { return currentVertexId_; }
143
144 /*
145 * Is the current vertex equal to the target.
146 */
147 template <typename WT>
149 {
150 return (bool)( currentVertexId_ == targetVertexId_ );
151 }
152
153 /*
154 * Is the current vertex not equal to the target.
155 */
156 template <typename WT>
158 {
159 return (bool)( currentVertexId_ != targetVertexId_ );
160 }
161
162}
int currentEdgeId() const
Get index of the current edge.
int currentVertexId() const
Get index of the current vertex.
EdgeIterator< WT > & operator++()
Increment operator - move to next vertex.
int currentDirectionId() const
Get direction index for the path within the current edge.
bool isEnd() const
Return true iff currentId == targetId.
void begin(int sourceId, int targetId)
Initialize iterator.
EdgeIterator(PolymerSpecies< WT > const &polymer)
Constructor.
~EdgeIterator()
Destructor.
bool notEnd() const
Return true iff currentId != targetId.
Descriptor for a block within a block polymer.
Definition Edge.h:59
int vertexId(int i) const
Get the id of one associated vertex.
Definition Edge.h:296
Descriptor for a linear or acyclic branched block polymer.
An array of exactly 2 objects.
Definition Pair.h:24
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
PSCF package top-level namespace.