Loading...
Searching...
No Matches
eonc::ReplicaDynamicsJob Class Referenceabstract

Base class for replica dynamics jobs (TAD, SafeHyper). More...

#include <ReplicaDynamicsJob.h>

Inheritance diagram for eonc::ReplicaDynamicsJob:

Classes

struct  PrdClock
 Clamped PRD clock: state_check, record, and buffer length are all >= 1. More...

Public Member Functions

 ~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.

Protected Member Functions

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.
virtual int dynamics ()=0
 The accelerated dynamics loop. Returns status (1 = transition, 0 = none).
virtual void reportResults ()
 Post-dynamics logging (override for job-specific messages).

Protected Attributes

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

Base class for replica dynamics jobs (TAD, SafeHyper).

Provides shared infrastructure: state checking via minimize-and-compare, binary search refinement of transition times, dephasing, and results I/O. Subclasses implement initExtra() for job-specific matter objects and dynamics() for the accelerated MD loop.

Definition at line 29 of file ReplicaDynamicsJob.h.

Constructor & Destructor Documentation

◆ ~ReplicaDynamicsJob()

eonc::ReplicaDynamicsJob::~ReplicaDynamicsJob ( )
overridedefault

Member Function Documentation

◆ checkState()

bool eonc::ReplicaDynamicsJob::checkState ( Matter * current,
Matter * reactant )
protected

Minimize a copy of current and compare to reactant.

Returns true if a transition (new state) was detected.

Definition at line 69 of file ReplicaDynamicsJob.cpp.

69 {
70 Matter tmp(pot, params);
71 tmp = *curr;
72 tmp.relax(true);
73 return !tmp.compare(*react);
74}
std::shared_ptr< Potential > pot
Definition Job.h:63
Parameters params
Definition Job.h:58

◆ dephase()

void eonc::ReplicaDynamicsJob::dephase ( )
protected

Dephase the trajectory to ensure thermal independence.

Definition at line 130 of file ReplicaDynamicsJob.cpp.

130 {
131 const double dt = params.dynamics_options().time_step;
132 if (!(dt > 0.0)) {
133 throw std::invalid_argument(
134 "ReplicaDynamicsJob::dephase: time_step must be positive");
135 }
136 long DephaseSteps =
137 static_cast<long>(params.parallel_replica_options().dephase_time / dt);
138 Dynamics dephaseDynamics(current.get(), params);
139 QUILL_LOG_DEBUG(log, "Dephasing for {:.2f} fs",
140 params.parallel_replica_options().dephase_time *
141 params.constants().timeUnit);
142
143 long step = 0, loop = 0;
144
145 while (step < DephaseSteps) {
146 long dephaseBufferLength = DephaseSteps - step;
147 if (dephaseBufferLength < 1) {
148 break;
149 }
150 loop++;
151 std::vector<std::shared_ptr<Matter>> dephaseBuffer(dephaseBufferLength);
152
153 for (long i = 0; i < dephaseBufferLength; i++) {
154 dephaseBuffer[i] = std::make_shared<Matter>(pot, params);
155 dephaseDynamics.oneStep();
156 *dephaseBuffer[i] = *current;
157 }
158
159 bool transitionFlag = checkState(current.get(), reactant.get());
160
161 if (transitionFlag) {
162 if (dephaseBuffer.size() < 2) {
163 AtomMatrix velocity = current->getVelocities();
164 velocity = velocity * (-1);
165 current->setVelocities(velocity);
166 continue;
167 }
168 long dephaseRefineStep = refine(dephaseBuffer, reactant.get());
169 QUILL_LOG_DEBUG(log, "loop = {}; dephase refine step = {}", loop,
170 dephaseRefineStep);
171 long ts = dephaseRefineStep - 1;
172 ts = (ts > 0) ? ts : 0;
173 QUILL_LOG_DEBUG(
174 log,
175 "Dephasing warning: in a new state, inverse the momentum and restart "
176 "from step {}",
177 step + ts);
178 *current = *dephaseBuffer[ts];
179 AtomMatrix velocity = current->getVelocities();
180 velocity = velocity * (-1);
181 current->setVelocities(velocity);
182 step = step + ts;
183 } else {
184 step = step + dephaseBufferLength;
185 QUILL_LOG_TRACE_L1(log, "Successful dephasing for {} steps", step);
186 }
187
188 const long loop_max = params.parallel_replica_options().dephase_loop_max;
189 if (loop_max > 0 && loop >= loop_max) {
190 QUILL_LOG_DEBUG(
191 log,
192 "Reach dephase loop maximum, stop dephasing! Dephased for {} steps",
193 step);
194 break;
195 }
196 QUILL_LOG_DEBUG(log, "Successfully Dephased for {:.2f} fs",
197 step * params.dynamics_options().time_step *
198 params.constants().timeUnit);
199 }
200}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
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 > reactant
bool checkState(Matter *current, Matter *reactant)
Minimize a copy of current and compare to reactant.
std::shared_ptr< Matter > current

