Added two modes, one via velocity and one via quaternion.
This commit is contained in:
committed by
Pierre de Buyl
parent
7076e9fe72
commit
8c7890b6df
@ -51,24 +51,34 @@ static constexpr const bool debug_out = false;
|
|||||||
FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv )
|
FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv )
|
||||||
: Fix(lmp, narg, argv)
|
: Fix(lmp, narg, argv)
|
||||||
{
|
{
|
||||||
// if( lmp->citeme) lmp->citeme->add(cite_fix_active);
|
if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command");
|
||||||
if( narg < 4 ) error->all(FLERR, "Illegal fix propel/self command");
|
|
||||||
|
|
||||||
AtomVecEllipsoid *av = static_cast<AtomVecEllipsoid*>(atom->avec);
|
|
||||||
if (!av) error->all(FLERR, "FixPropelSelf requires atom_style ellipsoid");
|
|
||||||
|
|
||||||
if( debug_out && comm->me == 0 ){
|
// The fix is to support the following cases:
|
||||||
fprintf(screen, "This is fix active, narg is %d\n", narg );
|
// 1. Simple atoms, in which case the force points along the velocity
|
||||||
fprintf(screen, "args:");
|
// 2. Cases where the atoms have an internal ellipsoid. Currently those
|
||||||
for( int i = 0; i < narg; ++i ){
|
// styles are only body and aspherical particles.
|
||||||
fprintf(screen, " %s", argv[i]);
|
// The first argument (mode) is used to differentiate between these.
|
||||||
|
|
||||||
|
// args: fix ID all propel/self mode magnitude
|
||||||
|
// Optional args are
|
||||||
|
const char *mode_str = argv[3];
|
||||||
|
if (strncmp(mode_str, "velocity", 8) == 0) {
|
||||||
|
mode = VELOCITY;
|
||||||
|
} else if (strncmp(mode_str, "quaternion", 10) == 0) {
|
||||||
|
// This mode should only be supported if the atom style has
|
||||||
|
// a quaternion (and if all atoms in the group have it)
|
||||||
|
if (verify_atoms_have_quaternion()) {
|
||||||
|
error->all(FLERR, "All atoms need a quaternion");
|
||||||
}
|
}
|
||||||
fprintf(screen, "\n");
|
mode = QUATERNION;
|
||||||
|
} else {
|
||||||
|
char msg[2048];
|
||||||
|
sprintf(msg, "Illegal mode \"%s\" for fix propel/self", mode_str);
|
||||||
|
error->all(FLERR, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// args: fix ID all propel/self magnitude prop1 prop2 prop3
|
|
||||||
// Optional args are
|
magnitude = force->numeric( FLERR, argv[4] );
|
||||||
magnitude = force->numeric( FLERR, argv[3] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,17 +102,29 @@ double FixPropelSelf::memory_usage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FixPropelSelf::post_force(int vflag )
|
||||||
void FixPropelSelf::post_force(int /* vflag */ )
|
|
||||||
{
|
{
|
||||||
// Then do the rest:
|
switch(mode) {
|
||||||
double **f = atom->f;
|
case QUATERNION:
|
||||||
|
post_force_quaternion(vflag);
|
||||||
|
break;
|
||||||
|
case VELOCITY:
|
||||||
|
post_force_velocity(vflag);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error->all(FLERR, "reached statement that should be unreachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FixPropelSelf::post_force_quaternion(int /* vflag */ )
|
||||||
|
{
|
||||||
|
double **f = atom->f;
|
||||||
AtomVecEllipsoid *av = static_cast<AtomVecEllipsoid*>(atom->avec);
|
AtomVecEllipsoid *av = static_cast<AtomVecEllipsoid*>(atom->avec);
|
||||||
|
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
|
|
||||||
|
|
||||||
AtomVecEllipsoid::Bonus *bonus = av->bonus;
|
AtomVecEllipsoid::Bonus *bonus = av->bonus;
|
||||||
// Add the active force to the atom force:
|
// Add the active force to the atom force:
|
||||||
@ -141,7 +163,71 @@ void FixPropelSelf::post_force(int /* vflag */ )
|
|||||||
f[i][0] += magnitude * f_rot[0];
|
f[i][0] += magnitude * f_rot[0];
|
||||||
f[i][1] += magnitude * f_rot[1];
|
f[i][1] += magnitude * f_rot[1];
|
||||||
f[i][2] += magnitude * f_rot[2];
|
f[i][2] += magnitude * f_rot[2];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FixPropelSelf::post_force_velocity(int /*vflag*/ )
|
||||||
|
{
|
||||||
|
double **f = atom->f;
|
||||||
|
double **v = atom->v;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
tagint *tag = atom->tag;
|
||||||
|
|
||||||
|
// Add the active force to the atom force:
|
||||||
|
for( int i = 0; i < nlocal; ++i ){
|
||||||
|
if( mask[i] & groupbit ){
|
||||||
|
const double *vi = v[i];
|
||||||
|
double f_act[3] = { vi[0], vi[1], vi[2] };
|
||||||
|
double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2];
|
||||||
|
double fnorm = magnitude / sqrt(nv2);
|
||||||
|
|
||||||
|
if (debug_out && comm->me == 0) {
|
||||||
|
// Magical reference particle:
|
||||||
|
if (tag[i] == 12) {
|
||||||
|
fprintf(screen, "Active force on atom %d: (%f %f %f)\n",
|
||||||
|
tag[i], f_act[0], f_act[1], f_act[2]);
|
||||||
|
fprintf(screen, " Total force before: (%f %f %f)\n",
|
||||||
|
f[i][0], f[i][1], f[i][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f[i][0] += fnorm * f_act[0];
|
||||||
|
f[i][1] += fnorm * f_act[1];
|
||||||
|
f[i][2] += fnorm * f_act[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FixPropelSelf::verify_atoms_have_quaternion()
|
||||||
|
{
|
||||||
|
int ellipsoid_flag = atom->ellipsoid_flag;
|
||||||
|
int body_flag = atom->body_flag;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
if (! (ellipsoid_flag || body_flag) ){
|
||||||
|
error->all(FLERR, "mode quaternion requires body or ellipsoid atoms");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure all atoms have ellipsoid or body set:
|
||||||
|
for (int i = 0; i < atom->nlocal; ++i) {
|
||||||
|
if (mask[i] & groupbit) {
|
||||||
|
if (ellipsoid_flag && atom->ellipsoid[i] < 0) {
|
||||||
|
error->all(FLERR, "Got atom without ellipsoid set");
|
||||||
|
// Kind-of pointless but silences some compiler warnings:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (body_flag && atom->body[i] < 0) {
|
||||||
|
error->all(FLERR, "Got atom without body set");
|
||||||
|
// Kind-of pointless but silences some compiler warnings:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,12 @@ namespace LAMMPS_NS {
|
|||||||
|
|
||||||
class FixPropelSelf : public Fix {
|
class FixPropelSelf : public Fix {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum operation_modes {
|
||||||
|
VELOCITY = 0,
|
||||||
|
QUATERNION = 1
|
||||||
|
};
|
||||||
|
|
||||||
FixPropelSelf(class LAMMPS *, int, char **);
|
FixPropelSelf(class LAMMPS *, int, char **);
|
||||||
virtual ~FixPropelSelf();
|
virtual ~FixPropelSelf();
|
||||||
virtual int setmask();
|
virtual int setmask();
|
||||||
@ -34,9 +40,16 @@ class FixPropelSelf : public Fix {
|
|||||||
|
|
||||||
double memory_usage();
|
double memory_usage();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
double magnitude;
|
double magnitude;
|
||||||
int thermostat_orient;
|
int thermostat_orient;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
int verify_atoms_have_quaternion();
|
||||||
|
void post_force_velocity(int);
|
||||||
|
void post_force_quaternion(int);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user