1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Naveen Michaud-Agrawal (Johns Hopkins U)
Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_spring_rg.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "respa.h"
#include "domain.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixSpringRG::FixSpringRG(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 5) error->all(FLERR,"Illegal fix spring/rg command");
k = atof(arg[3]);
rg0_flag = 0;
if (strcmp(arg[4],"NULL") == 0) rg0_flag = 1;
else rg0 = atof(arg[4]);
}
/* ---------------------------------------------------------------------- */
int FixSpringRG::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::init()
{
masstotal = group->mass(igroup);
// if rg0 was specified as NULL, compute current Rg
// only occurs on 1st run
if (rg0_flag) {
double xcm[3];
group->xcm(igroup,masstotal,xcm);
rg0 = group->gyration(igroup,masstotal,xcm);
rg0_flag = 0;
}
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
post_force(vflag);
else {
((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
post_force_respa(vflag,nlevels_respa-1,0);
((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
}
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::post_force(int vflag)
{
// compute current Rg and center-of-mass
double xcm[3];
group->xcm(igroup,masstotal,xcm);
double rg = group->gyration(igroup,masstotal,xcm);
// apply restoring force to atoms in group
// f = -k*(r-r0)*mass/masstotal
double dx,dy,dz,term1;
double **f = atom->f;
double **x = atom->x;
int *mask = atom->mask;
int *type = atom->type;
int *image = atom->image;
double *mass = atom->mass;
int nlocal = atom->nlocal;
double massfrac;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
term1 = 2.0 * k * (1.0 - rg0/rg);
xbox = (image[i] & 1023) - 512;
ybox = (image[i] >> 10 & 1023) - 512;
zbox = (image[i] >> 20) - 512;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
massfrac = mass[type[i]]/masstotal;
f[i][0] -= term1*dx*massfrac;
f[i][1] -= term1*dy*massfrac;
f[i][2] -= term1*dz*massfrac;
}
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
|