◆ dynamics()

virtual int eonc::ReplicaDynamicsJob::dynamics ( )
protectedpure virtual

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

Implemented in eonc::SafeHyperJob, and eonc::TADJob.

◆ initExtra()

virtual void eonc::ReplicaDynamicsJob::initExtra ( )
inlineprotectedvirtual

Create any extra matter objects needed by the subclass.

Reimplemented in eonc::TADJob.

Definition at line 94 of file ReplicaDynamicsJob.h.

94{}

◆ Job() [1/4]

eonc::Job::Job ( std::shared_ptr< Potential > potPassed,
const Parameters & parameters )
inline

Definition at line 91 of file Job.h.

92 : jtype{parameters.main_options().job},
93 params{parameters},
94 owned_runtime_{std::make_unique<Runtime>()},
96 pot{potPassed} {}
std::unique_ptr< Runtime > owned_runtime_
Non-null when this Job owns the composition root (one-shot makeJob).
Definition Job.h:60
JobType jtype
Definition Job.h:57
Runtime * runtime_
Always valid: either owned_runtime_.get() or a caller-owned Runtime.
Definition Job.h:62

◆ Job() [2/4]

eonc::Job::Job ( std::unique_ptr< Parameters > parameters)
inlineexplicit

Own a default-constructed Runtime.

Definition at line 89 of file Job.h.

90 : Job(std::move(parameters), std::make_unique<Runtime>()) {}
Job(std::unique_ptr< Parameters > parameters, Runtime &rt)
Borrow: caller keeps Runtime alive (CLI stack / Python Session).
Definition Job.h:76

◆ Job() [3/4]

eonc::Job::Job ( std::unique_ptr< Parameters > parameters,
Runtime & rt )
inline

Borrow: caller keeps Runtime alive (CLI stack / Python Session).

Definition at line 76 of file Job.h.

77 : jtype{parameters->main_options().job},
78 params{*std::move(parameters)},
80 runtime_{&rt},
81 pot{helpers::makePotential(params.potential_options().potential, params,
82 rt)} {}
std::shared_ptr< Potential > makePotential(const Parameters &params)

◆ Job() [4/4]

eonc::Job::Job ( std::unique_ptr< Parameters > parameters,
std::unique_ptr< Runtime > rt )
inline

Own a Runtime (one-shot makeJob / rvalue).

Definition at line 84 of file Job.h.

85 : Job(std::move(parameters), *rt) {
86 adoptRuntime(std::move(rt));
87 }
void adoptRuntime(std::unique_ptr< Runtime > rt)
Take ownership of a Runtime previously passed as Runtime&.
Definition Job.h:67

◆ prdClock()

ReplicaDynamicsJob::PrdClock eonc::ReplicaDynamicsJob::prdClock ( ) const
protected

Definition at line 76 of file ReplicaDynamicsJob.cpp.

76 {
77 const double dt = params.dynamics_options().time_step;
78 auto to_steps = [&](double interval) -> long {
79 if (!(dt > 0.0) || !(interval > 0.0)) {
80 return 1;
81 }
82 const long n = static_cast<long>(interval / dt);
83 return n < 1 ? 1 : n;
84 };
85 PrdClock c;
86 c.state_check =
87 to_steps(params.parallel_replica_options().state_check_interval);
88 c.record = to_steps(params.parallel_replica_options().record_interval);
89 if (c.record > c.state_check) {
90 c.record = c.state_check;
91 }
92 c.buffer = c.state_check / c.record;
93 if (c.buffer < 1) {
94 c.buffer = 1;
95 }
96 return c;
97}
Clamped PRD clock: state_check, record, and buffer length are all >= 1.

◆ refine()

long eonc::ReplicaDynamicsJob::refine ( const std::vector< std::shared_ptr< Matter > > & buff,
Matter * reactant )
protected

Binary search for the transition frame in a snapshot buffer.

Returns an index in [1, buff.size()) so refineStep - 1 is in range.

Definition at line 99 of file ReplicaDynamicsJob.cpp.

