git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7513 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2012-01-10 20:01:18 +00:00
parent 9a9ed90766
commit 8c3a07c169
5 changed files with 366 additions and 0 deletions

View File

@ -4,6 +4,7 @@ if (test $1 = 1) then
cp angle_cosine_shift.cpp ..
cp angle_cosine_shift_exp.cpp ..
cp angle_dipole.cpp ..
cp bond_harmonic_shift.cpp ..
cp bond_harmonic_shift_cut.cpp ..
cp compute_ackland_atom.cpp ..
@ -21,6 +22,7 @@ if (test $1 = 1) then
cp angle_cosine_shift.h ..
cp angle_cosine_shift_exp.h ..
cp angle_dipole.h ..
cp bond_harmonic_shift.h ..
cp bond_harmonic_shift_cut.h ..
cp compute_ackland_atom.h ..
@ -40,6 +42,7 @@ elif (test $1 = 0) then
rm -f ../angle_cosine_shift.cpp
rm -f ../angle_cosine_shift_exp.cpp
rm -f ../angle_dipole.cpp
rm -f ../bond_harmonic_shift.cpp
rm -f ../bond_harmonic_shift_cut.cpp
rm -f ../compute_ackland_atom.cpp
@ -57,6 +60,7 @@ elif (test $1 = 0) then
rm -f ../angle_cosine_shift.h
rm -f ../angle_cosine_shift_exp.h
rm -f ../angle_dipole.h
rm -f ../bond_harmonic_shift.h
rm -f ../bond_harmonic_shift_cut.h
rm -f ../compute_ackland_atom.h

View File

@ -20,6 +20,7 @@ about the feature or its coding.
angle_style cosine/shift, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
angle_style cosine/shift/exp, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
angle_style dipole, Mario Orsi, orsimario at gmail.com, 10 Jan 12
bond_style harmonic/shift, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
bond_style harmonic/shift/cut, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
compute ackland/atom, Gerolf Ziegenhain, gerolf at ziegenhain.com, 4 Oct 2007

View File

