Commit 88a33edb authored by Steve Plimpton's avatar Steve Plimpton Committed by GitHub
Browse files

Merge pull request #680 from lammps/map-yes

add atom_modify map yes, also timers to create_atoms and replicate
parents f7cbdcf9 6820db99
Loading
Loading
Loading
Loading
+29 −25
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ atom_modify keyword values ... :pre
one or more keyword/value pairs may be appended :ulb,l
keyword = {id} or {map} or {first} or {sort} :l
   {id} value = {yes} or {no}
   {map} value = {array} or {hash}
   {map} value = {yes} or {array} or {hash}
   {first} value = group-ID = group whose atoms will appear first in internal atom lists
   {sort} values = Nfreq binsize
     Nfreq = sort atoms spatially every this many time steps
@@ -25,8 +25,8 @@ keyword = {id} or {map} or {first} or {sort} :l

[Examples:]

atom_modify map hash
atom_modify map array sort 10000 2.0
atom_modify map yes
atom_modify map hash sort 10000 2.0
atom_modify first colloid :pre

[Description:]
@@ -62,29 +62,33 @@ switch. This is described in "Section 2.2"_Section_start.html#start_2
of the manual.  If atom IDs are not used, they must be specified as 0
for all atoms, e.g. in a data or restart file.

The {map} keyword determines how atom ID lookup is done for molecular
atom styles.  Lookups are performed by bond (angle, etc) routines in
LAMMPS to find the local atom index associated with a global atom ID.

When the {array} value is used, each processor stores a lookup table
of length N, where N is the largest atom ID in the system.  This is a
The {map} keyword determines how atoms with specific IDs are found
when required.  An example are the bond (angle, etc) methods which
need to find the local index of an atom with a specific global ID
which is a bond (angle, etc) partner.  LAMMPS performs this operation
efficiently by creating a "map", which is either an {array} or {hash}
table, as descibed below.

When the {map} keyword is not specified in your input script, LAMMPS
only creates a map for "atom_styles"_atom_style.html for molecular
systems which have permanent bonds (angles, etc).  No map is created
for atomic systems, since it is normally not needed.  However some
LAMMPS commands require a map, even for atomic systems, and will
generate an error if one does not exist.  The {map} keyword thus
allows you to force the creation of a map.  The {yes} value will
create either an {array} or {hash} style map, as explained in the next
paragraph.  The {array} and {hash} values create an atom-style or
hash-style map respectively.

For an {array}-style map, each processor stores a lookup table of
length N, where N is the largest atom ID in the system.  This is a
fast, simple method for many simulations, but requires too much memory
for large simulations.  The {hash} value uses a hash table to perform
the lookups.  This can be slightly slower than the {array} method, but
its memory cost is proportional to the number of atoms owned by a
processor, i.e. N/P when N is the total number of atoms in the system
and P is the number of processors.

When this setting is not specified in your input script, LAMMPS
creates a map, if one is needed, as an array or hash.  See the
discussion of default values below for how LAMMPS chooses which kind
of map to build.  Note that atomic systems do not normally need to
create a map.  However, even in this case some LAMMPS commands will
create a map to find atoms (and then destroy it), or require a
permanent map.  An example of the former is the "velocity loop
all"_velocity.html command, which uses a map when looping over all
atoms and insuring the same velocity values are assigned to an atom
ID, no matter which processor owns it.
for large simulations.  For a {hash}-style map, a hash table is
created on each processor, which finds an atom ID in constant time
(independent of the global number of atom IDs).  It can be slightly
slower than the {array} map, but its memory cost is proportional to
the number of atoms owned by a processor, i.e. N/P when N is the total
number of atoms in the system and P is the number of processors.

The {first} keyword allows a "group"_group.html to be specified whose
atoms will be maintained as the first atoms in each processor's list
+20 −16
Original line number Diff line number Diff line
@@ -393,32 +393,36 @@ thermostatting and barostatting.
:line

These fixes compute a temperature and pressure each timestep.  To do
this, the fix creates its own computes of style "temp" and "pressure",
as if one of these two sets of commands had been issued:
this, the thermostat and barostat fixes create their own computes of
style "temp" and "pressure", as if one of these sets of commands had
been issued:

For fix nvt:
compute fix-ID_temp group-ID temp
compute fix-ID_press group-ID pressure fix-ID_temp :pre

For fix npt and fix nph:
compute fix-ID_temp all temp
compute fix-ID_press all pressure fix-ID_temp :pre

