Run for fixed length of time with fix dt/reset

I had a discussion with a coworker this morning that prompted me to ask,
how difficult would it be, given LAMMPS's existing implementations, to
define a command (for example, "run_time") that would run a simulation not
for a specified number of time steps, but until a specified amount of
("real") time has passed? For example,
   run_time 2.0E3
would run molecular dynamics for two thousand time units (picoseconds, for
example). This is a trivial change for fixed-timestep simulations, but
becomes non-trivial when using fix dt/reset.

I poked around in run.cpp, and my guess would be that any such routine
would have to somehow fake out the Verlet::run function, which expects an
argument that is the number of time steps.

It is of course possible to do this in a loop, like so:
   fix 1 all dt/reset 10 1.0E-9 1.0E-3 0.01 units box
   variable realtime equal f_1[1]
   run 0 # Compensates for "pre no" on run below
   label runstart
   run 1000 pre no post no
   if "${realtime} > 100.0" then "jump SELF endrun"
   jump SELF startrun
   label endrun
However, that disrupts the output considerably and adds some overhead from
entering and exiting the loop so many times. It also overshoots the final
time by as much as 999 time steps in the example above.

I have a vague recollection of a discussion related to this popping up
before, so I apologize if this issue has been addressed already.

Karl D. Hammond
University of Tennessee, Knoxville
[email protected]

"You can never know everything, and part of what you know is always
   wrong. A portion of wisdom lies in knowing that. A portion of courage
   lies in going on anyway."
"Nothing ever goes as you expect. Expect nothing, and you will not be

You can streamline the loop you
wrote by using something like

run 10000 pre no post no every 100 "if '${time} < 300.0' then quit"

This gets rid of loop overhead. It doesn't work to
replace "quit" with jump out of the loop, but that is
probably do-able. I'd have to think about it more.