PSCF v1.1
fd1d/solvers/Mixture.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 "Mixture.h"
9#include <fd1d/domain/Domain.h>
10
11#include <cmath>
12
13namespace Pscf {
14namespace Fd1d
15{
16
18 : ds_(-1.0),
19 domainPtr_(0)
20 { setClassName("Mixture"); }
21
23 {}
24
25 void Mixture::readParameters(std::istream& in)
26 {
28
29 // Read optimal contour step size
30 read(in, "ds", ds_);
31
32 UTIL_CHECK(nMonomer() > 0);
34 UTIL_CHECK(ds_ > 0);
35 }
36
37 void Mixture::setDomain(Domain const& domain)
38 {
39 UTIL_CHECK(nMonomer() > 0);
41 UTIL_CHECK(ds_ > 0);
42
43 domainPtr_ = &domain;
44
45 // Process polymers - set discretization for all blocks
46 if (nPolymer() > 0) {
47 int i, j;
48 for (i = 0; i < nPolymer(); ++i) {
49 for (j = 0; j < polymer(i).nBlock(); ++j) {
50 polymer(i).block(j).setDiscretization(domain, ds_);
51 }
52 }
53 }
54
55 // Process solvents - set discretization for all solvents
56 if (nSolvent() > 0) {
57 for (int i = 0; i < nSolvent(); ++i) {
58 solvent(i).setDiscretization(domain);
59 }
60 }
61
62 }
63
64 /*
65 * Reset statistical segment length for one monomer type.
66 */
67 void Mixture::setKuhn(int monomerId, double kuhn)
68 {
69 // Set new Kuhn length for relevant Monomer object
70 monomer(monomerId).setKuhn(kuhn);
71
72 // Update kuhn length for all blocks of this monomer type
73 for (int i = 0; i < nPolymer(); ++i) {
74 for (int j = 0; j < polymer(i).nBlock(); ++j) {
75 if (monomerId == polymer(i).block(j).monomerId()) {
76 polymer(i).block(j).setKuhn(kuhn);
77 }
78 }
79 }
80 }
81
82 /*
83 * Compute concentrations (but not total free energy).
84 */
87 {
88 UTIL_CHECK(domainPtr_);
89 UTIL_CHECK(domain().nx() > 0);
90 UTIL_CHECK(nMonomer() > 0);
91 UTIL_CHECK(nPolymer() + nSolvent() > 0);
92 UTIL_CHECK(wFields.capacity() == nMonomer());
93 UTIL_CHECK(cFields.capacity() == nMonomer());
94
95 int nx = domain().nx();
96 int nm = nMonomer();
97 int i, j, k;
98
99 // Clear all monomer concentration fields
100 for (i = 0; i < nm; ++i) {
101 UTIL_CHECK(cFields[i].capacity() == nx);
102 UTIL_CHECK(wFields[i].capacity() == nx);
103 for (j = 0; j < nx; ++j) {
104 cFields[i][j] = 0.0;
105 }
106 }
107
108 // Process polymer species
109 if (nPolymer() > 0) {
110
111 for (i = 0; i < nPolymer(); ++i) {
112
113 // Solve MDE for all blocks in polymer
114 polymer(i).compute(wFields);
115
116 // Accumulate monomer concentrations
117 for (j = 0; j < polymer(i).nBlock(); ++j) {
118 int monomerId = polymer(i).block(j).monomerId();
119 UTIL_CHECK(monomerId >= 0);
120 UTIL_CHECK(monomerId < nm);
121 CField& monomerField = cFields[monomerId];
122 CField const & blockField = polymer(i).block(j).cField();
123 for (k = 0; k < nx; ++k) {
124 monomerField[k] += blockField[k];
125 }
126 }
127
128 }
129
130 }
131
132 // Process solvent species
133 if (nSolvent() > 0) {
134 for (i = 0; i < nSolvent(); ++i) {
135
136 int monomerId = solvent(i).monomerId();
137 UTIL_CHECK(monomerId >= 0);
138 UTIL_CHECK(monomerId < nm);
139
140 // Compute solvent concentration and q
141 solvent(i).compute(wFields[monomerId]);
142
143 // Add to monomer concentrations
144 CField& monomerField = cFields[monomerId];
145 CField const & solventField = solvent(i).cField();
146 for (k = 0; k < nx; ++k) {
147 monomerField[k] += solventField[k];
148 }
149
150 }
151 }
152
153 }
154
155} // namespace Fd1d
156} // namespace Pscf
One-dimensional spatial domain and discretization grid.
int nx() const
Get number of spatial grid points, including both endpoints.
void readParameters(std::istream &in)
Read all parameters and initialize.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void setKuhn(int monomerId, double kuhn)
Reset statistical segment length for one monomer type.
void setDomain(Domain const &domain)
Create an association with the domain and allocate memory.
void compute(DArray< WField > const &wFields, DArray< CField > &cFields)
Compute concentrations.
Polymer & polymer(int id)
Get a polymer object.
Definition: MixtureTmpl.h:220
int nSolvent() const
Get number of solvent (point particle) species.
Definition: MixtureTmpl.h:198
int nMonomer() const
Get number of monomer types.
Definition: MixtureTmpl.h:190
Monomer const & monomer(int id) const
Get a Monomer type descriptor (const reference).
Definition: MixtureTmpl.h:206
Solvent & solvent(int id)
Set a solvent solver object.
Definition: MixtureTmpl.h:234
virtual void readParameters(std::istream &in)
Read parameters from file and initialize.
Definition: MixtureTmpl.h:280
int nPolymer() const
Get number of polymer species.
Definition: MixtureTmpl.h:194
void setKuhn(double kuhn)
Set statistical segment length.
Definition: Monomer.h:126
int capacity() const
Return allocated size.
Definition: Array.h:159
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
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
C++ namespace for polymer self-consistent field theory (PSCF).