PSCF v1.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" // base class
12
13namespace Pscf
14{
15
16 class Edge;
17 using namespace Util;
18
19 /*
20 * Constructor.
21 */
22 template <class BT>
25 blocks_()
26 { setClassName("PolymerTmpl"); }
27
28 /*
29 * Destructor.
30 */
31 template <class BT>
34
35 /*
36 * Allocate blocks array.
37 */
38 template <class BT>
40 { blocks_.allocate(nBlock()); }
41
42 /*
43 * Read blocks array from parameter file.
44 */
45 template <class BT>
46 void PolymerTmpl<BT>::readBlocks(std::istream& in)
47 { readDArray<BT>(in, "blocks", blocks_, nBlock()); }
48
49 /*
50 * Read parameter file block.
51 */
52 template <class BT>
53 void PolymerTmpl<BT>::readParameters(std::istream& in)
54 {
55
56 // Call PoymerSpecies base class member function
57 // Initializes PolymerSpecies, and Edge and Vertex components
59
60 // The remainder of this function sets and validates immutable
61 // information about graph topology that is stored by propagators.
62
63 PropagatorT * propagatorPtr = nullptr;
64 PropagatorT const * sourcePtr = nullptr;
65 Vertex const * headPtr = nullptr;
66 Vertex const * tailPtr = nullptr;
67 Pair<int> propId;
68 int blockId, forwardId, reverseId, headId, tailId, i;
69 bool isHeadEnd, isTailEnd;
70
71 // Set sources and end flags for all propagators
72 for (blockId = 0; blockId < nBlock(); ++blockId) {
73 for (forwardId = 0; forwardId < 2; ++forwardId) {
74
75 propagatorPtr = &block(blockId).propagator(forwardId);
77 // Identify head and tail vertices
78 if (forwardId == 0) {
79 reverseId = 1;
80 } else {
81 reverseId = 0;
82 }
83 headId = block(blockId).vertexId(forwardId);
84 tailId = block(blockId).vertexId(reverseId);
85 headPtr = &vertex(headId); // pointer to head vertex
86 tailPtr = &vertex(tailId); // pointer to tail vertex
87
88 // Add pointers to source propagators
89 for (i = 0; i < headPtr->size(); ++i) {
90 propId = headPtr->inPropagatorId(i);
91 if (propId[0] == blockId) {
92 UTIL_CHECK(propId[1] != forwardId);
93 } else {
94 sourcePtr =
95 &block(propId[0]).propagator(propId[1]);
96 propagatorPtr->addSource(*sourcePtr);
97 }
98 }
99
100 // Set vertex end flags
101 isHeadEnd = (headPtr->size() == 1) ? true : false;
102 isTailEnd = (tailPtr->size() == 1) ? true : false;
103 propagatorPtr->setEndFlags(isHeadEnd, isTailEnd);
104
105 } // end loop over forwardId (propagator direction id)
106 } // end loop over blockId
107
108 // Check validity - throw Exception if error detected
109 isValid();
110 }
111
112 /*
113 * Checks validity of propagator data set in readParameters.
114 *
115 * This function only checks validity of propagator source and end flag
116 * member data that is set in PolymerTmpl<BT>::readParameters. It
117 * does not check validity of members of PolymerSpecies, Edge, and Vertex
118 * that are set and validated within the PolymerSpecies::readParameters
119 * base class member function.
120 */
121 template <class BT>
122 void PolymerTmpl<BT>::isValid()
123 {
124 Vertex const * v0Ptr = nullptr;
125 Vertex const * v1Ptr = nullptr;
126 PropagatorT const * p0Ptr = nullptr;
127 PropagatorT const * p1Ptr = nullptr;
128 int bId, v0Id, v1Id;
129
130 // Loop over blocks
131 for (bId = 0; bId < nBlock(); ++bId) {
132 v0Id = block(bId).vertexId(0);
133 v1Id = block(bId).vertexId(1);
134 UTIL_CHECK(v0Id >= 0 && v0Id < nVertex());
135 UTIL_CHECK(v1Id >= 0 && v1Id < nVertex());
136 UTIL_CHECK(v0Id != v1Id);
137 v0Ptr = &vertex(v0Id);
138 v1Ptr = &vertex(v1Id);
139 p0Ptr = &(block(bId).propagator(0));
140 p1Ptr = &(block(bId).propagator(1));
141 UTIL_CHECK(p0Ptr->nSource() == (v0Ptr->size() - 1));
142 UTIL_CHECK(p1Ptr->nSource() == (v1Ptr->size() - 1));
143 UTIL_CHECK(p0Ptr->isHeadEnd() == p1Ptr->isTailEnd());
144 UTIL_CHECK(p0Ptr->isHeadEnd() == (v0Ptr->size() == 1));
145 UTIL_CHECK(p1Ptr->isHeadEnd() == (v1Ptr->size() == 1));
146 }
147
148 }
149
150 /*
151 * Solve the MDE for all blocks of this polymer.
152 */
153 template <class BT>
154 void PolymerTmpl<BT>::solve(double phiTot)
155 {
156
157 // Clear all propagators
158 for (int j = 0; j < nPropagator(); ++j) {
159 propagator(j).setIsSolved(false);
160 }
161
162 // Solve modified diffusion equation for all propagators in
163 // the order specified by function makePlan.
164 for (int j = 0; j < nPropagator(); ++j) {
165 UTIL_CHECK(propagator(j).isReady());
166 propagator(j).solve();
167 }
168
169 // Compute molecular partition function Q
170 double Q = block(0).propagator(0).computeQ();
171
172 // The PropagatorT::computeQ function returns a spatial average.
173 // Correct for partial occupation of the unit cell.
174 Q = Q/phiTot;
175
176 // Set q and compute phi or mu, depending on the ensemble
177 Species::setQ(Q);
178
179 }
180
181}
182#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
typename BT::PropagatorT PropagatorT
Modified diffusion equation solver for one block, in one direction.
Definition PolymerTmpl.h:64
void allocateBlocks() final
Allocate array of Block objects.
void readBlocks(std::istream &in) final
Read array of data for blocks from parameter file.
~PolymerTmpl()
Destructor.
int nPropagator() const
Number of propagators (2*nBlock).
int nBlock() const
Number of blocks.
virtual void readParameters(std::istream &in)
Read and initialize.
PropagatorT & propagator(int blockId, int directionId)
Get the propagator for a specific block and direction (non-const).
virtual void solve(double phiTot=1.0)
Solve modified diffusion equation for all propagators.
PolymerTmpl()
Constructor.
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.
Definition param_pc.dox:1