PSCF v1.4.0
r1d/solvers/Propagator.cpp
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 "Propagator.h"
9#include "Block.h"
10#include <r1d/field/Domain.h>
11
12namespace Pscf {
13namespace R1d
14{
15
16 using namespace Util;
17
18 /*
19 * Constructor.
20 */
22 : blockPtr_(0),
23 ns_(0),
24 nx_(0),
25 isAllocated_(false)
26 {}
27
28 /*
29 * Destructor.
30 */
33
34 /*
35 * Allocate memory used by this propagator.
36 */
37 void Propagator::allocate(int ns, int nx)
38 {
39 ns_ = ns;
40 nx_ = nx;
41 qFields_.allocate(ns);
42 for (int i = 0; i < ns; ++i) {
43 qFields_[i].allocate(nx);
44 }
45 isAllocated_ = true;
46 }
47
48 /*
49 * Reallocate memory used by this propagator using new ns value.
50 */
52 {
53 UTIL_CHECK(isAllocated_);
54 UTIL_CHECK(ns_ != ns);
55 ns_ = ns;
56
57 // Deallocate memory previously used by this propagator.
58 // NOTE: DArray::deallocate() calls "delete [] ptr", where ptr is a
59 // pointer to the underlying C array. This will call the destructor
60 // for each element in the underlying C array, freeing all memory
61 // that was allocated to the objects stored in the DArray.
62 qFields_.deallocate();
63
64 // Allocate memory in qFields_ using new value of ns
65 qFields_.allocate(ns);
66 for (int i = 0; i < ns; ++i) {
67 qFields_[i].allocate(nx_);
68 }
69
70 setIsSolved(false);
71 }
72
73
75 { return isAllocated_; }
76
77 /*
78 * Compute initial head q-field from final tail q-fields of sources.
79 */
80 void Propagator::computeHead()
81 {
82
83 // Reference to head of this propagator
84 FieldT& qh = qFields_[0];
85
86 // Initialize qh field to 1.0 at all grid points
87 int ix;
88 for (ix = 0; ix < nx_; ++ix) {
89 qh[ix] = 1.0;
90 }
91
92 // Pointwise multiply tail q-fields of all sources
93 for (int is = 0; is < nSource(); ++is) {
94 if (!source(is).isSolved()) {
95 UTIL_THROW("Source not solved in computeHead");
96 }
97 FieldT const& qt = source(is).tail();
98 for (ix = 0; ix < nx_; ++ix) {
99 qh[ix] *= qt[ix];
100 }
101 }
102 }
103
104 /*
105 * Solve the modified diffusion equation for this block.
106 */
108 {
109 computeHead();
110 for (int iStep = 0; iStep < ns_ - 1; ++iStep) {
111 block().step(qFields_[iStep], qFields_[iStep + 1]);
112 }
113 setIsSolved(true);
114 }
115
116 /*
117 * Solve the modified diffusion equation with specified initial field.
118 */
120 {
121 // Initialize initial (head) field
122 FieldT& qh = qFields_[0];
123 for (int i = 0; i < nx_; ++i) {
124 qh[i] = head[i];
125 }
126
127 // Setup solver and solve
128 for (int iStep = 0; iStep < ns_ - 1; ++iStep) {
129 block().step(qFields_[iStep], qFields_[iStep + 1]);
130 }
131 setIsSolved(true);
132 }
133
134 /*
135 * Integrate to calculate monomer concentration for this block
136 */
137 void Propagator::computeQ(double & Q)
138 {
139 if (!isSolved()) {
140 UTIL_THROW("Propagator is not solved.");
141 }
142 if (!hasPartner()) {
143 UTIL_THROW("Propagator has no partner set.");
144 }
145 if (!partner().isSolved()) {
146 UTIL_THROW("Partner propagator is not solved");
147 }
148 FieldT const& qh = head();
149 FieldT const& qt = partner().tail();
150 Q = block().domain().innerProduct(qh, qt);
151 }
152
153}
154}
const Propagator & partner() const
const Propagator & source(int id) const
FieldT const & head() const
Return q-field at beginning of block (initial condition).
bool isAllocated() const
Has memory been allocated for this propagator?
int ns() const
Number of values of s (or slices), including head and tail.
void solve()
Solve the modified diffusion equation (MDE) for this block.
void computeQ(double &Q)
Compute and return partition function for the molecule.
void reallocate(int ns)
Reallocate memory used by this propagator.
void allocate(int ns, int nx)
Set discretization and allocate memory.
DArray< double > FieldT
Generic field (function of position).
#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
SCFT with real 1D fields.
PSCF package top-level namespace.