Loading...
Searching...
No Matches
eonc::SafeHyperJob Class Reference

#include <SafeHyperJob.h>

Inheritance diagram for eonc::SafeHyperJob:

Public Member Functions

 ~SafeHyperJob ()=default
Public Member Functions inherited from eonc::ReplicaDynamicsJob
 ~ReplicaDynamicsJob () override=default
std::vector< std::string > run () override
 Virtual run; used solely for dynamic dispatch.
std::shared_ptr< Matter > runFromMatter (std::shared_ptr< Matter > initial)
 Matter-first entry: seed geometry, skip con2matter load.
 Job (std::unique_ptr< Parameters > parameters, Runtime &rt)
 Borrow: caller keeps Runtime alive (CLI stack / Python Session).
 Job (std::unique_ptr< Parameters > parameters, std::unique_ptr< Runtime > rt)
 Own a Runtime (one-shot makeJob / rvalue).
 Job (std::unique_ptr< Parameters > parameters)
 Own a default-constructed Runtime.
 Job (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
Public Member Functions inherited from eonc::Job
void adoptRuntime (std::unique_ptr< Runtime > rt)
 Take ownership of a Runtime previously passed as Runtime&.
 Job (std::unique_ptr< Parameters > parameters, Runtime &rt)
 Borrow: caller keeps Runtime alive (CLI stack / Python Session).
 Job (std::unique_ptr< Parameters > parameters, std::unique_ptr< Runtime > rt)
 Own a Runtime (one-shot makeJob / rvalue).
 Job (std::unique_ptr< Parameters > parameters)
 Own a default-constructed Runtime.
 Job (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
virtual ~Job ()=default
JobType getType ()
PotRegistry & pots () noexcept
void releasePotential ()
 Drop the Potential so on_destroyed is recorded before Runtime dies.

Private Member Functions

int dynamics () override
 The accelerated dynamics loop. Returns status (1 = transition, 0 = none).
void reportResults () override
 Post-dynamics logging (override for job-specific messages).

Private Attributes

double transitionPot {0.0}
std::vector< double > timeBuffer
std::vector< double > biasBuffer

Additional Inherited Members

Protected Member Functions inherited from eonc::ReplicaDynamicsJob
bool checkState (Matter *current, Matter *reactant)
 Minimize a copy of current and compare to reactant.
long refine (const std::vector< std::shared_ptr< Matter > > &buff, Matter *reactant)
 Binary search for the transition frame in a snapshot buffer.
void dephase ()
 Dephase the trajectory to ensure thermal independence.
PrdClock prdClock () const
void saveData (int status)
 Write results.dat and structure con files.
virtual void initExtra ()
 Create any extra matter objects needed by the subclass.
Protected Attributes inherited from eonc::ReplicaDynamicsJob
std::shared_ptr< Matter > current
std::shared_ptr< Matter > reactant
std::shared_ptr< Matter > saddle
std::shared_ptr< Matter > product
std::shared_ptr< Matter > finalState
std::shared_ptr< Matter > finalStateTmp
bool metaStateFlag {false}
bool newStateFlag {false}
size_t minimizeFCalls {0}
size_t mdFCalls {0}
size_t dephaseFCalls {0}
size_t refineFCalls {0}
long transitionStep {0}
double time {0.0}
double minCorrectedTime {1.0e200}
double transitionTime {0.0}
std::vector< std::string > returnFiles
eonc::log::Scoped log
Protected Attributes inherited from eonc::Job
JobType jtype
Parameters params
std::unique_ptr< Runtime > owned_runtime_
 Non-null when this Job owns the composition root (one-shot makeJob).
Runtime * runtime_
 Always valid: either owned_runtime_.get() or a caller-owned Runtime.
std::shared_ptr< Potential > pot

Detailed Description

Definition at line 19 of file SafeHyperJob.h.

Constructor & Destructor Documentation

◆ ~SafeHyperJob()

eonc::SafeHyperJob::~SafeHyperJob ( )
default

Member Function Documentation

◆ dynamics()

int eonc::SafeHyperJob::dynamics ( )
overrideprivatevirtual

The accelerated dynamics loop. Returns status (1 = transition, 0 = none).

Implements eonc::ReplicaDynamicsJob.

Definition at line 33 of file SafeHyperJob.cpp.

33 {
34 bool transitionFlag = false, recordFlag = true, stopFlag = false,
35 firstTransitFlag = false;
36 long nFreeCoord = reactant->numberOfFreeAtoms() * 3;
37 long mdBufferLength;
38 long step = 0, refineStep, newStateStep = 0;
39 long nCheck = 0, nRecord = 0, nBoost = 0, nState = 0;
40 long StateCheckInterval, RecordInterval;
41 double kinE, kinT, avgT, varT;
42 double kB = params.constants().kB;
43 double correctedTime = 0.0, sumCorrectedTime = 0.0, firstTransitionTime = 0.0;
44 double Temp = 0.0, sumT = 0.0, sumT2 = 0.0;
45 double sumboost = 0.0, boost = 1.0, boostPotential = 0.0;
46 double transitionTime_current = 0.0, transitionTime_pre = 0.0;
47 AtomMatrix velocity;
48
49 minCorrectedTime = 1.0e200;
50 const auto clock = prdClock();
51 StateCheckInterval = clock.state_check;
52 RecordInterval = clock.record;
53 Temp = params.main_options().temperature;
55
56 mdBufferLength = clock.buffer;
57 std::vector<std::shared_ptr<Matter>> mdBuffer(mdBufferLength);
58 for (long i = 0; i < mdBufferLength; i++) {
59 mdBuffer[i] = std::make_shared<Matter>(pot, params);
60 }
61 timeBuffer.resize(mdBufferLength);
62 biasBuffer.resize(mdBufferLength);
63
64 Dynamics safeHyper(current.get(), params);
65 BondBoost bondBoost(current.get(), params);
66
67 if (params.hyperdynamics_options().bias_potential ==
69 bondBoost.initialize();
70 current->setBiasPotential(&bondBoost);
71 }
72
73 safeHyper.setThermalVelocity();
74
75 {
76 eonc::ForceCallTimer timer(dephaseFCalls);
77 dephase();
78 }
79
80 QUILL_LOG_DEBUG(
81 log,
82 "Starting MD run\nTemperature: {:.2f} Kelvin\n"
83 "Total Simulation Time: {:.2f} fs\nTime Step: {:.2f} fs\nTotal Steps: {}",
84 Temp,
85 params.dynamics_options().steps * params.dynamics_options().time_step *
86 params.constants().timeUnit,
87 params.dynamics_options().time_step * params.constants().timeUnit,
88 params.dynamics_options().steps);
89 QUILL_LOG_DEBUG(log, "MD buffer length: {}", mdBufferLength);
90
91 long tenthSteps = params.dynamics_options().steps / 10;
92 if (tenthSteps == 0) {
93 tenthSteps = params.dynamics_options().steps;
94 }
95
96 while (!stopFlag) {
97 boost = 1.0;
98 boostPotential = 0.0;
99 if ((params.hyperdynamics_options().bias_potential ==
101 !newStateFlag) {
102 bondBoost.advance();
103 boostPotential = bondBoost.boost();
104 QUILL_LOG_TRACE_L1(log, "step= {} , boost = {:.5f}", step,
105 boostPotential);
106 if (Temp > 0.0 && kB > 0.0) {
107 boost = std::exp(boostPotential / kB / Temp);
108 } else {
109 boost = 1.0;
110 }
111 if (boost > 1.0) {
112 sumboost += boost;
113 nBoost++;
114 }
115 }
116 time += params.dynamics_options().time_step * boost;
117
118 kinE = current->getKineticEnergy();
119 kinT = (2.0 * kinE / nFreeCoord / kB);
120 sumT += kinT;
121 sumT2 += kinT * kinT;
122 QUILL_LOG_TRACE_L1(log, "steps = {:10} temp = {:10.5f}", step, kinT);
123
124 safeHyper.oneStep();
125 mdFCalls++;
126
127 nCheck++;
128 step++;
129 QUILL_LOG_TRACE_L1(log, "step = {:4}, time = {:10.4f}", step, time);
130
131 if (params.parallel_replica_options().refine_transition && recordFlag &&
132 !newStateFlag) {
133 if (nCheck % RecordInterval == 0) {
134 *mdBuffer[nRecord] = *current;
135 timeBuffer[nRecord] = time;
136 biasBuffer[nRecord] = boostPotential;
137 nRecord++;
138 }
139 }
140
141 if ((nCheck == StateCheckInterval) && !newStateFlag) {
142 nCheck = 0;
143 nRecord = 0;
144 {
145 eonc::ForceCallTimer timer(minimizeFCalls);
146 transitionFlag = checkState(current.get(), reactant.get());
147 }
148 if (transitionFlag) {
149 nState++;
150 QUILL_LOG_DEBUG(log, "New State {}: ", nState);
153 newStateStep = step;
154 transitionStep = newStateStep;
155 firstTransitFlag = 1;
156 }
157 }
158
159 if (transitionFlag) {
160 QUILL_LOG_TRACE_L1(log, "Refining transition time.");
161 const bool can_refine =
162 params.parallel_replica_options().refine_transition && nRecord >= 2;
163 if (can_refine) {
164 eonc::ForceCallTimer timer(refineFCalls);
165 refineStep = refine(mdBuffer, reactant.get());
167 newStateStep - StateCheckInterval + refineStep * RecordInterval;
168 transitionTime_current = timeBuffer[static_cast<size_t>(refineStep)];
169 transitionPot = biasBuffer[static_cast<size_t>(refineStep)];
170 const long prev = refineStep > 0 ? refineStep - 1 : 0;
171 *current = *mdBuffer[static_cast<size_t>(prev)];
172 } else {
173 refineStep = 0;
174 transitionTime_current = time;
175 transitionPot = boostPotential;
176 }
177 transitionTime = transitionTime_current - transitionTime_pre;
178 transitionTime_pre = transitionTime_current;
179 correctedTime =
180 (Temp > 0.0 && kB > 0.0)
181 ? transitionTime * std::exp((-1) * transitionPot / kB / Temp)
183 sumCorrectedTime += correctedTime;
184 if (nState == 1) {
185 firstTransitionTime = transitionTime;
186 }
187 velocity = current->getVelocities();
188 velocity = velocity * (-1);
189 current->setVelocities(velocity);
190
191 if (correctedTime < minCorrectedTime) {
192 minCorrectedTime = correctedTime;
193 if (can_refine) {
194 *saddle = *mdBuffer[static_cast<size_t>(refineStep)];
195 } else {
196 *saddle = *current;
197 }
199 }
200 QUILL_LOG_DEBUG(log,
201 "tranisitonTime= {:.3e} s, biasPot= {:.3f} eV, "
202 "correctedTime= {:.3e} s, "
203 "sumCorrectedTime= {:.3e} s, minCorTime= {:.3e} s",
204 transitionTime * 1e-15 * params.constants().timeUnit,
206 correctedTime * 1e-15 * params.constants().timeUnit,
207 sumCorrectedTime * 1e-15 * params.constants().timeUnit,
208 minCorrectedTime * 1.0e-15 * params.constants().timeUnit);
209
210 transitionFlag = false;
211 }
212
213 if (firstTransitFlag && sumCorrectedTime > firstTransitionTime) {
214 stopFlag = true;
215 newStateFlag = true;
216 }
217
218 if ((step % tenthSteps == 0) || (step == params.dynamics_options().steps)) {
219 double maxAtomDistance = current->perAtomNorm(*reactant);
220 QUILL_LOG_DEBUG(
221 log, "progress: {:.0f}%, max displacement: {:.3f}, step {} / {}",
222 static_cast<double>(100.0 * step / params.dynamics_options().steps),
223 maxAtomDistance, step, params.dynamics_options().steps);
224 }
225
226 // Honor dynamics step budget (parity with TADJob); without this the
227 // loop only exits on a confidence-gated transition and can run forever.
228 if (step >= params.dynamics_options().steps) {
229 stopFlag = true;
230 }
231 }
232
233 avgT = sumT / step;
234 varT = sumT2 / step - avgT * avgT;
235
236 if (nBoost > 0) {
237 QUILL_LOG_DEBUG(log,
238 "Temperature : Average = {:.6f} ; Stddev = {:.6f} ; "
239 "Factor = {:.6f}; Boost = {:.6f}",
240 avgT, std::sqrt(varT), varT / avgT / avgT * nFreeCoord / 2,
241 sumboost / nBoost);
242 } else {
243 QUILL_LOG_DEBUG(
244 log,
245 "Temperature : Average = {:.6f} ; Stddev = {:.6f} ; Factor = {:.6f}",
246 avgT, std::sqrt(varT), varT / avgT / avgT * nFreeCoord / 2);
247 }
248 if (std::isfinite(avgT) == 0) {
249 QUILL_LOG_DEBUG(log, "Infinite average temperature, something went wrong!");
250 newStateFlag = false;
251 }
252
253 // finalState is only filled on transition; keep product valid otherwise.
254 current->setBiasPotential(nullptr);
255
256 if (newStateFlag && finalState) {
258 } else if (current) {
259 *product = *current;
260 }
261
262 if (newStateFlag) {
263 return 1;
264 } else {
265 return 0;
266 }
267}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
static const char BOND_BOOST[]
Definition BondBoost.h:75
std::shared_ptr< Potential > pot
Definition Job.h:63
Parameters params
Definition Job.h:58
long refine(const std::vector< std::shared_ptr< Matter > > &buff, Matter *reactant)
Binary search for the transition frame in a snapshot buffer.
std::shared_ptr< Matter > saddle
std::shared_ptr< Matter > product
std::shared_ptr< Matter > finalState
std::shared_ptr< Matter > reactant
bool checkState(Matter *current, Matter *reactant)
Minimize a copy of current and compare to reactant.
std::shared_ptr< Matter > current
void dephase()
Dephase the trajectory to ensure thermal independence.
std::shared_ptr< Matter > finalStateTmp
std::vector< double > timeBuffer
std::vector< double > biasBuffer

◆ reportResults()

void eonc::SafeHyperJob::reportResults ( )
overrideprivatevirtual

Post-dynamics logging (override for job-specific messages).

Reimplemented from eonc::ReplicaDynamicsJob.

Definition at line 21 of file SafeHyperJob.cpp.

21 {
22 if (newStateFlag) {
23 QUILL_LOG_DEBUG(log, "Transition time: {:.2e} s",
24 minCorrectedTime * 1.0e-15 * params.constants().timeUnit);
25 } else {
26 QUILL_LOG_DEBUG(log,
27 "No new state was found in {} dynamics steps ({:.3e} s)",
28 params.dynamics_options().steps,
29 time * 1.0e-15 * params.constants().timeUnit);
30 }
31}

Member Data Documentation

◆ biasBuffer

std::vector<double> eonc::SafeHyperJob::biasBuffer
private

Definition at line 30 of file SafeHyperJob.h.

◆ timeBuffer

std::vector<double> eonc::SafeHyperJob::timeBuffer
private

Definition at line 29 of file SafeHyperJob.h.

◆ transitionPot

double eonc::SafeHyperJob::transitionPot {0.0}
private

Definition at line 28 of file SafeHyperJob.h.

28{0.0};

The documentation for this class was generated from the following files: