PSCF v1.3.1
rpg/fts/montecarlo/McMove.tpp
1#ifndef RPG_MC_MOVE_TPP
2#define RPG_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 <rpg/fts/montecarlo/McSimulator.h>
14#include <rpg/fts/compressor/Compressor.h>
15#include <rpg/system/System.h>
16#include <pscf/cuda/CudaRandom.h>
17#include <util/random/Random.h>
18
19namespace Pscf {
20namespace Rpg {
21
22 using namespace Util;
23
24 /*
25 * Constructor.
26 */
27 template <int D>
29 : simulatorPtr_(&simulator),
30 systemPtr_(&(simulator.system())),
31 randomPtr_(&(simulator.random())),
32 cudaRandomPtr_(&(simulator.cudaRandom())),
33 nAttempt_(0),
34 nAccept_(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 McMove<D>::readParameters(std::istream &in)
49 {}
50
51 /*
52 * Read the probability from file.
53 */
54 template <int D>
55 void McMove<D>::readProbability(std::istream &in)
56 { read<double>(in, "probability", probability_); }
57
58 /*
59 * Setup at beginning of loop.
60 *
61 * Trivial default implementation - initializes counters.
62 */
63 template <int D>
65 {
66 nAttempt_ = 0;
67 nAccept_ = 0;
68 nFail_ = 0;
70 simulator().computeWc();
71 if (simulator().needsCc() || simulator().needsDc()){
72 system().compute();
73 simulator().computeCc();
74 }
75 if (simulator().needsDc()){
76 simulator().computeDc();
77 }
78 }
79
80 /*
81 * Trivial default implementation - always returns false.
82 */
83 template <int D>
85 {
86 totalTimer_.start();
88
89 // Get current Hamiltonian
90 double oldHamiltonian = simulator().hamiltonian();
91
92 // Save current state
93 simulator().saveState();
94
95 // Clear both eigen-components of the fields and hamiltonian
96 simulator().clearData();
97
98 // Attempt modification
99 attemptMoveTimer_.start();
100 attemptMove();
101 attemptMoveTimer_.stop();
102
103 // Call compressor
104 compressorTimer_.start();
105 int compress = simulator().compressor().compress();
106 UTIL_CHECK(system().c().hasData());
107 compressorTimer_.stop();
108
109 bool isConverged = false;
110 if (compress != 0){
112 simulator().restoreState();
113 } else {
114 isConverged = true;
115
116 // Compute eigenvector components of the current w fields
117 componentTimer_.start();
118 simulator().computeWc();
119 // Compute cc fields if any move require cc fields
120 if (simulator().needsCc() || simulator().needsDc()){
121 //system().compute();
122 UTIL_CHECK(system().c().hasData());
123 simulator().computeCc();
124 }
125 // Compute dc fields if any move require dc fields
126 if (simulator().needsDc()){
127 simulator().computeDc();
128 }
129 componentTimer_.stop();
130
131 // Evaluate new Hamiltonian
132 hamiltonianTimer_.start();
133 simulator().computeHamiltonian();
134 double newHamiltonian = simulator().hamiltonian();
135 hamiltonianTimer_.stop();
136
137 // Accept or reject move
138 bool accept = false;
139 decisionTimer_.start();
140 double weight = exp(-(newHamiltonian - oldHamiltonian));
141 accept = random().metropolis(weight);
142 if (accept) {
144 simulator().clearState();
145 } else {
146 simulator().restoreState();
147 }
148 decisionTimer_.stop();
149
150 }
151 totalTimer_.stop();
152
153 return isConverged;
154 }
155
156 /*
157 * Trivial default implementation - do nothing
158 */
159 template <int D>
161 {}
162
163 template<int D>
164 void McMove<D>::outputTimers(std::ostream& out)
165 {
166 // Output timing results, if requested.
167 double total = totalTimer_.time();
168 out << " "
169 << "Total" << std::setw(17) << "Per Move" << std::setw(14) << "Fraction" << "\n";
170 out << "Attempt Move: "
171 << Dbl(attemptMoveTimer_.time(), 9, 3) << " s, "
172 << Dbl(attemptMoveTimer_.time()/nAttempt_, 9, 3) << " s, "
173 << Dbl(attemptMoveTimer_.time()/total, 9, 3) << "\n";
174 out << "Compressor: "
175 << Dbl(compressorTimer_.time(), 9, 3) << " s, "
176 << Dbl(compressorTimer_.time()/nAttempt_, 9, 3) << " s, "
177 << Dbl(compressorTimer_.time()/total, 9, 3) << "\n";
178 out << "Compute eigen-components: "
179 << Dbl(componentTimer_.time(), 9, 3) << " s, "
180 << Dbl(componentTimer_.time()/nAttempt_, 9, 3) << " s, "
181 << Dbl(componentTimer_.time()/total, 9, 3) << "\n";
182 out << "Compute Hamiltonian: "
183 << Dbl(hamiltonianTimer_.time(), 9, 3) << " s, "
184 << Dbl(hamiltonianTimer_.time()/nAttempt_, 9, 3) << " s, "
185 << Dbl(hamiltonianTimer_.time()/total, 9, 3) << "\n";
186 out << "Accept or Reject: "
187 << Dbl(decisionTimer_.time(), 9, 3) << " s, "
188 << Dbl(decisionTimer_.time()/nAttempt_, 9, 3) << " s, "
189 << Dbl(decisionTimer_.time()/total, 9, 3) << "\n";
190 out << "total time: "
191 << Dbl(total, 9, 3) << " s, "
192 << Dbl(total/nAttempt_, 9, 3) << " s \n";
193 out << "\n";
194 }
195
196 template<int D>
198 {
199 attemptMoveTimer_.clear();
200 compressorTimer_.clear();
201 componentTimer_.clear();
202 hamiltonianTimer_.clear();
203 decisionTimer_.clear();
204 totalTimer_.clear();
205 }
206
207
208}
209}
210#endif
CudaRandom & cudaRandom()
Get cuda random number generator by reference.
virtual ~McMove()
Destructor.
void incrementNAttempt()
Increment the number of attempted moves.
Random & random()
Get Random number generator of parent System.
virtual void attemptMove()
Attempt unconstrained move.
virtual bool move()
Generate, attempt, and accept or reject a Monte Carlo move.
void readProbability(std::istream &in)
Read the probability from file.
virtual bool needsCc()
Decide whether cc fields need to be saved for move The default implementation is false.
McSimulator< D > & simulator()
Get parent McSimulator object.
virtual void readParameters(std::istream &in)
Read required parameters from file.
System< D > & system()
Get parent System object.
void incrementNAccept()
Increment the number of accepted moves.
void incrementNFail()
Increment the number of failed moves.
virtual void outputTimers(std::ostream &out)
Log output timing results.
virtual void setup()
Setup before the beginning of each simulation run.
McMove(McSimulator< D > &simulator)
Constructor.
Timer attemptMoveTimer_
Timers for McMove.
virtual bool needsDc()
Decide whether dc fields need to be saved for move The default implementation is false.
virtual void clearTimers()
Clear timers.
virtual void output()
Output statistics for this move (at the end of simulation)
Monte-Carlo simulation coordinator.
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.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
SCFT and PS-FTS with real periodic fields (GPU)
PSCF package top-level namespace.
Definition param_pc.dox:1