100 {
101 QUILL_LOG_TRACE_L1(log, "Refining transition time.");
102 const long n = static_cast<long>(buff.size());
103 if (n <= 1) {
104 throw std::runtime_error(
105 "ReplicaDynamics refine: need at least two snapshots");
106 }
107
108 long lo = 0;
109 long hi = n - 1;
110
111 while ((hi - lo) > 1) {
112 long mid = lo + (hi - lo) / 2;
113 if (!checkState(buff[static_cast<size_t>(mid)].get(), react)) {
114 lo = mid;
115 } else {
116 hi = mid;
117 }
118 }
119
120 long idx = (lo + hi) / 2 + 1;
121 if (idx < 1) {
122 idx = 1;
123 }
124 if (idx >= n) {
125 idx = n - 1;
126 }
127 return idx;
128}
quill::Logger * get() noexcept
Get or create the default "combi" logger.
Definition EonLogger.h:44

◆ reportResults()

virtual void eonc::ReplicaDynamicsJob::reportResults ( )
inlineprotectedvirtual

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

Reimplemented in eonc::SafeHyperJob, and eonc::TADJob.

Definition at line 100 of file ReplicaDynamicsJob.h.

100{}

◆ run()

std::vector< std::string > eonc::ReplicaDynamicsJob::run ( )
overridevirtual

Virtual run; used solely for dynamic dispatch.

Implements eonc::Job.

Definition at line 24 of file ReplicaDynamicsJob.cpp.

24 {
25 auto seed = std::make_shared<Matter>(pot, params);
26 std::string reactantFilename =
27 eonc::helpers::getRelevantFile(params.main_options().conFilename);
28 if (!eonc::io::io_ok(seed->con2matter(reactantFilename))) {
29 QUILL_LOG_CRITICAL(log, "Failed to load {}", reactantFilename);
30 throw std::runtime_error("failed to load " + reactantFilename);
31 }
32 (void)runFromMatter(std::move(seed));
33 return returnFiles;
34}
std::vector< std::string > returnFiles
std::shared_ptr< Matter > runFromMatter(std::shared_ptr< Matter > initial)
Matter-first entry: seed geometry, skip con2matter load.
std::string getRelevantFile(std::string filename)
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38

◆ runFromMatter()

std::shared_ptr< Matter > eonc::ReplicaDynamicsJob::runFromMatter ( std::shared_ptr< Matter > initial)

Matter-first entry: seed geometry, skip con2matter load.

Returns final trajectory Matter (current).

Definition at line 37 of file ReplicaDynamicsJob.cpp.

37 {
38 if (!initial) {
39 throw std::runtime_error("runFromMatter: initial Matter is null");
40 }
41 current = initial;
42 current->setPotential(pot);
43 reactant = std::make_shared<Matter>(pot, params);
44 saddle = std::make_shared<Matter>(pot, params);
45 product = std::make_shared<Matter>(pot, params);
46 finalState = std::make_shared<Matter>(pot, params);
47 finalStateTmp = std::make_shared<Matter>(pot, params);
48
50 time = 0.0;
51
52 QUILL_LOG_DEBUG(log, "Minimizing initial reactant");
53 {
54 eonc::ForceCallTimer timer(minimizeFCalls);
55 *reactant = *current;
56 reactant->relax();
57 }
58
59 initExtra();
60
61 int status = dynamics();
62
63 saveData(status);
65
66 return current;
67}
std::shared_ptr< Matter > saddle
std::shared_ptr< Matter > product
void saveData(int status)
Write results.dat and structure con files.
virtual int dynamics()=0
The accelerated dynamics loop. Returns status (1 = transition, 0 = none).
std::shared_ptr< Matter > finalState
virtual void initExtra()
Create any extra matter objects needed by the subclass.
virtual void reportResults()
Post-dynamics logging (override for job-specific messages).
std::shared_ptr< Matter > finalStateTmp

◆ saveData()

void eonc::ReplicaDynamicsJob::saveData ( int status)
protected

Write results.dat and structure con files.

Definition at line 202 of file ReplicaDynamicsJob.cpp.

