PSCF v1.1
fd1d/solvers/Propagator.cpp
1/*
2* PSCF - Polymer Self-Consistent Field Theory
3*
4* Copyright 2016 - 2022, 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 <fd1d/domain/Domain.h>
11
12namespace Pscf {
13namespace Fd1d
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 */
32 {}
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
71
73 { return isAllocated_; }
74
75 /*
76 * Compute initial head QField from final tail QFields of sources.
77 */
78 void Propagator::computeHead()
79 {
80
81 // Reference to head of this propagator
82 QField& qh = qFields_[0];
83
84 // Initialize qh field to 1.0 at all grid points
85 int ix;
86 for (ix = 0; ix < nx_; ++ix) {
87 qh[ix] = 1.0;
88 }
89
90 // Pointwise multiply tail QFields of all sources
91 for (int is = 0; is < nSource(); ++is) {
92 if (!source(is).isSolved()) {
93 UTIL_THROW("Source not solved in computeHead");
94 }
95 QField const& qt = source(is).tail();
96 for (ix = 0; ix < nx_; ++ix) {
97 qh[ix] *= qt[ix];
98 }
99 }
100 }
101
102 /*
103 * Solve the modified diffusion equation for this block.
104 */
106 {
107 computeHead();
108 for (int iStep = 0; iStep < ns_ - 1; ++iStep) {
109 block().step(qFields_[iStep], qFields_[iStep + 1]);
110 }
111 setIsSolved(true);
112 }
113
114 /*
115 * Solve the modified diffusion equation with specified initial field.
116 */
118 {
119 // Initialize initial (head) field
120 QField& qh = qFields_[0];
121 for (int i = 0; i < nx_; ++i) {
122 qh[i] = head[i];
123 }
124
125 // Setup solver and solve
126 for (int iStep = 0; iStep < ns_ - 1; ++iStep) {
127 block().step(qFields_[iStep], qFields_[iStep + 1]);
128 }
129 setIsSolved(true);
130 }
131
132 /*
133 * Integrate to calculate monomer concentration for this block
134 */
136 {
137 if (!isSolved()) {
138 UTIL_THROW("Propagator is not solved.");
139 }
140 if (!hasPartner()) {
141 UTIL_THROW("Propagator has no partner set.");
142 }
143 if (!partner().isSolved()) {
144 UTIL_THROW("Partner propagator is not solved");
145 }
146 QField const& qh = head();
147 QField const& qt = partner().tail();
148 return block().domain().innerProduct(qh, qt);
149 }
150
151}
152}
Domain const & domain() const
Return associated domain by reference.
void step(DArray< double > const &q, DArray< double > &qNew)
Compute one step of integration loop, from i to i+1.
double innerProduct(Field const &f, Field const &g) const
Compute inner product of two real fields.
DArray< double > QField
Propagator q-field type.
void solve()
Solve the modified diffusion equation (MDE) for this block.
double computeQ()
Compute and return partition function for the molecule.
void reallocate(int ns)
Reallocate memory used by this propagator.
QField const & head() const
Return q-field at beginning of block (initial condition).
int ns() const
Number of values of s (or slices), including head and tail.
bool isAllocated() const
Has memory been allocated for this propagator?
void allocate(int ns, int nx)
Set discretization and allocate memory.
void setIsSolved(bool isSolved)
Set the isSolved flag to true or false.
const Propagator & partner() const
Get partner propagator.
const Propagator & source(int id) const
Get a source propagator.
bool isSolved() const
Has the modified diffusion equation been solved?
bool hasPartner() const
Does this have a partner propagator?
int nSource() const
Number of source / prerequisite propagators.
#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:51
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1