@ -0,0 +1,207 @@
/* ----------------------------------------------------------------------
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: Mario Orsi (U Southampton), orsimario@gmail.com
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_dipole.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
AngleDipole::AngleDipole(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleDipole::~AngleDipole()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(gamma0);
}
}
/* ---------------------------------------------------------------------- */
void AngleDipole::compute(int eflag, int vflag)
{
int iRef,iDip,iDummy,n,type;
double delx,dely,delz;
double eangle,tangle,f1[3],f3[3];
double r,dr,cosGamma,deltaGamma,kdg,rmu;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; // position vector
double **mu = atom->mu; // point-dipole components and moment magnitude
double **torque = atom->torque;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
if (!newton_bond)
error->all(FLERR,"'newton' flag for bonded interactions must be 'on'");
for (n = 0; n < nanglelist; n++) {
iDip = anglelist[n][0]; // dipole whose orientation is to be restrained
iRef = anglelist[n][1]; // reference atom toward which dipole will point
iDummy = anglelist[n][2]; // dummy atom - irrelevant to the interaction
type = anglelist[n][3];
delx = x[iRef][0] - x[iDip][0];
dely = x[iRef][1] - x[iDip][1];
delz = x[iRef][2] - x[iDip][2];
domain->minimum_image(delx,dely,delz);
r = sqrt(delx*delx + dely*dely + delz*delz);
rmu = r * mu[iDip][3];
cosGamma = (mu[iDip][0]*delx+mu[iDip][1]*dely+mu[iDip][2]*delz) / rmu;
deltaGamma = cosGamma - cos(gamma0[type]);
kdg = k[type] * deltaGamma;
if (eflag) eangle = kdg * deltaGamma; // energy
tangle = 2.0 * kdg / rmu;
torque[iDip][0] += tangle * (dely*mu[iDip][2] - delz*mu[iDip][1]);
torque[iDip][1] += tangle * (delz*mu[iDip][0] - delx*mu[iDip][2]);
torque[iDip][2] += tangle * (delx*mu[iDip][1] - dely*mu[iDip][0]);
f1[0] = f1[1] = f1[2] = f3[0] = f3[1] = f3[2] = 0.0;
if (evflag) // tally energy (virial=0 because force=0)
ev_tally(iRef,iDip,iDummy,nlocal,newton_bond,eangle,f1,f3,
0.0,0.0,0.0,0.0,0.0,0.0);
}
}
/* ---------------------------------------------------------------------- */
void AngleDipole::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(gamma0,n+1,"angle:gamma0");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleDipole::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double gamma0_one = force->numeric(arg[2]);
// convert gamma0 from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
gamma0[i] = gamma0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ----------------------------------------------------------------------
used by SHAKE
------------------------------------------------------------------------- */
double AngleDipole::equilibrium_angle(int i)
{
return gamma0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleDipole::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&gamma0[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleDipole::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&gamma0[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&gamma0[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
used by ComputeAngleLocal
------------------------------------------------------------------------- */
double AngleDipole::single(int type, int iRef, int iDip, int iDummy)
{
double **x = atom->x; // position vector
double **mu = atom->mu; // point-dipole components and moment magnitude
double delx = x[iRef][0] - x[iDip][0];
double dely = x[iRef][1] - x[iDip][1];
double delz = x[iRef][2] - x[iDip][2];
domain->minimum_image(delx,dely,delz);
double r = sqrt(delx*delx + dely*dely + delz*delz);
double rmu = r * mu[iDip][3];
double cosGamma = (mu[iDip][0]*delx+mu[iDip][1]*dely+mu[iDip][2]*delz) / rmu;
double deltaGamma = cosGamma - cos(gamma0[type]);
double kdg = k[type] * deltaGamma;
return kdg * deltaGamma; // energy
}

View File

@ -0,0 +1,56 @@
/* ----------------------------------------------------------------------
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 ANGLE_CLASS
AngleStyle(dipole,AngleDipole)
#else
#ifndef LMP_ANGLE_DIPOLE_H
#define LMP_ANGLE_DIPOLE_H
#include "stdio.h"
#include "angle.h"
namespace LAMMPS_NS {
class AngleDipole : public Angle {
public:
AngleDipole(class LAMMPS *);
virtual ~AngleDipole();
virtual void compute(int, int);
void coeff(int, char **);
double equilibrium_angle(int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, int, int, int);
protected:
double *k,*gamma0;
void allocate();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Incorrect args for angle coefficients
Self-explanatory. Check the input script or data file.
*/

View File

@ -0,0 +1,98 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
angle_style dipole command :h3
[Syntax:]
angle_style dipole :pre
[Examples:]
angle_style dipole
angle_coeff 6 2.1 180.0 :pre
[Description:]
The {dipole} angle style is used to control the orientation of a dipolar
atom within a molecule "(Orsi)"_#Orsi. Specifically, the {dipole} angle
style restrains the orientation of a point dipole mu_j (embedded in atom
'j') with respect to a reference (bond) vector r_ij = r_i - r_j, where 'i'
is another atom of the same molecule (typically, 'i' and 'j' are also
covalently bonded).
It is convenient to define an angle gamma between the 'free' vector mu_j
and the reference (bond) vector r_ij:
:c,image(Eqs/angle_dipole_gamma.jpg)
The {dipole} angle style uses the potential:
:c,image(Eqs/angle_dipole_potential.jpg)
where K is a rigidity constant and gamma0 is an equilibrium (reference)
angle.
The torque on the dipole can be obtained by differentiating the
potential using the 'chain rule' as in appendix C.3 of
"(Allen)"_#Allen:
:c,image(Eqs/angle_dipole_torque.jpg)
Example: if gamma0 is set to 0 degrees, the torque generated by
the potential will tend to align the dipole along the reference
direction defined by the (bond) vector r_ij (in other words, mu_j is
restrained to point towards atom 'i').
Note that the angle dipole potential does not give rise to any force,
because it does not depend on the distance between i and j (it only
depends on the angle between mu_j and r_ij).
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy)
gamma0 (degrees) :ul
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
"user-misc" package. See the "Making LAMMPS"_Section_start.html#2_3
section for more info on packages.
IMPORTANT: In the "Angles" section of the data file, the atom id 'j'
corresponding to the dipole to restrain must come before the atom id
of the reference atom 'i'. A third atom id 'k' must also be provided,
although 'k' is just a 'dummy' atom which can be any atom; it may be
useful to choose a convention (e.g., 'k'='i') and adhere to it. For
example, if id=1 for the dipolar atom to restrain, and id=2 for the
reference atom, the corresponding line in the "Angles" section of the
data file would read: X X 1 2 2
The "newton" command for intramolecular interactions must be "on"
(which is the default).
This angle style should not be used with SHAKE.
[Related commands:]
"angle_coeff"_angle_coeff.html, "angle_hybrid"_angle_hybrid.html
[Default:] none
:line
:link(Orsi)
[(Orsi)] Orsi & Essex, The ELBA force field for coarse-grain modeling of
lipid membranes, PloS ONE 6(12): e28637, 2011.
:link(Allen)
[(Allen)] Allen & Tildesley, Computer Simulation of Liquids,
Clarendon Press, Oxford, 1987.