202 {
203 std::string resultsFilename("results.dat");
204 returnFiles.push_back(resultsFilename);
205 size_t totalFCalls = minimizeFCalls + mdFCalls + dephaseFCalls + refineFCalls;
206
207 {
208 std::ofstream out(resultsFilename, std::ios::binary);
209 if (out) {
210 out << std::format(
211 "{} potential_type\n",
212 magic_enum::enum_name<PotType>(params.potential_options().potential));
213 out << std::format("{} random_seed\n", params.main_options().randomSeed);
214 out << std::format("{:f} potential_energy_reactant\n",
215 reactant->getPotentialEnergy());
216 out << std::format("{} total_force_calls\n", totalFCalls);
217 out << std::format("{} force_calls_dephase\n", dephaseFCalls);
218 out << std::format("{} force_calls_dynamics\n", mdFCalls);
219 out << std::format("{} force_calls_minimize\n", minimizeFCalls);
220 out << std::format("{} force_calls_refine\n", refineFCalls);
221 out << std::format("{} transition_found\n", (newStateFlag) ? 1 : 0);
222
223 if (newStateFlag) {
224 out << std::format("{:e} transition_time_s\n",
225 minCorrectedTime * 1.0e-15 *
226 params.constants().timeUnit);
227 out << std::format("{:f} potential_energy_product\n",
228 product->getPotentialEnergy());
229 out << std::format("{:f} moved_distance\n",
230 product->distanceTo(*reactant));
231 }
232
233 out << std::format("{:e} simulation_time_s\n",
234 time * 1.0e-15 * params.constants().timeUnit);
235 out << std::format("{:f} speedup\n",
236 time / params.dynamics_options().steps /
237 params.dynamics_options().time_step);
238 }
239 }
240
241 std::string reactantFilename("reactant.con");
242 returnFiles.push_back(reactantFilename);
243 if (!eonc::io::io_ok(reactant->matter2con(reactantFilename))) {
244 QUILL_LOG_ERROR(log, "Failed to write {}", reactantFilename);
245 }
246
247 if (newStateFlag) {
248 std::string productFilename("product.con");
249 returnFiles.push_back(productFilename);
250 if (!eonc::io::io_ok(product->matter2con(productFilename))) {
251 QUILL_LOG_ERROR(log, "Failed to write {}", productFilename);
252 }
253
254 if (params.parallel_replica_options().refine_transition) {
255 std::string saddleFilename("saddle.con");
256 returnFiles.push_back(saddleFilename);
257 if (!eonc::io::io_ok(saddle->matter2con(saddleFilename))) {
258 QUILL_LOG_ERROR(log, "Failed to write {}", saddleFilename);
259 }
260 }
261 }
262}

Member Data Documentation

◆ current

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::current
protected

Definition at line 40 of file ReplicaDynamicsJob.h.

◆ dephaseFCalls

size_t eonc::ReplicaDynamicsJob::dephaseFCalls {0}
protected

Definition at line 54 of file ReplicaDynamicsJob.h.

54{0};

◆ finalState

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::finalState
protected

Definition at line 44 of file ReplicaDynamicsJob.h.

◆ finalStateTmp

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::finalStateTmp
protected

Definition at line 45 of file ReplicaDynamicsJob.h.

◆ log

eonc::log::Scoped eonc::ReplicaDynamicsJob::log
protected

Definition at line 64 of file ReplicaDynamicsJob.h.

◆ mdFCalls

size_t eonc::ReplicaDynamicsJob::mdFCalls {0}
protected

Definition at line 53 of file ReplicaDynamicsJob.h.

53{0};

◆ metaStateFlag

bool eonc::ReplicaDynamicsJob::metaStateFlag {false}
protected

Definition at line 48 of file ReplicaDynamicsJob.h.

48{false};

◆ minCorrectedTime

double eonc::ReplicaDynamicsJob::minCorrectedTime {1.0e200}
protected

Definition at line 60 of file ReplicaDynamicsJob.h.

60{1.0e200};

◆ minimizeFCalls

size_t eonc::ReplicaDynamicsJob::minimizeFCalls {0}
protected

Definition at line 52 of file ReplicaDynamicsJob.h.

52{0};

◆ newStateFlag

bool eonc::ReplicaDynamicsJob::newStateFlag {false}
protected

Definition at line 49 of file ReplicaDynamicsJob.h.

49{false};

◆ product

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::product
protected

Definition at line 43 of file ReplicaDynamicsJob.h.

◆ reactant

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::reactant
protected

Definition at line 41 of file ReplicaDynamicsJob.h.

◆ refineFCalls

size_t eonc::ReplicaDynamicsJob::refineFCalls {0}
protected

Definition at line 55 of file ReplicaDynamicsJob.h.

55{0};

◆ returnFiles

std::vector<std::string> eonc::ReplicaDynamicsJob::returnFiles
protected

Definition at line 63 of file ReplicaDynamicsJob.h.

◆ saddle

std::shared_ptr<Matter> eonc::ReplicaDynamicsJob::saddle
protected

Definition at line 42 of file ReplicaDynamicsJob.h.

◆ time

double eonc::ReplicaDynamicsJob::time {0.0}
protected

Definition at line 59 of file ReplicaDynamicsJob.h.

59{0.0};

◆ transitionStep

long eonc::ReplicaDynamicsJob::transitionStep {0}
protected

Definition at line 58 of file ReplicaDynamicsJob.h.

58{0};

◆ transitionTime

double eonc::ReplicaDynamicsJob::transitionTime {0.0}
protected

Definition at line 61 of file ReplicaDynamicsJob.h.

61{0.0};

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