[lammps-users] problem trying to update a compute

I am trying to write a new method (based off the temper command), and have run into 2 snags.

the first is that I have a compute which I need to track in my time integration loop and have available at times different than those I want to have for the thermo output (it is also included in a thermo_style custom command).

This compute is of the type ‘compute reduce max…’, and I am able to access the values by using something like:

my_maxdisp = maxdispcompute->compute_scalar();

However, this appears to only give me the value that is available from the last time the compute was calculated (i.e. from the last thermo ouput step), so I tried borrowing an idea from the pe compute in temper.cpp so that I have the following line after the above line:

maxdispcompute->addstep(update->ntimestep + nevery);

But I still seem to only get the values that were calculated at the last thermo output step. And when I remove that compute from the thermo_style custom line, it seems to work as I expect (updating at the times given in the addstep call). Any ideas what could be going on here? is there a way to do this that will allow me to have this value in the thermo output, but not have to have the thermo output steps match up with the steps in my time loop?

The second is how to go about selectively triggering a dump, rather than dumping at a uniform time. Is there a way to do this in the input file? or is this best done in the source code… and if so, how?

Thanks,

Dave

David E. Farrell

Graduate Student

Mechanical Engineering

Northwestern University

email: [email protected]…435…

Dave,

With the information you’ve provided, and without looking at your source code, I can come up with some guesses as to what is going on. But I’d recommend a simple solution: create two separate “reduce max” computes with different names: one for the thermo output and one for use by your new method. (This approach will be slightly inefficient due to duplicating work when the intervals coincide, but it will probably be less confusing for you to code up.) Then, make sure that your new method does the addstep for your compute within the for loop (see line 206 of temper.cpp as an example), so that the addstep method gets called each time.

On your second question, you could use a series of commands in the sequence: dump, run, undump, dump, run, undump. But that is really a “manual” trigger. You probably want something more automated that triggers when something special happens during your simulation. Perhaps you could use a loop ( http://lammps.sandia.gov/doc/jump.html ), with an “if” command ( http://lammps.sandia.gov/doc/if.html ) inside the loop to periodically check to see if your condition has been met and do a dump if it has. Note that you can perform dumps that print a single time snapshot per file.

If you want something more special-purpose and/or complex than this, you could write a fix that triggers a dump whenever your criteria has been met. See the documentation about writing your own fix: http://lammps.sandia.gov/doc/Section_modify.html#fix

Paul

I tried making 2 computes - and the same behavior occurs. it seems that the thermo output frequency is dominating, regardless of what I do. I have illustrated this by changing the frequency to 1 (which would match the setup in my new command call in the input file) - and indeed, even the new compute gets updated at the times the thermo output is computed. I am wondering if there isn’t some gotcha with the thermo output vs added steps…

Here is my input file, the source code for my method and the universe log file (this runs on several partitions so this is just the global one showing the output that is only being updated every 10 steps, in accordance with the thermo output frequency). at line 158 is the addstep call within the time loop.

Perhaps you can catch something that I can’t

Thanks,

Dave

run_PRD.cpp (6.36 KB)

PRD_test.in (2.28 KB)

log.lammps (1.48 KB)

All that compute->addstep() does is insure that computes
which need energy or virial info have that computed on
the apppropriate timesteps. If you call compute->compute_scalar()
there is no way you will get out-of-date info unless you wrote
a compute yourself that doesn't return the right thing.

Steve

In my last post, I attached the source and input files I am working with (I can email you the entire thing if you want). I am using lammps internal computes (nothing I made). What I am seeing is that for some reason it appears the thermo output frequency controls when the values are updated - despite the calls I put in to compute->compute_scalar(). I removed the addstep calls.

The compute setup I am using is like this:

fix 1 interior coord/original
compute 4 interior displace/atom 1
compute 5 interior reduce max c_4[4]
compute 6 interior reduce max c_4[4]

I am accessing compute 6 in my method, and trying to get its value every step (for testing). compute 5 is outputted at every thermo output step in the thermo output.

I checked this by making the frequency that I compute the my_maxdisp variable in the source code different than the thermo output frequency. what I see for when the update in my code is done every step while the thermo frequency is set to 10 steps is something like this (what I am outputting is the value of my_maxdisp on each partition):

LAMMPS (22 Jan 2008)
Running on 4 partitions of processors
Initial ${replica} setting: value 1 on partition 0
Setting up Parallel Replica Dynamics Evolve and Check run …
Step D1 D2 …
42010 0.000000 0.000000 0.000000 0.000000
42011 0.000000 0.000000 0.000000 0.000000
42012 0.000000 0.000000 0.000000 0.000000
42013 0.000000 0.000000 0.000000 0.000000
42014 0.000000 0.000000 0.000000 0.000000
42015 0.000000 0.000000 0.000000 0.000000
42016 0.000000 0.000000 0.000000 0.000000
42017 0.000000 0.000000 0.000000 0.000000
42018 0.000000 0.000000 0.000000 0.000000
42019 0.000000 0.000000 0.000000 0.000000
42020 0.429573 0.450896 0.452040 0.429213

Meanwhile, when I set the thermo output and the my_maxdisp re-compute frequency to 1, I get the maximum displacement being different at every step:

LAMMPS (22 Jan 2008)
Running on 4 partitions of processors
Initial ${replica} setting: value 1 on partition 0
Setting up Parallel Replica Dynamics Evolve and Check run …
Step D1 D2 …
42010 0.000000 0.000000 0.000000 0.000000
42011 0.049921 0.050047 0.046568 0.050565
42012 0.099415 0.098770 0.092960 0.100878
42013 0.147208 0.145255 0.138430 0.150010
42014 0.191983 0.194916 0.182233 0.198303
42015 0.238370 0.245408 0.225566 0.246968
42016 0.285671 0.294146 0.274286 0.292932
42017 0.329769 0.339989 0.323084 0.335067
42018 0.369290 0.381925 0.369605 0.372356
42019 0.402935 0.419113 0.412863 0.403949
42020 0.429573 0.450896 0.452040 0.429213

Since you say that it is impossible that the compute_scalar() call does not return an up-to-date value, I am curious about why I see this discrepancy which seems to be directly related to the thermo output frequency. I guess another culprit could be a race-condition that makes it such that the values haven’t yet been updated on the universe root process when id does the printing- but that seems unlikely.

Dave

I think the problem is that the compute reduce you are accessing invokes
computes itself underneath (displace/atom). That one will think
it has already been invoked on the current timestep unless its
"invoked" flag is cleared.

So you should call modify->clearstep_compute() from your fix
before accessing these computes.

This is what thermo and dumps and various fixes (fix ave/time, etc)
do before potentially calling a hierarchy of computes.

Steve

Ah, as I looked through the compute code more, I wondered if something like that was happening. That the displace/atom may not be updating makes a lot of sense.

Dave

Just wanted to post to say that adding the modify->clearstep_compute() did make it all work out.

Thanks,

Dave