PSCF v1.4.0
McMove.tpp
1#ifndef RP_MC_MOVE_TPP
2#define RP_MC_MOVE_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 "McMove.h"
12
13#include <util/random/Random.h>
14#include <util/archives/Serializable_includes.h>
15
16namespace Pscf {
17namespace Rp {
18
19 using namespace Util;
20
21 /*
22 * Constructor.
23 */
24 template <int D, class T>
25 McMove<D,T>::McMove(typename T::McSimulator& simulator)
26 : simulatorPtr_(&simulator),
27 systemPtr_(&(simulator.system())),
28 randomPtr_(&(simulator.random())),
29 vecRandomPtr_(&(simulator.vecRandom())),
30 probability_(0.0),
31 nAttempt_(0),
32 nAccept_(0),
33 nFail_(0)
34 {}
35
36 /*
37 * Read parameters - empty default implementation.
38 */
39 template <int D, class T>
40 void McMove<D,T>::readParameters(std::istream &in)
41 {}
42
43 /*
44 * Read the probability from file.
45 */
46 template <int D, class T>
47 void McMove<D,T>::readProbability(std::istream &in)
48 { read<double>(in, "probability", probability_); }
49
50 /*
51 * Setup at beginning of loop.
52 *
53 * Trivial default implementation - initializes counters.
54 */
55 template <int D, class T>
57 {
58 nAttempt_ = 0;
59 nAccept_ = 0;
60 nFail_ = 0;
62 simulator().computeWc();
63
64 if (simulator().needsCc() || simulator().needsDc()){
65 system().compute();
66 simulator().computeCc();
67 }
68
69 if (simulator().needsDc()){
70 simulator().computeDc();
71 }
72 }
73
74 /*
75 * Standard Metropolis MC move.
76 */
77 template <int D, class T>
79 {
80 // Start timers
81 totalTimer_.start();
82 attemptMoveTimer_.start();
84
85 // Get current Hamiltonian
86 double oldHamiltonian = simulator().hamiltonian();
87
88 // Save current state
89 simulator().saveState();
90
91 // Clear both eigen-components of the fields and hamiltonian
92 simulator().clearData();
93
94 // Attempt modification of exchange fields
96 attemptMoveTimer_.stop();
97
98 // Call compressor to modify pressure-like fields
99 compressorTimer_.start();
100 int compress = simulator().compressor().compress();
101 UTIL_CHECK(system().c().hasData());
102 compressorTimer_.stop();
103
104 bool isConverged = false;
105 if (compress != 0){
107 simulator().restoreState();
108 } else {
109 isConverged = true;
110
111 // Compute eigenvector components of the current fields
112 componentTimer_.start();
113 simulator().computeWc();
114 // Compute cc fields if any move require cc fields
115 if (simulator().needsCc() || simulator().needsDc()){
116 UTIL_CHECK(system().c().hasData());
117 //system().compute();
118 simulator().computeCc();
119 }
120 // Compute dc fields if any move require dc fields
121 if (simulator().needsDc()){
122 simulator().computeDc();
124 componentTimer_.stop();
125
126 // Evaluate new Hamiltonian
127 hamiltonianTimer_.start();
128 simulator().computeHamiltonian();
129 double newHamiltonian = simulator().hamiltonian();
130 hamiltonianTimer_.stop();
131
132 // Accept or reject move
133 decisionTimer_.start();
134 bool accept = false;
135 double weight = exp(-(newHamiltonian - oldHamiltonian));
136 if (newHamiltonian - oldHamiltonian <= 1e-10){
137 accept = true;
138 } else{
139 accept = random().metropolis(weight);
140 }
141 if (accept) {
142 incrementNAccept();
143 simulator().clearState();
144 } else {
145 simulator().restoreState();
146 }
147 decisionTimer_.stop();
148
149 }
150 totalTimer_.stop();
151
152 return isConverged;
153 }
154
155 /*
156 * Trivial default implementation - do nothing
157 */
158 template <int D, class T>
160 {}
161
162 /*
163 * Output timing information at tend of simulation.
164 */
165 template<int D, class T>
166 void McMove<D,T>::outputTimers(std::ostream& out)
167 {
168 out << "\n";
169 out << className();
170 out << " time contributions:\n";
171 outputTimerData(out);
172 }
173
174 /*
175 * Output raw timing information, with class name label.
176 */
177 template<int D, class T>
178 void McMove<D,T>::outputTimerData(std::ostream& out)
179 {
180 // Output timing results, if requested.
181 double total = totalTimer_.time();
182 out << " " << "Total"
183 << std::setw(17) << "Per Move"
184 << std::setw(14) << "Fraction" << "\n";
185 out << "Attempt Move: "
186 << Dbl(attemptMoveTimer_.time(), 9, 3) << " s, "
187 << Dbl(attemptMoveTimer_.time()/nAttempt_, 9, 3) << " s, "
188 << Dbl(attemptMoveTimer_.time()/total, 9, 3) << "\n";
189 out << "Compressor: "
190 << Dbl(compressorTimer_.time(), 9, 3) << " s, "
191 << Dbl(compressorTimer_.time()/nAttempt_, 9, 3) << " s, "
192 << Dbl(compressorTimer_.time()/total, 9, 3) << "\n";
193 out << "Compute eigen-components: "
194 << Dbl(componentTimer_.time(), 9, 3) << " s, "
195 << Dbl(componentTimer_.time()/nAttempt_, 9, 3) << " s, "
196 << Dbl(componentTimer_.time()/total, 9, 3) << "\n";
197 out << "Compute Hamiltonian: "
198 << Dbl(hamiltonianTimer_.time(), 9, 3) << " s, "
199 << Dbl(hamiltonianTimer_.time()/nAttempt_, 9, 3) << " s, "
200 << Dbl(hamiltonianTimer_.time()/total, 9, 3) << "\n";
201 out << "Accept or Reject: "
202 << Dbl(decisionTimer_.time(), 9, 3) << " s, "
203 << Dbl(decisionTimer_.time()/nAttempt_, 9, 3) << " s, "
204 << Dbl(decisionTimer_.time()/total, 9, 3) << "\n";
205 out << "total time: "
206 << Dbl(total, 9, 3) << " s, "
207 << Dbl(total/nAttempt_, 9, 3) << " s \n";
208 out << "\n";
209 }
210
211 /*
212 * Clear all timers.
213 */
214 template<int D, class T>
216 {
217 attemptMoveTimer_.clear();
218 compressorTimer_.clear();
219 componentTimer_.clear();
220 hamiltonianTimer_.clear();
221 decisionTimer_.clear();
222 totalTimer_.clear();
223 }
224
225}
226}
227#endif
Random & random()
Get the scalar random number generator.
virtual void clearTimers()
Clear timers.
Definition McMove.tpp:215
T::McSimulator & simulator()
Get parent McSimulator object (non-const ref).
virtual void outputTimers(std::ostream &out)
Write timing results to a file.
Definition McMove.tpp:166
void readProbability(std::istream &in)
Read the probability from file.
Definition McMove.tpp:47
T::VecRandom & vecRandom()
Get the vector random number generator.
void outputTimerData(std::ostream &out)
Write timing data to a file, without a class label.
Definition McMove.tpp:178
McMove(typename T::McSimulator &simulator)
Constructor.
Definition McMove.tpp:25
T::System & system()
Get parent System object (non-const ref).
virtual void output()
Output statistics for this move (at the end of simulation)
Definition McMove.tpp:159
virtual bool needsCc()
Decide whether cc fields need to be saved for move.
virtual void setup()
Setup before the beginning of each simulation run.
Definition McMove.tpp:56
Timer attemptMoveTimer_
Timers for McMove.
virtual void readParameters(std::istream &in)
Read required parameters from file.
Definition McMove.tpp:40
virtual bool move()
Generate, attempt, and accept or reject a Monte Carlo move.
Definition McMove.tpp:78
virtual bool needsDc()
Decide whether dc fields need to be saved for move.
void incrementNAttempt()
Increment the number of attempted moves.
Wrapper for a double precision number, for formatted ostream output.
Definition Dbl.h:40
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
std::string className() const
Get 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.