25 auto seed = std::make_shared<Matter>(
pot,
params);
26 std::string reactantFilename =
29 QUILL_LOG_CRITICAL(
log,
"Failed to load {}", reactantFilename);
30 throw std::runtime_error(
"failed to load " + reactantFilename);
36std::shared_ptr<Matter>
39 throw std::runtime_error(
"runFromMatter: initial Matter is null");
52 QUILL_LOG_DEBUG(
log,
"Minimizing initial reactant");
77 const double dt =
params.dynamics_options().time_step;
78 auto to_steps = [&](
double interval) ->
long {
79 if (!(dt > 0.0) || !(interval > 0.0)) {
82 const long n =
static_cast<long>(interval / dt);
87 to_steps(
params.parallel_replica_options().state_check_interval);
88 c.
record = to_steps(
params.parallel_replica_options().record_interval);
100 const std::vector<std::shared_ptr<Matter>> &buff,
Matter *react) {
101 QUILL_LOG_TRACE_L1(
log,
"Refining transition time.");
102 const long n =
static_cast<long>(buff.size());
104 throw std::runtime_error(
105 "ReplicaDynamics refine: need at least two snapshots");
111 while ((hi - lo) > 1) {
112 long mid = lo + (hi - lo) / 2;
113 if (!
checkState(buff[
static_cast<size_t>(mid)].get(), react)) {
120 long idx = (lo + hi) / 2 + 1;
131 const double dt =
params.dynamics_options().time_step;
133 throw std::invalid_argument(
134 "ReplicaDynamicsJob::dephase: time_step must be positive");
137 static_cast<long>(
params.parallel_replica_options().dephase_time / dt);
139 QUILL_LOG_DEBUG(
log,
"Dephasing for {:.2f} fs",
140 params.parallel_replica_options().dephase_time *
141 params.constants().timeUnit);
143 long step = 0, loop = 0;
145 while (step < DephaseSteps) {
146 long dephaseBufferLength = DephaseSteps - step;
147 if (dephaseBufferLength < 1) {
151 std::vector<std::shared_ptr<Matter>> dephaseBuffer(dephaseBufferLength);
153 for (
long i = 0; i < dephaseBufferLength; i++) {
154 dephaseBuffer[i] = std::make_shared<Matter>(
pot,
params);
161 if (transitionFlag) {
162 if (dephaseBuffer.size() < 2) {
164 velocity = velocity * (-1);
165 current->setVelocities(velocity);
169 QUILL_LOG_DEBUG(
log,
"loop = {}; dephase refine step = {}", loop,
171 long ts = dephaseRefineStep - 1;
172 ts = (ts > 0) ? ts : 0;
175 "Dephasing warning: in a new state, inverse the momentum and restart "
180 velocity = velocity * (-1);
181 current->setVelocities(velocity);
184 step = step + dephaseBufferLength;
185 QUILL_LOG_TRACE_L1(
log,
"Successful dephasing for {} steps", step);
188 const long loop_max =
params.parallel_replica_options().dephase_loop_max;
189 if (loop_max > 0 && loop >= loop_max) {
192 "Reach dephase loop maximum, stop dephasing! Dephased for {} steps",
196 QUILL_LOG_DEBUG(
log,
"Successfully Dephased for {:.2f} fs",
197 step *
params.dynamics_options().time_step *
198 params.constants().timeUnit);
203 std::string resultsFilename(
"results.dat");
208 std::ofstream out(resultsFilename, std::ios::binary);
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",
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);
220 out << std::format(
"{} force_calls_refine\n",
refineFCalls);
221 out << std::format(
"{} transition_found\n", (
newStateFlag) ? 1 : 0);
224 out << std::format(
"{:e} transition_time_s\n",
226 params.constants().timeUnit);
227 out << std::format(
"{:f} potential_energy_product\n",
228 product->getPotentialEnergy());
229 out << std::format(
"{:f} moved_distance\n",
233 out << std::format(
"{:e} simulation_time_s\n",
234 time * 1.0e-15 *
params.constants().timeUnit);
235 out << std::format(
"{:f} speedup\n",
237 params.dynamics_options().time_step);
241 std::string reactantFilename(
"reactant.con");
244 QUILL_LOG_ERROR(
log,
"Failed to write {}", reactantFilename);
248 std::string productFilename(
"product.con");
251 QUILL_LOG_ERROR(
log,
"Failed to write {}", productFilename);
254 if (
params.parallel_replica_options().refine_transition) {
255 std::string saddleFilename(
"saddle.con");
258 QUILL_LOG_ERROR(
log,
"Failed to write {}", saddleFilename);
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
void oneStep(int stepNumber=-1)
RAII wrapper for tracking force calls over a scope.
std::shared_ptr< Potential > pot
bool relax(bool quiet=false, bool writeMovie=false, bool checkpoint=false, std::string prefixMovie=std::string(), std::string prefixCheckpoint=std::string(), bool retainMovieFrames=false)
bool compare(const Matter &matter, bool indistinguishable=false)
std::vector< std::string > returnFiles
std::vector< std::string > run() override
Virtual run; used solely for dynamic dispatch.
long refine(const std::vector< std::shared_ptr< Matter > > &buff, Matter *reactant)
Binary search for the transition frame in a snapshot buffer.
PrdClock prdClock() const
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 > reactant
bool checkState(Matter *current, Matter *reactant)
Minimize a copy of current and compare to reactant.
std::shared_ptr< Matter > runFromMatter(std::shared_ptr< Matter > initial)
Matter-first entry: seed geometry, skip con2matter load.
std::shared_ptr< Matter > current
void dephase()
Dephase the trajectory to ensure thermal independence.
std::shared_ptr< Matter > finalStateTmp
std::string getRelevantFile(std::string filename)
constexpr bool io_ok(IoStatus s) noexcept
RAII resource manager for the ARTn C library with global synchronization.
Clamped PRD clock: state_check, record, and buffer length are all >= 1.