See the "compute temp"_compute_temp.html and "compute
pressure"_compute_pressure.html commands for details.  Note that the
IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID
+ underscore + "press".  For fix nvt, the group for the new computes
is the same as the fix group.  For fix nph and fix npt, the group for
the new computes is "all" since pressure is computed for the entire
system.
For fix nvt, the group for the new temperature compute is the same as
the fix group.  For fix npt and fix nph, the group for both the new
temperature and pressure compute is "all" since pressure is computed
for the entire system.  In the case of fix nph, the temperature
compute is not used for thermostatting, but just for a kinetic-energy
contribution to the pressure.  See the "compute
temp"_compute_temp.html and "compute pressure"_compute_pressure.html
commands for details.  Note that the IDs of the new computes are the
fix-ID + underscore + "temp" or fix_ID + underscore + "press".

Note that these are NOT the computes used by thermodynamic output (see
the "thermo_style"_thermo_style.html command) with ID = {thermo_temp}
and {thermo_press}.  This means you can change the attributes of this
and {thermo_press}.  This means you can change the attributes of these
fix's temperature or pressure via the
"compute_modify"_compute_modify.html command or print this temperature
or pressure during thermodynamic output via the "thermo_style
custom"_thermo_style.html command using the appropriate compute-ID.
It also means that changing attributes of {thermo_temp} or
{thermo_press} will have no effect on this fix.
"compute_modify"_compute_modify.html command.  Or you can print this
temperature or pressure during thermodynamic output via the
"thermo_style custom"_thermo_style.html command using the appropriate
compute-ID.  It also means that changing attributes of {thermo_temp}
or {thermo_press} will have no effect on this fix.

Like other fixes that perform thermostatting, fix nvt and fix npt can
be used with "compute commands"_compute.html that calculate a
+3 −2
Original line number Diff line number Diff line
@@ -453,12 +453,12 @@ void Atom::create_avec(const char *style, int narg, char **arg, int trysuffix)
  // if molecular system:
  // atom IDs must be defined
  // force atom map to be created
  // map style may be reset by map_init() and its call to map_style_set()
  // map style will be reset to array vs hash to by map_init()

  molecular = avec->molecular;
  if (molecular && tag_enable == 0)
    error->all(FLERR,"Atom IDs must be used for molecular systems");
  if (molecular) map_style = 1;
  if (molecular) map_style = 3;
}

/* ----------------------------------------------------------------------
@@ -593,6 +593,7 @@ void Atom::modify_params(int narg, char **arg)
                   "Atom_modify map command after simulation box is defined");
      if (strcmp(arg[iarg+1],"array") == 0) map_user = 1;
      else if (strcmp(arg[iarg+1],"hash") == 0) map_user = 2;
      else if (strcmp(arg[iarg+1],"yes") == 0) map_user = 3;
      else error->all(FLERR,"Illegal atom_modify command");
      map_style = map_user;
      iarg += 2;
+2 −2
Original line number Diff line number Diff line
@@ -298,12 +298,12 @@ int Atom::map_style_set()
  MPI_Allreduce(&max,&map_tag_max,1,MPI_LMP_TAGINT,MPI_MAX,world);

  // set map_style for new map
  // if user-selected, use that setting
  // if user-selected to array/hash, use that setting
  // else if map_tag_max > 1M, use hash
  // else use array

  int map_style_old = map_style;
  if (map_user) map_style = map_user;
  if (map_user == 1 || map_user == 2) map_style = map_user;
  else if (map_tag_max > 1000000) map_style = 2;
  else map_style = 1;

+14 −2
Original line number Diff line number Diff line
@@ -343,6 +343,11 @@ void CreateAtoms::command(int narg, char **arg)
    }
  }

  // Record wall time for atom creation

  MPI_Barrier(world);
  double time1 = MPI_Wtime();

  // clear ghost count and any ghost bonus data internal to AtomVec
  // same logic as beginning of Comm::exchange()
  // do it now b/c creating atoms will overwrite ghost atoms
@@ -509,6 +514,9 @@ void CreateAtoms::command(int narg, char **arg)
    if (domain->triclinic) domain->lamda2x(atom->nlocal);
  }

  MPI_Barrier(world);
  double time2 = MPI_Wtime();

  // clean up

  delete ranmol;
@@ -521,12 +529,16 @@ void CreateAtoms::command(int narg, char **arg)
  // print status

  if (comm->me == 0) {
    if (screen)
    if (screen) {
      fprintf(screen,"Created " BIGINT_FORMAT " atoms\n",
              atom->natoms-natoms_previous);
    if (logfile)
      fprintf(screen,"  Time spent = %g secs\n",time2-time1);
    }
    if (logfile) {
      fprintf(logfile,"Created " BIGINT_FORMAT " atoms\n",
              atom->natoms-natoms_previous);
      fprintf(logfile,"  Time spent = %g secs\n",time2-time1);
    }
  }

  // for MOLECULE mode:
Loading