added internal fix dummy command to enable more control of fix ordering

This commit is contained in:
Steve Plimpton
2019-11-05 12:57:34 -07:00
parent cf251eb8be
commit d8ef5f6991
17 changed files with 253 additions and 32 deletions

View File

@ -24,6 +24,7 @@
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_dummy.h"
#include "fix_neigh_history.h"
#include "comm.h"
#include "neighbor.h"
@ -43,7 +44,6 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp)
no_virial_fdotr_compute = 1;
history = 1;
size_history = 3;
fix_history = NULL;
single_extra = 10;
svector = new double[10];
@ -60,6 +60,19 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp)
// keep default behavior of history[i][j] = -history[j][i]
nondefault_history_transfer = 0;
// create dummy fix as placeholder for FixNeighHistory
// this is so final order of Modify:fix will conform to input script
fix_history = NULL;
char **fixarg = new char*[3];
fixarg[0] = (char *) "NEIGH_HISTORY_DUMMY";
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "DUMMY";
modify->add_fix(3,fixarg,1);
delete [] fixarg;
fix_dummy = (FixDummy *) modify->fix[modify->nfix-1];
}
/* ---------------------------------------------------------------------- */
@ -69,7 +82,9 @@ PairGranHookeHistory::~PairGranHookeHistory()
if (copymode) return;
delete [] svector;
if (fix_history) modify->delete_fix("NEIGH_HISTORY");
if (!fix_history) modify->delete_fix("NEIGH_HISTORY_DUMMY");
else modify->delete_fix("NEIGH_HISTORY");
if (allocated) {
memory->destroy(setflag);
@ -412,7 +427,9 @@ void PairGranHookeHistory::init_style()
dt = update->dt;
// if first init, create Fix needed for storing shear history
// if history is stored and first init, create Fix to store history
// it replaces FixDummy, created in the constructor
// this is so its order in the fix list is preserved
if (history && fix_history == NULL) {
char dnumstr[16];
@ -422,7 +439,7 @@ void PairGranHookeHistory::init_style()
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "NEIGH_HISTORY";
fixarg[3] = dnumstr;
modify->add_fix(4,fixarg,1);
modify->replace_fix("NEIGH_HISTORY_DUMMY",4,fixarg,1);
delete [] fixarg;
fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1];
fix_history->pair = this;

View File

@ -56,6 +56,7 @@ class PairGranHookeHistory : public Pair {
int size_history;
class FixDummy *fix_dummy;
class FixNeighHistory *fix_history;
// storage of rigid body masses for use in granular interactions

View File

@ -1,13 +1,14 @@
/* ----------------------------------------------------------------------
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
@ -25,6 +26,7 @@ See the README file in the top-level LAMMPS directory.
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_dummy.h"
#include "fix_neigh_history.h"
#include "comm.h"
#include "neighbor.h"
@ -62,7 +64,6 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp)
{
single_enable = 1;
no_virial_fdotr_compute = 1;
fix_history = NULL;
single_extra = 12;
svector = new double[single_extra];
@ -90,6 +91,19 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp)
nondefault_history_transfer = 0;
tangential_history_index = 0;
roll_history_index = twist_history_index = 0;
// create dummy fix as placeholder for FixNeighHistory
// this is so final order of Modify:fix will conform to input script
fix_history = NULL;
char **fixarg = new char*[3];
fixarg[0] = (char *) "NEIGH_HISTORY_DUMMY";
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "DUMMY";
modify->add_fix(3,fixarg,1);
delete [] fixarg;
fix_dummy = (FixDummy *) modify->fix[modify->nfix-1];
}
/* ---------------------------------------------------------------------- */
@ -97,7 +111,9 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp)
PairGranular::~PairGranular()
{
delete [] svector;
if (fix_history) modify->delete_fix("NEIGH_HISTORY");
if (!fix_history) modify->delete_fix("NEIGH_HISTORY_DUMMY");
else modify->delete_fix("NEIGH_HISTORY");
if (allocated) {
memory->destroy(setflag);
@ -1021,8 +1037,9 @@ void PairGranular::init_style()
dt = update->dt;
// if history is stored:
// if first init, create Fix needed for storing history
// if history is stored and first init, create Fix to store history
// it replaces FixDummy, created in the constructor
// this is so its order in the fix list is preserved
if (use_history && fix_history == NULL) {
char dnumstr[16];
@ -1032,7 +1049,7 @@ void PairGranular::init_style()
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "NEIGH_HISTORY";
fixarg[3] = dnumstr;
modify->add_fix(4,fixarg,1);
modify->replace_fix("NEIGH_HISTORY_DUMMY",4,fixarg,1);
delete [] fixarg;
fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1];
fix_history->pair = this;

View File

@ -51,6 +51,7 @@ class PairGranular : public Pair {
double *maxrad_dynamic,*maxrad_frozen;
double **cut;
class FixDummy *fix_dummy;
class FixNeighHistory *fix_history;
// storage of rigid body masses for use in granular interactions
@ -111,4 +112,4 @@ Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/
*/

View File

@ -302,10 +302,10 @@ FixBocs::FixBocs(LAMMPS *lmp, int narg, char **arg) :
// pre_exchange only required if flips can occur due to shape changes
if (flipflag && (p_flag[3] || p_flag[4] || p_flag[5]))
pre_exchange_flag = 1;
pre_exchange_flag = pre_exchange_migrate = 1;
if (flipflag && (domain->yz != 0.0 || domain->xz != 0.0 ||
domain->xy != 0.0))
pre_exchange_flag = 1;
pre_exchange_flag = pre_exchange_migrate = 1;
}
// convert input periods to frequencies

View File

@ -22,6 +22,7 @@
#include "atom.h"
#include "force.h"
#include "domain.h"
#include "modify.h"
#include "comm.h"
#include "memory.h"
#include "error.h"
@ -112,19 +113,21 @@ void FixSRP::init()
if ((bptype < 1) || (bptype > atom->ntypes))
error->all(FLERR,"Illegal bond particle type");
// fix SRP should be the first fix running at the PRE_EXCHANGE step.
// Otherwise it might conflict with, e.g. fix deform
// this fix must come before any fix which migrates atoms in its pre_exchange()
// b/c this fix's pre_exchange() creates per-atom data structure
// that data must be current for atom migration to carry it along
if (modify->n_pre_exchange > 1) {
char *first = modify->fix[modify->list_pre_exchange[0]]->id;
if ((comm->me == 0) && (strcmp(id,first) != 0))
error->warning(FLERR,"Internal fix for pair srp defined too late."
" May lead to incorrect behavior.");
for (int i = 0; i < modify->nfix; i++) {
if (modify->fix[i] == this) break;
if (modify->fix[i]->pre_exchange_migrate)
error->all(FLERR,"Fix SRP comes after a fix which "
"migrates atoms in pre_exchange");
}
// setup neigh exclusions for diff atom types
// bond particles do not interact with other types
// type bptype only interacts with itself
char* arg1[4];
arg1[0] = (char *) "exclude";
arg1[1] = (char *) "type";

View File

@ -79,13 +79,18 @@ PairSRP::PairSRP(LAMMPS *lmp) : Pair(lmp)
segment = NULL;
// generate unique fix-id for this pair style instance
fix_id = strdup("XX_FIX_SRP");
fix_id[0] = '0' + srp_instance / 10;
fix_id[1] = '0' + srp_instance % 10;
++srp_instance;
// create fix SRP instance here, as it has to
// be executed before all other fixes
// create fix SRP instance here
// similar to granular pair styles with history,
// this should be early enough that FixSRP::pre_exchange()
// will be invoked before other fixes that migrate atoms
// this is checked for in FixSRP
char **fixarg = new char*[3];
fixarg[0] = fix_id;
fixarg[1] = (char *) "all";
@ -143,7 +148,6 @@ PairSRP::~PairSRP()
------------------------------------------------------------------------- */
void PairSRP::compute(int eflag, int vflag)
{
// setup energy and virial
ev_init(eflag, vflag);
@ -458,6 +462,7 @@ void PairSRP::init_style()
error->all(FLERR,"PairSRP: Pair srp requires newton pair on");
// verify that fix SRP is still defined and has not been changed.
int ifix = modify->find_fix(fix_id);
if (f_srp != (FixSRP *)modify->fix[ifix])
error->all(FLERR,"Fix SRP has been changed unexpectedly");
@ -471,6 +476,7 @@ void PairSRP::init_style()
// bonds of this type will be represented by bond particles
// if bond type is 0, then all bonds have bond particles
// btype = bond type
char c0[20];
char* arg0[2];
sprintf(c0, "%d", btype);
@ -506,7 +512,6 @@ void PairSRP::init_style()
double PairSRP::init_one(int i, int j)
{
if (setflag[i][j] == 0) error->all(FLERR,"PairSRP: All pair coeffs are not set");
cut[j][i] = cut[i][j];

View File

@ -79,6 +79,7 @@ Fix::Fix(LAMMPS *lmp, int /*narg*/, char **arg) :
respa_level = -1;
maxexchange = 0;
maxexchange_dynamic = 0;
pre_exchange_migrate = 0;
scalar_flag = vector_flag = array_flag = 0;
peratom_flag = local_flag = 0;

View File

@ -58,6 +58,7 @@ class Fix : protected Pointers {
int respa_level; // which respa level to apply fix (1-Nrespa)
int maxexchange; // max # of per-atom values for Comm::exchange()
int maxexchange_dynamic; // 1 if fix sets maxexchange dynamically
int pre_exchange_migrate; // 1 if fix migrates atoms in pre_exchange()
int scalar_flag; // 0/1 if compute_scalar() function exists
int vector_flag; // 0/1 if compute_vector() function exists

View File

@ -40,6 +40,7 @@ FixBalance::FixBalance(LAMMPS *lmp, int narg, char **arg) :
if (narg < 6) error->all(FLERR,"Illegal fix balance command");
box_change_domain = 1;
pre_exchange_migrate = 1;
scalar_flag = 1;
extscalar = 0;
vector_flag = 1;

View File

@ -48,6 +48,7 @@ rfix(NULL), irregular(NULL), set(NULL)
no_change_box = 1;
restart_global = 1;
pre_exchange_migrate = 1;
nevery = force->inumeric(FLERR,arg[3]);
if (nevery <= 0) error->all(FLERR,"Illegal fix deform command");

65
src/fix_dummy.cpp Normal file
View File

@ -0,0 +1,65 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "fix_dummy.h"
#include <cstring>
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixDummy::FixDummy(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
// process optional args
// customize here and in setmask() by adding a new keyword from fix.h
// only necessary if both of these are true:
// (a) the real fix you are placeholding for defines the method
// (b) the real fix will be defined so late in run initialization
// that the dummy fix will have already been processed by Modify::init()
// to add its index to its lists of fixes to invoke during timestepping
initial_integrate_flag = final_integrate_flag = 0;
pre_exchange_flag = pre_neighbor_flag = 0;
pre_force_flag = post_force_flag = 0;
end_of_step_flag = 0;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"initial_integrate") == 0) initial_integrate_flag = 1;
else if (strcmp(arg[iarg],"final_integrate") == 0) final_integrate_flag = 1;
else if (strcmp(arg[iarg],"final_integrate") == 0) final_integrate_flag = 1;
else if (strcmp(arg[iarg],"final_integrate") == 0) final_integrate_flag = 1;
else if (strcmp(arg[iarg],"final_integrate") == 0) final_integrate_flag = 1;
else if (strcmp(arg[iarg],"final_integrate") == 0) final_integrate_flag = 1;
else error->all(FLERR,"Illegal fix DUMMY command");
iarg++;
}
}
/* ---------------------------------------------------------------------- */
int FixDummy::setmask()
{
int mask = 0;
if (initial_integrate_flag) mask |= INITIAL_INTEGRATE;
if (final_integrate_flag) mask |= FINAL_INTEGRATE;
if (pre_exchange_flag) mask |= PRE_EXCHANGE;
if (pre_neighbor_flag) mask |= PRE_NEIGHBOR;
if (pre_force_flag) mask |= PRE_FORCE;
if (post_force_flag) mask |= POST_FORCE;
if (end_of_step_flag) mask |= END_OF_STEP;
return mask;
}

53
src/fix_dummy.h Normal file
View File

@ -0,0 +1,53 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
FixStyle(DUMMY,FixDummy)
#else
#ifndef LMP_FIX_DUMMY_H
#define LMP_FIX_DUMMY_H
#include "fix.h"
namespace LAMMPS_NS {
class FixDummy : public Fix {
public:
FixDummy(class LAMMPS *, int, char **);
virtual ~FixDummy() {}
int setmask();
protected:
int initial_integrate_flag,final_integrate_flag;
int pre_exchange_flag,pre_neighbor_flag;
int pre_force_flag,post_force_flag;
int end_of_step_flag;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/

View File

@ -19,6 +19,7 @@
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "modify.h"
#include "force.h"
#include "pair.h"
#include "memory.h"
@ -147,6 +148,19 @@ void FixNeighHistory::init()
if (atom->tag_enable == 0)
error->all(FLERR,"Neighbor history requires atoms have IDs");
// this fix must come before any fix which migrates atoms in its pre_exchange()
// b/c this fix's pre_exchange() creates per-atom data structure
// that data must be current for atom migration to carry it along
for (int i = 0; i < modify->nfix; i++) {
if (modify->fix[i] == this) break;
if (modify->fix[i]->pre_exchange_migrate)
error->all(FLERR,"Fix neigh_history comes after a fix which "
"migrates atoms in pre_exchange");
}
// setup data struct
allocate_pages();
}

View File

@ -492,10 +492,10 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) :
// pre_exchange only required if flips can occur due to shape changes
if (flipflag && (p_flag[3] || p_flag[4] || p_flag[5]))
pre_exchange_flag = 1;
pre_exchange_flag = pre_exchange_migrate = 1;
if (flipflag && (domain->yz != 0.0 || domain->xz != 0.0 ||
domain->xy != 0.0))
pre_exchange_flag = 1;
pre_exchange_flag = pre_exchange_migrate = 1;
}
// convert input periods to frequencies

View File

@ -953,6 +953,46 @@ void Modify::add_fix(int narg, char **arg, int trysuffix)
fix[ifix]->post_constructor();
}
/* ----------------------------------------------------------------------
replace replaceID fix with a new fix
this is used by callers to preserve ordering of fixes
e.g. create replaceID as a FixDummy instance early in the input script
replace it later with the desired Fix instance
------------------------------------------------------------------------- */
void Modify::replace_fix(const char *replaceID,
int narg, char **arg, int trysuffix)
{
int ifix = find_fix(replaceID);
if (ifix < 0) error->all(FLERR,"Modify replace_fix ID could not be found");
// change ID, igroup, style of fix being replaced to match new fix
// requires some error checking on arguments for new fix
if (narg < 3) error->all(FLERR,"Illegal replace_fix invocation");
int jfix = find_fix(arg[0]);
if (jfix >= 0) error->all(FLERR,"Replace_fix ID is already in use");
delete [] fix[ifix]->id;
int n = strlen(arg[0]) + 1;
fix[ifix]->id = new char[n];
strcpy(fix[ifix]->id,arg[0]);
int jgroup = group->find(arg[1]);
if (jgroup == -1) error->all(FLERR,"Could not find replace_fix group ID");
fix[ifix]->igroup = jgroup;
delete [] fix[ifix]->style;
n = strlen(arg[2]) + 1;
fix[ifix]->style = new char[n];
strcpy(fix[ifix]->style,arg[2]);
// invoke add_fix
// it will find and overwrite the replaceID fix
add_fix(narg,arg,trysuffix);
}
/* ----------------------------------------------------------------------
one instance per fix in style_fix.h
------------------------------------------------------------------------- */

View File

@ -96,6 +96,7 @@ class Modify : protected Pointers {
virtual int min_reset_ref();
void add_fix(int, char **, int trysuffix=1);
void replace_fix(const char *, int, char **, int trysuffix=1);
void modify_fix(int, char **);
void delete_fix(const char *);
void delete_fix(int);