PSCF v1.3
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/domain/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 QFieldT& 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 QFieldT 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 QFieldT& 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 */
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 QFieldT const& qh = head();
149 QFieldT const& qt = partner().tail();
150 return block().domain().innerProduct(qh, qt);
151 }
152
153}
154}
const Propagator & partner() const
const Propagator & source(int id) const
DArray< double > QFieldT
Propagator q-field type.
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.
QFieldT const & head() const
Return q-field at beginning of block (initial condition).
double computeQ()
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.
#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.
Definition param_pc.dox:1