PSCF v1.3
PolymerTmpl.h
1#ifndef PSCF_POLYMER_TMPL_H
2#define PSCF_POLYMER_TMPL_H
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 <pscf/chem/PolymerSpecies.h> // base class
12#include <util/param/ParamComposite.h> // base class
13
14#include <util/containers/Pair.h> // member template
15#include <util/containers/DArray.h> // member template
16
17#include <pscf/chem/Vertex.h>
18#include <pscf/chem/PolymerType.h>
19#include <pscf/chem/PolymerModel.h>
20
21namespace Pscf
22{
23
24 class Edge;
25 using namespace Util;
26
48 template <class BT>
50 {
51
52 public:
53
54 // Public typename aliases
55
59 using BlockT = BT;
60
64 using PropagatorT = typename BT::PropagatorT;
65
66 // Public member functions
67
72
77
83 virtual void readParameters(std::istream& in);
84
115 virtual void solve(double phiTot = 1.0);
116
119
129 Edge& edge(int id) final;
130
136 Edge const& edge(int id) const final;
137
143 BT& block(int id);
144
150 BT const& block(int id) const ;
151
164 PropagatorT& propagator(int blockId, int directionId);
165
172 PropagatorT const & propagator(int blockId, int directionId) const;
173
182
184
185 // Inherited public members
186
196
197 using Species::phi;
198 using Species::mu;
199 using Species::q;
200 using Species::ensemble;
201
202 protected:
203
207 void allocateBlocks() final;
208
214 void readBlocks(std::istream& in) final;
215
216 private:
217
219 DArray<BlockT> blocks_;
220
226 void isValid();
227
228 };
229
230 // Inline functions
231
232 /*
233 * Get a specified Edge (block descriptor) by non-const reference.
234 */
235 template <class BT>
236 inline
237 Edge& PolymerTmpl<BT>::edge(int id)
238 { return blocks_[id]; }
239
240 /*
241 * Get a specified Edge (block descriptor) by const reference.
242 */
243 template <class BT>
244 inline
245 Edge const & PolymerTmpl<BT>::edge(int id) const
246 { return blocks_[id]; }
247
248 /*
249 * Get a specified Block solver by non-const reference.
250 */
251 template <class BT>
252 inline
254 { return blocks_[id]; }
255
256 /*
257 * Get a specified Block solver by const reference.
258 */
259 template <class BT>
260 inline
261 BT const & PolymerTmpl<BT>::block(int id) const
262 { return blocks_[id]; }
263
264 /*
265 * Get a propagator, indexed by block and direction ids (non-const).
266 */
267 template <class BT>
268 inline
269 typename BT::PropagatorT&
270 PolymerTmpl<BT>::propagator(int blockId, int directionId)
271 { return block(blockId).propagator(directionId); }
272
273 /*
274 * Get a propagator, indexed by block and direction ids (const).
275 */
276 template <class BT>
277 inline
278 typename BT::PropagatorT const &
279 PolymerTmpl<BT>::propagator(int blockId, int directionId) const
280 { return block(blockId).propagator(directionId); }
281
282 /*
283 * Get a propagator, indexed in order of computation.
284 */
285 template <class BT>
286 inline
287 typename BT::PropagatorT& PolymerTmpl<BT>::propagator(int id)
288 {
289 Pair<int> propId = propagatorId(id);
290 return propagator(propId[0], propId[1]);
291 }
292
293 #if 0
294 // Non-inline functions
295
296 /*
297 * Constructor.
298 */
299 template <class BT>
301 : PolymerSpecies(),
302 blocks_()
303 { setClassName("PolymerTmpl"); }
304
305 /*
306 * Destructor.
307 */
308 template <class BT>
310 {}
311
312 /*
313 * Allocate blocks array.
314 */
315 template <class BT>
317 { blocks_.allocate(nBlock()); }
318
319 /*
320 * Read blocks array from parameter file.
321 */
322 template <class BT>
323 void PolymerTmpl<BT>::readBlocks(std::istream& in)
324 { readDArray<BT>(in, "blocks", blocks_, nBlock()); }
325
326 /*
327 * Read parameter file block.
328 */
329 template <class BT>
330 void PolymerTmpl<BT>::readParameters(std::istream& in)
331 {
332
333 // Call PoymerSpecies base class member function
334 // Initializes PolymerSpecies, and Edge and Vertex components
336
337 // The remainder of this function sets and validates immutable
338 // information about graph topology that is stored by propagators.
339
340 PropagatorT * propagatorPtr = nullptr;
341 PropagatorT const * sourcePtr = nullptr;
342 Vertex const * headPtr = nullptr;
343 Vertex const * tailPtr = nullptr;
344 Pair<int> propId;
345 int blockId, forwardId, reverseId, headId, tailId, i;
346 bool isHeadEnd, isTailEnd;
347
348 // Set sources and end flags for all propagators
349 for (blockId = 0; blockId < nBlock(); ++blockId) {
350 for (forwardId = 0; forwardId < 2; ++forwardId) {
351
352 propagatorPtr = &block(blockId).propagator(forwardId);
353
354 // Identify head and tail vertices
355 if (forwardId == 0) {
356 reverseId = 1;
357 } else {
358 reverseId = 0;
359 }
360 headId = block(blockId).vertexId(forwardId);
361 tailId = block(blockId).vertexId(reverseId);
362 headPtr = &vertex(headId); // pointer to head vertex
363 tailPtr = &vertex(tailId); // pointer to tail vertex
364
365 // Add pointers to source propagators
366 for (i = 0; i < headPtr->size(); ++i) {
367 propId = headPtr->inPropagatorId(i);
368 if (propId[0] == blockId) {
369 UTIL_CHECK(propId[1] != forwardId);
370 } else {
371 sourcePtr =
372 &block(propId[0]).propagator(propId[1]);
373 propagatorPtr->addSource(*sourcePtr);
374 }
375 }
376
377 // Set vertex end flags
378 isHeadEnd = (headPtr->size() == 1) ? true : false;
379 isTailEnd = (tailPtr->size() == 1) ? true : false;
380 propagatorPtr->setEndFlags(isHeadEnd, isTailEnd);
381
382 } // end loop over forwardId (propagator direction id)
383 } // end loop over blockId
384
385 // Check validity - throw Exception if error detected
386 isValid();
387 }
388
389 /*
390 * Checks validity of propagator data set in readParameters.
391 *
392 * This function only checks validity of propagator source and end flag
393 * member data that is set in PolymerTmpl<BT>::readParameters. It
394 * does not check validity of members of PolymerSpecies, Edge, and Vertex
395 * that are set and validated within the PolymerSpecies::readParameters
396 * base class member function.
397 */
398 template <class BT>
399 void PolymerTmpl<BT>::isValid()
400 {
401 Vertex const * v0Ptr = nullptr;
402 Vertex const * v1Ptr = nullptr;
403 PropagatorT const * p0Ptr = nullptr;
404 PropagatorT const * p1Ptr = nullptr;
405 int bId, v0Id, v1Id;
406
407 // Loop over blocks
408 for (bId = 0; bId < nBlock(); ++bId) {
409 v0Id = block(bId).vertexId(0);
410 v1Id = block(bId).vertexId(1);
411 UTIL_CHECK(v0Id >= 0 && v0Id < nVertex());
412 UTIL_CHECK(v1Id >= 0 && v1Id < nVertex());
413 UTIL_CHECK(v0Id != v1Id);
414 v0Ptr = &vertex(v0Id);
415 v1Ptr = &vertex(v1Id);
416 p0Ptr = &(block(bId).propagator(0));
417 p1Ptr = &(block(bId).propagator(1));
418 UTIL_CHECK(p0Ptr->nSource() == (v0Ptr->size() - 1));
419 UTIL_CHECK(p1Ptr->nSource() == (v1Ptr->size() - 1));
420 UTIL_CHECK(p0Ptr->isHeadEnd() == p1Ptr->isTailEnd());
421 UTIL_CHECK(p0Ptr->isHeadEnd() == (v0Ptr->size() == 1));
422 UTIL_CHECK(p1Ptr->isHeadEnd() == (v1Ptr->size() == 1));
423 }
424
425 }
426
427 /*
428 * Solve the MDE for all blocks of this polymer.
429 */
430 template <class BT>
431 void PolymerTmpl<BT>::solve(double phiTot)
432 {
433
434 // Clear all propagators
435 for (int j = 0; j < nPropagator(); ++j) {
436 propagator(j).setIsSolved(false);
437 }
438
439 // Solve modified diffusion equation for all propagators in
440 // the order specified by function makePlan.
441 for (int j = 0; j < nPropagator(); ++j) {
442 UTIL_CHECK(propagator(j).isReady());
443 propagator(j).solve();
444 }
445
446 // Compute molecular partition function Q
447 double Q = block(0).propagator(0).computeQ();
448
449 // The PropagatorT::computeQ function returns a spatial average.
450 // Correct for partial occupation of the unit cell.
451 Q = Q/phiTot;
452
453 // Set q and compute phi or mu, depending on the ensemble
454 Species::setQ(Q);
455
456 }
457 #endif
458
459}
460#include "PolymerTmpl.tpp"
461#endif
Descriptor for a block within a block polymer.
Definition Edge.h:59
Descriptor for a linear or acyclic branched block polymer.
const Vertex & vertex(int id) const
Get a specified Vertex by const reference.
PolymerSpecies()
Constructor.
Pair< int > const & path(int is, int it) const
Get an id for a propagator from one vertex towards a target.
int nVertex() const
Number of vertices (junctions and chain ends).
virtual void readParameters(std::istream &in)
Read parameters and initialize.
int nPropagator() const
Number of propagators (2*nBlock).
int nBead() const
Total number of beads in the polymer (bead model).
int nBlock() const
Number of blocks.
double length() const
Sum of the lengths of all blocks in the polymer (thread model).
Pair< int > const & propagatorId(int id) const
Get a propagator identifier, indexed by order of computation.
PolymerType::Enum type() const
Get Polymer type (Branched or Linear)
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.
BT const & block(int id) const
Get a specified Block (solver and descriptor) by const reference.
void readBlocks(std::istream &in) final
~PolymerTmpl()
Destructor.
PropagatorT const & propagator(int blockId, int directionId) const
Get the propagator for a specific block and direction (const).
PropagatorT & propagator(int id)
Get a propagator indexed in order of computation (non-const).
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).
Edge const & edge(int id) const final
Get a specified Edge (block descriptor) by const reference.
BT BlockT
Block of a block polymer.
Definition PolymerTmpl.h:59
virtual void solve(double phiTot=1.0)
Solve modified diffusion equation for all propagators.
PolymerTmpl()
Constructor.
Pair< int > const & propagatorId(int id) const
Get a propagator identifier, indexed by order of computation.
Edge & edge(int id) final
Get a specified Edge (block descriptor) by non-const reference.
BT & block(int id)
Get a specified Block (solver and descriptor).
double phi() const
Get the overall volume fraction for this species.
Definition Species.h:149
void setQ(double q)
Set q and compute phi or mu (depending on the ensemble).
Definition Species.cpp:63
double mu() const
Get the chemical potential for this species (units kT=1).
Definition Species.h:155
Ensemble ensemble() const
Get the statistical ensemble for this species (open or closed).
Definition Species.h:167
double q() const
Get the molecular partition function for this species.
Definition Species.h:161
A junction or chain end in a block polymer.
Definition Vertex.h:31
Dynamically allocatable contiguous array template.
Definition DArray.h:32
An array of exactly 2 objects.
Definition Pair.h:24
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