PSCF v1.3.3
rpc/fts/brownian/ExplicitBdStep.tpp
1#ifndef RPC_EXPLICIT_BD_STEP_TPP
2#define RPC_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 <rpc/system/System.h>
13#include <rpc/solvers/Mixture.h>
14#include <rpc/field/Domain.h>
15#include <rpc/fts/brownian/BdSimulator.h>
16#include <rpc/fts/compressor/Compressor.h>
17#include <pscf/math/IntVec.h>
18#include <util/random/Random.h>
19
20namespace Pscf {
21namespace Rpc {
22
23 using namespace Util;
24 using namespace Prdc::Cpu;
25
26 /*
27 * Constructor.
28 */
29 template <int D>
31 : BdStep<D>(simulator),
32 w_(),
33 dwc_(),
34 mobility_(0.0)
35 {}
36
37 /*
38 * Destructor, empty default implementation.
39 */
40 template <int D>
43
44 /*
45 * ReadParameters, empty default implementation.
46 */
47 template <int D>
48 void ExplicitBdStep<D>::readParameters(std::istream &in)
49 {
50 read(in, "mobility", mobility_);
51
52 // Allocate memory for private containers
53 int nMonomer = system().mixture().nMonomer();
54 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
55 w_.allocate(nMonomer);
56 for (int i=0; i < nMonomer; ++i) {
57 w_[i].allocate(meshDimensions);
58 }
59 dwc_.allocate(meshDimensions);
60
61 }
62
63 template <int D>
65 {
66 // Check array capacities
67 int meshSize = system().domain().mesh().size();
68 int nMonomer = system().mixture().nMonomer();
69 UTIL_CHECK(w_.capacity() == nMonomer);
70 for (int i=0; i < nMonomer; ++i) {
71 UTIL_CHECK(w_[i].capacity() == meshSize);
72 }
73 UTIL_CHECK(dwc_.capacity() == meshSize);
74 }
75
76 template <int D>
78 {
79 // Array sizes and indices
80 const int nMonomer = system().mixture().nMonomer();
81 const int meshSize = system().domain().mesh().size();
82 int i, j, k;
83
84 // Save current state
85 simulator().saveState();
86
87 // Copy current W fields from parent system into w_
88 for (i = 0; i < nMonomer; ++i) {
89 w_[i] = system().w().rgrid(i);
90 }
91
92 // Constants for dynamics
93 const double vSystem = system().domain().unitCell().volume();
94 const double a = -1.0*mobility_;
95 const double b = sqrt(2.0*mobility_*double(meshSize)/vSystem);
96
97 // Modify local field copy wc_
98 // Loop over eigenvectors of projected chi matrix
99 double dwd, dwr, evec;
100 for (j = 0; j < nMonomer - 1; ++j) {
101 RField<D> const & dc = simulator().dc(j);
102 for (k = 0; k < meshSize; ++k) {
103 dwd = a*dc[k];
104 dwr = b*random().gaussian();
105 dwc_[k] = dwd + dwr;
106 }
107 // Loop over monomer types
108 for (i = 0; i < nMonomer; ++i) {
109 RField<D> & w = w_[i];
110 evec = simulator().chiEvecs(j,i);
111 for (k = 0; k < meshSize; ++k) {
112 w[k] += evec*dwc_[k];
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
Field of real double precision values on an FFT mesh.
Definition cpu/RField.h:29
Brownian dynamics simulator for PS-FTS.
BdSimulator< D > & simulator()
Get parent BdSimulator object.
System< D > & system()
Get parent System object.
BdStep(BdSimulator< D > &simulator)
Constructor.
Random & random()
Get Random number generator of parent System.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
ExplicitBdStep(BdSimulator< D > &simulator)
Constructor.
virtual void setup()
Setup before simulation.
virtual void readParameters(std::istream &in)
Read required parameters from file.
virtual bool step()
Take a single Brownian dynamics step.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
Real periodic fields, SCFT and PS-FTS (CPU).
Definition param_pc.dox:2
PSCF package top-level namespace.