PSCF v1.3.3
rpg/fts/brownian/ExplicitBdStep.tpp
1#ifndef RPG_EXPLICIT_BD_STEP_TPP
2#define RPG_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
13#include <rpg/fts/brownian/BdSimulator.h>
14#include <rpg/fts/compressor/Compressor.h>
15#include <rpg/solvers/Mixture.h>
16#include <rpg/field/Domain.h>
17#include <rpg/system/System.h>
18#include <prdc/cuda/VecOp.h>
19#include <pscf/math/IntVec.h>
20
21namespace Pscf {
22namespace Rpg {
23
24 using namespace Util;
25 using namespace Pscf::Prdc;
26 using namespace Pscf::Prdc::Cuda;
27
28 /*
29 * Constructor.
30 */
31 template <int D>
33 : BdStep<D>(simulator),
34 w_(),
35 dwc_(),
36 mobility_(0.0)
37 {}
38
39 /*
40 * Destructor, empty default implementation.
41 */
42 template <int D>
45
46 /*
47 * ReadParameters, empty default implementation.
48 */
49 template <int D>
50 void ExplicitBdStep<D>::readParameters(std::istream &in)
51 {
52 read(in, "mobility", mobility_);
53
54 // Allocate memory for private containers
55 int nMonomer = system().mixture().nMonomer();
56 IntVec<D> meshDimensions = system().domain().mesh().dimensions();
57 w_.allocate(nMonomer);
58 for (int i=0; i < nMonomer; ++i) {
59 w_[i].allocate(meshDimensions);
60 }
61 dwc_.allocate(meshDimensions);
62
63 }
64
65 template <int D>
67 {
68 // Check array capacities
69 int meshSize = system().domain().mesh().size();
70 IntVec<D> dimensions = system().domain().mesh().dimensions();
71 int nMonomer = system().mixture().nMonomer();
72 UTIL_CHECK(w_.capacity() == nMonomer);
73 for (int i=0; i < nMonomer; ++i) {
74 UTIL_CHECK(w_[i].capacity() == meshSize);
75 }
76 UTIL_CHECK(dwc_.capacity() == meshSize);
77 gaussianField_.allocate(dimensions);
78 }
79
80 template <int D>
82 {
83 // Array sizes and indices
84 const int nMonomer = system().mixture().nMonomer();
85 const int meshSize = system().domain().mesh().size();
86 int i, j;
87
88 // Save current state
89 simulator().saveState();
90
91 // Copy current W fields from parent system into w_
92 for (i = 0; i < nMonomer; ++i) {
93 VecOp::eqV(w_[i], system().w().rgrid(i));
94 }
95
96 // Constants for dynamics
97 const double vSystem = system().domain().unitCell().volume();
98 double a = -1.0*mobility_;
99 double b = sqrt(2.0*mobility_*double(meshSize)/vSystem);
100
101 // Constants for normal distribution
102 double stddev = 1.0;
103 double mean = 0;
104
105 // Modify local field copy wc_
106 // Loop over eigenvectors of projected chi matrix
107 double evec;
108 for (j = 0; j < nMonomer - 1; ++j) {
109 RField<D> const & dc = simulator().dc(j);
110
111 // Generate normal distributed random floating point numbers
112 cudaRandom().normal(gaussianField_, stddev, mean);
113
114 // dwc
115 VecOp::addVcVc(dwc_, dc, a, gaussianField_, b);
116
117 // Loop over monomer types
118 for (i = 0; i < nMonomer; ++i) {
119 RField<D> & w = w_[i];
120 evec = simulator().chiEvecs(j,i);
121 VecOp::addEqVc(w, dwc_, evec);
122 }
123
124 }
125
126 // Set modified fields in parent system
127 system().w().setRGrid(w_);
128 simulator().clearData();
129
130 // Enforce incompressibility (also solves MDE repeatedly)
131 bool isConverged = false;
132 int compress = simulator().compressor().compress();
133 if (compress != 0){
134 simulator().restoreState();
135 } else {
136 isConverged = true;
137 UTIL_CHECK(system().c().hasData());
138
139 // Evaluate component properties in new state
140 simulator().clearState();
141 simulator().computeWc();
142 simulator().computeCc();
143 simulator().computeDc();
144
145 }
146
147 return isConverged;
148 }
149
150}
151}
152#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.
BdStep(BdSimulator< D > &simulator)
Constructor.
System< D > & system()
Get parent System object.
CudaRandom & cudaRandom()
Get Random number generator of parent System.
BdSimulator< D > & simulator()
Get parent BdSimulator object.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
virtual bool step()
Take a single Brownian dynamics step.
virtual void readParameters(std::istream &in)
Read required parameters from file.
ExplicitBdStep(BdSimulator< D > &simulator)
Constructor.
virtual void setup()
Setup before simulation.
#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)
Vector assignment, a[i] = b[i].
Definition VecOp.cpp:23
void addVcVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c, DeviceArray< cudaReal > const &d, cudaReal const e)
Vector addition w/ coefficient, a[i] = (b[i]*c) + (d[i]*e), kernel wrapper.
Definition VecOpMisc.cu:304
void addEqVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c)
Vector addition in-place w/ coefficient, a[i] += b[i] * c, kernel wrapper.
Definition VecOpMisc.cu:343
Fields, FFTs, and utilities for periodic boundary conditions (CUDA)
Definition CField.cu:12
Periodic fields and crystallography.
Definition CField.cpp:11
SCFT and PS-FTS with real periodic fields (GPU)
PSCF package top-level namespace.