PSCF v1.3.3
PolymerTmpl.tpp
1#ifndef PSCF_POLYMER_TMPL_TPP
2#define PSCF_POLYMER_TMPL_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "PolymerTmpl.h"
12
13namespace Pscf {
14
15 class Edge;
16 using namespace Util;
17
18 /*
19 * Constructor.
20 */
21 template <class BT, class PT>
24 blocks_()
25 { setClassName("PolymerTmpl"); }
26
27 /*
28 * Destructor.
29 */
30 template <class BT, class PT>
33
34 /*
35 * Allocate blocks array.
36 */
37 template <class BT, class PT>
39 { blocks_.allocate(nBlock()); }
40
41 /*
42 * Read blocks array from parameter file.
43 */
44 template <class BT, class PT>
45 void PolymerTmpl<BT,PT>::readBlocks(std::istream& in)
46 { readDArray<BT>(in, "blocks", blocks_, nBlock()); }
47
48 /*
49 * Read parameter file block.
50 */
51 template <class BT, class PT>
53 {
54
55 // Call PoymerSpecies base class member function
56 // Initializes PolymerSpecies, and Edge and Vertex components
58
59 // The remainder of this function sets and validates immutable
60 // information about graph topology that is stored by propagators.
61
62 PT * propagatorPtr = nullptr;
63 PT const * sourcePtr = nullptr;
64 Vertex const * headPtr = nullptr;
65 Vertex const * tailPtr = nullptr;
66 Pair<int> propId;
67 int blockId, forwardId, reverseId, headId, tailId, i;
68 bool isHeadEnd, isTailEnd;
69
70 // Set sources and end flags for all propagators
71 for (blockId = 0; blockId < nBlock(); ++blockId) {
72 for (forwardId = 0; forwardId < 2; ++forwardId) {
73
74 propagatorPtr = &block(blockId).propagator(forwardId);
75
76 // Identify head and tail vertices
77 if (forwardId == 0) {
78 reverseId = 1;
79 } else {
80 reverseId = 0;
81 }
82 headId = block(blockId).vertexId(forwardId);
83 tailId = block(blockId).vertexId(reverseId);
84 headPtr = &vertex(headId); // pointer to head vertex
85 tailPtr = &vertex(tailId); // pointer to tail vertex
86
87 // Add pointers to source propagators
88 for (i = 0; i < headPtr->size(); ++i) {
89 propId = headPtr->inPropagatorId(i);
90 if (propId[0] == blockId) {
91 UTIL_CHECK(propId[1] != forwardId);
92 } else {
93 sourcePtr =
94 &block(propId[0]).propagator(propId[1]);
95 propagatorPtr->addSource(*sourcePtr);
96 }
97 }
98
99 // Set vertex end flags
100 isHeadEnd = (headPtr->size() == 1) ? true : false;
101 isTailEnd = (tailPtr->size() == 1) ? true : false;
102 propagatorPtr->setEndFlags(isHeadEnd, isTailEnd);
103
104 } // end loop over forwardId (propagator direction id)
105 } // end loop over blockId
106
107 // Check validity - throw Exception if error detected
108 isValid();
109 }
111 /*
112 * Checks validity of propagator data set in readParameters.
113 *
114 * This function only checks validity of propagator source and end flag
115 * member data that is set in PolymerTmpl<BT,PT>::readParameters. It
116 * does not check validity of members of PolymerSpecies, Edge, and Vertex
117 * that are set and validated within the PolymerSpecies::readParameters
118 * base class member function.
119 */
120 template <class BT, class PT>
121 void PolymerTmpl<BT,PT>::isValid()
122 {
123 Vertex const * v0Ptr = nullptr;
124 Vertex const * v1Ptr = nullptr;
125 PT const * p0Ptr = nullptr;
126 PT const * p1Ptr = nullptr;
127 int bId, v0Id, v1Id;
128
129 // Loop over blocks
130 for (bId = 0; bId < nBlock(); ++bId) {
131 v0Id = block(bId).vertexId(0);
132 v1Id = block(bId).vertexId(1);
133 UTIL_CHECK(v0Id >= 0 && v0Id < nVertex());
134 UTIL_CHECK(v1Id >= 0 && v1Id < nVertex());
135 UTIL_CHECK(v0Id != v1Id);
136 v0Ptr = &vertex(v0Id);
137 v1Ptr = &vertex(v1Id);
138 p0Ptr = &(block(bId).propagator(0));
139 p1Ptr = &(block(bId).propagator(1));
140 UTIL_CHECK(p0Ptr->nSource() == (v0Ptr->size() - 1));
141 UTIL_CHECK(p1Ptr->nSource() == (v1Ptr->size() - 1));
142 UTIL_CHECK(p0Ptr->isHeadEnd() == p1Ptr->isTailEnd());
143 UTIL_CHECK(p0Ptr->isHeadEnd() == (v0Ptr->size() == 1));
144 UTIL_CHECK(p1Ptr->isHeadEnd() == (v1Ptr->size() == 1));
145 }
146
147 }
148
149 /*
150 * Solve the MDE for all blocks of this polymer.
151 */
152 template <class BT, class PT>
153 void PolymerTmpl<BT,PT>::solve(double phiTot)
154 {
155
156 // Clear all propagators
157 for (int j = 0; j < nPropagator(); ++j) {
158 propagator(j).setIsSolved(false);
160
161 // Solve modified diffusion equation for all propagators in
162 // the order specified by function makePlan.
163 for (int j = 0; j < nPropagator(); ++j) {
164 UTIL_CHECK(propagator(j).isReady());
165 propagator(j).solve();
166 }
167
168 // Compute molecular partition function Q
169 double Q = block(0).propagator(0).computeQ();
170
171 // The PT::computeQ function returns a spatial average.
172 // Correct for partial occupation of the unit cell.
173 Q = Q/phiTot;
174
175 // Set q and compute phi or mu, depending on the ensemble
176 Species::setQ(Q);
177
178 }
179
180 /*
181 * Get a propagator, indexed by block and direction ids (non-const).
182 */
183 template <class BT, class PT>
184 PT& PolymerTmpl<BT,PT>::propagator(int blockId, int directionId)
185 { return block(blockId).propagator(directionId); }
186
187 /*
188 * Get a propagator, indexed by block and direction ids (const).
189 */
190 template <class BT, class PT>
191 PT const &
192 PolymerTmpl<BT,PT>::propagator(int blockId, int directionId) const
193 { return block(blockId).propagator(directionId); }
194
195 /*
196 * Get a propagator, indexed in order of computation.
197 */
198 template <class BT, class PT>
200 {
201 Pair<int> propId = propagatorId(id);
202 return propagator(propId[0], propId[1]);
203 }
204
205}
206#endif
Descriptor for a block within a block polymer.
Definition Edge.h:59
PolymerSpecies()
Constructor.
virtual void readParameters(std::istream &in)
Read parameters and initialize.
const Vertex & vertex(int id) const
virtual void solve(double phiTot=1.0)
Solve modified diffusion equation for all propagators.
void readBlocks(std::istream &in) final
Read array of data for blocks from parameter file.
~PolymerTmpl()
Destructor.
PT & propagator(int blockId, int directionId)
Get the propagator for a specific block and direction (non-const).
int nPropagator() const
Number of propagators (2*nBlock).
virtual void readParameters(std::istream &in)
Read and initialize.
int nBlock() const
Number of blocks.
PolymerTmpl()
Constructor.
void allocateBlocks() final
Allocate array of Block objects.
Pair< int > const & propagatorId(int id) const
Get a propagator identifier, indexed by order of computation.
void setQ(double q)
Set q and compute phi or mu (depending on the ensemble).
Definition Species.cpp:63
A junction or chain end in a block polymer.
Definition Vertex.h:31
int size() const
Get the number of attached blocks.
Definition Vertex.h:110
Pair< int > const & inPropagatorId(int i) const
Get the block and direction of an incoming propagator.
Definition Vertex.h:114
An array of exactly 2 objects.
Definition Pair.h:24
DArrayParam< Type > & readDArray(std::istream &in, const char *label, DArray< Type > &array, int n)
Add and read a required DArray < Type > parameter.
void setClassName(const char *className)
Set class name string.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
PSCF package top-level namespace.