PSCF v1.4.0
fts/montecarlo/ShiftMove.tpp
1#ifndef RP_SHIFT_TPP
2#define RP_SHIFT_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 "ShiftMove.h"
12
13#include <pscf/mesh/Mesh.h>
14#include <util/containers/Array.h>
15#include <util/random/Random.h>
16
17namespace Pscf {
18namespace Rp {
19
20 using namespace Util;
21
22 /*
23 * Constructor.
24 */
25 template <int D, class T>
26 ShiftMove<D,T>::ShiftMove(typename T::McSimulator& simulator)
27 : McMoveT(simulator),
28 maxShift_(0),
29 isAllocated_(false)
30 { ParamComposite::setClassName("ShiftMove"); }
31
32 /*
33 * Read body of parameter file block.
34 */
35 template <int D, class T>
36 void ShiftMove<D,T>::readParameters(std::istream &in)
37 {
38
39 // Read the probability
40 McMoveT::readProbability(in);
41
42 // Read the maximum shift
43 ParamComposite::read(in, "maxShift", maxShift_);
44
45 // Validate maxShift_ value
46 UTIL_CHECK(maxShift_ > 0);
47 IntVec<D> const & dim = system().domain().mesh().dimensions();
48 for (int i = 0; i < D; i++) {
49 UTIL_CHECK(maxShift_ < dim[i]);
50 }
51 }
52
53 /*
54 * Setup just before beginning a simulation.
55 */
56 template <int D, class T>
58 {
59 // Setup base class
60 McMoveT::setup();
61
62 // Allocate memory if necessary
63 if (!isAllocated_) {
64 const int nMonomer = system().mixture().nMonomer();
65 IntVec<D> const & dim = system().domain().mesh().dimensions();
66 w_.allocate(nMonomer);
67 for (int i = 0; i < nMonomer; ++i) {
68 w_[i].allocate(dim);
69 }
70 isAllocated_ = true;
71 }
72 }
73
74 /*
75 * Attempt unconstrained move
76 */
77 template <int D, class T>
79 {
80 // Select random displacement by integer numbers of mesh points
81 IntVec<D> shift;
82 for (int i = 0; i < D; i++){
83 shift[i] = McMoveT::random().uniformInt(-maxShift_, maxShift_ + 1);
84 }
85
86 // Compute shifted fields stored in w_ array
87 shiftFields(shift);
88
89 // Update w-fields in parent system
90 system().w().setRGrid(w_);
91 }
92
93 /*
94 * Shift a single field.
95 */
96 template <int D, class T>
98 Array<double> const & in,
99 IntVec<D> shift,
100 IntVec<D> dimensions) const
101 {
102 Mesh<D> mesh(dimensions);
103 IntVec<D> inPosition, outPosition;
104 int meshSize = mesh.size();
105 UTIL_CHECK(out.capacity() == meshSize);
106 UTIL_CHECK(in.capacity() == meshSize);
107
108 for (int i = 0; i < meshSize; ++i) {
109 inPosition = mesh.position(i);
110 for (int d = 0; d < D; ++d){
111 outPosition[d] = inPosition[d] + shift[d];
112 if (outPosition[d] < 0){
113 outPosition[d] += dimensions[d];
114 }
115 UTIL_CHECK(outPosition[d] >= 0);
116 outPosition[d] = outPosition[d] % dimensions[d];
117 }
118 out[mesh.rank(outPosition)] = in[mesh.rank(inPosition)];
119 }
120 }
121
122}
123}
124#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
Description of a regular grid of points in a periodic domain.
Definition Mesh.h:61
int size() const
Get total number of grid points.
Definition Mesh.h:229
int rank(IntVec< D > const &position) const
Get the rank of a grid point with specified position.
Definition Mesh.tpp:72
IntVec< D > position(int rank) const
Get the position IntVec<D> of a grid point with a specified rank.
Definition Mesh.tpp:89
void attemptMove() override
Attempt move that translates all w fields.
DArray< typename T::RField > w_
Shifted field configurations.
void readParameters(std::istream &in) override
Read body of parameter file block.
ShiftMove(typename T::McSimulator &simulator)
Constructor.
virtual void shiftFields(IntVec< D > const &shift)=0
Compute and store shifted w fields.
void shiftField(Array< double > &out, Array< double > const &in, IntVec< D > shift, IntVec< D > dimensions) const
Compute a shifted version of a field.
void setup() override
Setup before the beginning of each simulation run.
Array container class template.
Definition Array.h:40
int capacity() const
Return allocated size.
Definition Array.h:144
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
Class templates for real-valued periodic fields.
PSCF package top-level namespace.