PSCF v1.4.0
ExplicitBdStep.tpp
1#ifndef RP_EXPLICIT_BD_STEP_TPP
2#define RP_EXPLICIT_BD_STEP_TPP
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 "ExplicitBdStep.h"
12#include <pscf/math/IntVec.h>
13
14namespace Pscf {
15namespace Rp {
16
17 using namespace Util;
18 using namespace Prdc;
19
20 /*
21 * Constructor.
22 */
23 template <int D, class T>
24 ExplicitBdStep<D,T>::ExplicitBdStep(typename T::BdSimulator& simulator)
25 : BdStepT(simulator),
26 w_(),
27 dwc_(),
28 gaussianField_(),
29 mobility_(0.0)
30 { ParamComposite::setClassName("ExplicitBdStep"); }
31
32 /*
33 * Read body of parameter file block and allocate memory.
34 */
35 template <int D, class T>
37 {
38 ParamComposite::read(in, "mobility", mobility_);
39
40 // Allocate memory
41 int nMonomer = system().mixture().nMonomer();
42 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
43 w_.allocate(nMonomer);
44 for (int i=0; i < nMonomer; ++i) {
45 w_[i].allocate(meshDimensions);
46 }
47 dwc_.allocate(meshDimensions);
48 }
49
50 /*
51 * Setup before entering simulation loop.
52 */
53 template <int D, class T>
55 {
56 // Check array capacities
57 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
58 int meshSize = system().domain().mesh().size();
59 int nMonomer = system().mixture().nMonomer();
60 UTIL_CHECK(w_.capacity() == nMonomer);
61 for (int i = 0; i < nMonomer; ++i) {
62 UTIL_CHECK(w_[i].capacity() == meshSize);
63 }
64 UTIL_CHECK(dwc_.capacity() == meshSize);
65 gaussianField_.allocate(meshDimensions);
66 }
67
68 /*
69 * Take a single BD step.
70 */
71 template <int D, class T>
73 {
74 // Array sizes and indices
75 const int nMonomer = system().mixture().nMonomer();
76 const int meshSize = system().domain().mesh().size();
77 int i, j;
78
79 // Save current state
80 simulator().saveState();
81
82 // Copy current W fields from parent system into w_
83 for (i = 0; i < nMonomer; ++i) {
84 VecOp::eqV(w_[i], system().w().rgrid(i));
85 }
86
87 // Constants for dynamics
88 const double vSystem = system().domain().unitCell().volume();
89 const double a = -1.0*mobility_;
90 const double b = sqrt(2.0*mobility_*double(meshSize)/vSystem);
91
92 // Constants for normal distribution
93 const double stddev = 1.0;
94 const double mean = 0.0;
95
96 // Modify local field copy wc_
97 // Loop over eigenvectors of projected chi matrix
98 double evec;
99 for (j = 0; j < nMonomer - 1; ++j) {
100
101 // Generate normal distributed random numbers
102 vecRandom().normal(gaussianField_, stddev, mean);
103
104 // Compute change dwc_
105 typename T::RField const & dc = simulator().dc(j);
106 VecOp::addVcVc(dwc_, dc, a, gaussianField_, b);
107
108 // Loop over monomer types
109 for (i = 0; i < nMonomer; ++i) {
110 typename T::RField & w = w_[i];
111 evec = simulator().chiEvecs(j,i);
112 VecOp::addEqVc(w, dwc_, evec);
113 }
114
115 }
116
117 // Set modified fields in parent system
118 system().w().setRGrid(w_);
119 simulator().clearData();
120
121 // Enforce incompressibility (also solves MDE repeatedly)
122 bool isConverged = false;
123 int compress = simulator().compressor().compress();
124 if (compress != 0){
125 simulator().restoreState();
126 } else {
127 isConverged = true;
128 UTIL_CHECK(system().c().hasData());
129
130 // Evaluate component properties in new state
131 simulator().clearState();
132 simulator().computeWc();
133 simulator().computeCc();
134 simulator().computeDc();
135 }
136
137 return isConverged;
138 }
139
140}
141}
142#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
void setup() override
Setup before simulation.
bool step() override
Take a single Brownian dynamics step.
void readParameters(std::istream &in) override
Read body of parameter file block.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
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
void eqV(Array< double > &a, Array< double > const &b, const int beginIdA, const int beginIdB, const int n)
Vector assignment, a[i] = b[i] (real, slice).
Definition VecOp.cpp:21
void addEqVc(Array< double > &a, Array< double > const &b, const double c)
Add scaled vector in-place, a[i] += b[i]*c (real).
Definition VecOp.cpp:395
Periodic fields and crystallography.
Definition complex.cpp:11
Class templates for real-valued periodic fields.
void addVcVc(Array< double > &a, Array< double > const &b1, const double c1, Array< double > const &b2, const double c2)
Add two scaled vectors, a[i] = b1[i]*c1 + b2[2]*c2 (real).
Definition VecOp.cpp:364
PSCF package top-level namespace.