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

This commit is contained in:
sjplimp
2007-06-20 13:32:19 +00:00
parent 47d2408d13
commit 1164816776
36 changed files with 4150 additions and 815 deletions

300
src/ASPHERE/fix_npt_asphere.cpp Executable file
View File

@ -0,0 +1,300 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_npt_asphere.h"
#include "math_extra.h"
#include "atom.h"
#include "force.h"
#include "compute.h"
#include "kspace.h"
#include "update.h"
#include "domain.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
FixNPTASphere::FixNPTASphere(LAMMPS *lmp, int narg, char **arg) :
FixNPT(lmp, narg, arg)
{
if (atom->quat == NULL || atom->angmom == NULL || atom->torque == NULL)
error->all("Fix npt/asphere requires atom attributes "
"quat, angmom, torque");
}
/* ---------------------------------------------------------------------- */
void FixNPTASphere::init()
{
FixNPT::init();
dtq = 0.5 * update->dt;
}
/* ----------------------------------------------------------------------
1st half of Verlet update
------------------------------------------------------------------------- */
void FixNPTASphere::initial_integrate()
{
int i;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
// update eta_dot
t_target = t_start + delta * (t_stop-t_start);
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
eta += dtv*eta_dot;
// update omega_dot
// for non-varying dims, p_freq is 0.0, so omega_dot doesn't change
double f_omega;
double denskt = (atom->natoms*boltz*t_target) /
(domain->xprd*domain->yprd*domain->zprd) * nktv2p;
for (i = 0; i < 3; i++) {
p_target[i] = p_start[i] + delta * (p_stop[i]-p_start[i]);
f_omega = p_freq[i]*p_freq[i] * (p_current[i]-p_target[i])/denskt;
omega_dot[i] += f_omega*dthalf;
omega_dot[i] *= drag_factor;
omega[i] += dtv*omega_dot[i];
factor[i] = exp(-dthalf*(eta_dot+omega_dot[i]));
dilation[i] = exp(dthalf*omega_dot[i]);
}
ang_factor = exp(-dthalf*eta_dot);
// v update only for atoms in NPT group
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **quat = atom->quat;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double dtfm;
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] = v[i][0]*factor[0] + dtfm*f[i][0];
v[i][1] = v[i][1]*factor[1] + dtfm*f[i][1];
v[i][2] = v[i][2]*factor[2] + dtfm*f[i][2];
}
}
// rescale simulation box and all owned atoms by 1/2 step
box_dilate(0);
// x update by full step only for atoms in NPT group
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
}
}
// update angular momentum by 1/2 step
// update quaternion a full step via Richardson iteration
// returns new normalized quaternion
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
angmom[i][0] = angmom[i][0] * ang_factor + dtf * torque[i][0];
angmom[i][1] = angmom[i][1] * ang_factor + dtf * torque[i][1];
angmom[i][2] = angmom[i][2] * ang_factor + dtf * torque[i][2];
double inertia[3];
calculate_inertia(atom->mass[type[i]],atom->shape[type[i]],inertia);
richardson(quat[i],angmom[i],inertia);
}
}
// rescale simulation box and all owned atoms by 1/2 step
// redo KSpace coeffs since volume has changed
box_dilate(0);
if (kspace_flag) force->kspace->setup();
}
/* ----------------------------------------------------------------------
2nd half of Verlet update
------------------------------------------------------------------------- */
void FixNPTASphere::final_integrate()
{
int i;
// v update only for atoms in NPT group
double **v = atom->v;
double **f = atom->f;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double dtfm;
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] = (v[i][0] + dtfm*f[i][0]) * factor[0];
v[i][1] = (v[i][1] + dtfm*f[i][1]) * factor[1];
v[i][2] = (v[i][2] + dtfm*f[i][2]) * factor[2];
angmom[i][0] = (angmom[i][0] + dtf * torque[i][0]) * ang_factor;
angmom[i][1] = (angmom[i][1] + dtf * torque[i][1]) * ang_factor;
angmom[i][2] = (angmom[i][2] + dtf * torque[i][2]) * ang_factor;
}
}
// compute new T,P
t_current = temperature->compute_scalar();
if (press_couple == 0) {
if (ptemperature) double ptmp = ptemperature->compute_scalar();
double tmp = pressure->compute_scalar();
} else {
temperature->compute_vector();
if (ptemperature) ptemperature->compute_vector();
pressure->compute_vector();
}
couple();
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
// update omega_dot
// for non-varying dims, p_freq is 0.0, so omega_dot doesn't change
double f_omega;
double denskt = (atom->natoms*boltz*t_target) /
(domain->xprd*domain->yprd*domain->zprd) * nktv2p;
for (i = 0; i < 3; i++) {
f_omega = p_freq[i]*p_freq[i] * (p_current[i]-p_target[i])/denskt;
omega_dot[i] += f_omega*dthalf;
omega_dot[i] *= drag_factor;
}
}
/* ----------------------------------------------------------------------
Richardson iteration to update quaternion accurately
------------------------------------------------------------------------- */
void FixNPTASphere::richardson(double *q, double *m, double *moments)
{
// compute omega at 1/2 step from m at 1/2 step and q at 0
double w[3];
omega_from_mq(q,m,moments,w);
// full update from dq/dt = 1/2 w q
double wq[4];
MathExtra::multiply_vec_quat(w,q,wq);
double qfull[4];
qfull[0] = q[0] + dtq * wq[0];
qfull[1] = q[1] + dtq * wq[1];
qfull[2] = q[2] + dtq * wq[2];
qfull[3] = q[3] + dtq * wq[3];
MathExtra::normalize4(qfull);
// 1st half of update from dq/dt = 1/2 w q
double qhalf[4];
qhalf[0] = q[0] + 0.5*dtq * wq[0];
qhalf[1] = q[1] + 0.5*dtq * wq[1];
qhalf[2] = q[2] + 0.5*dtq * wq[2];
qhalf[3] = q[3] + 0.5*dtq * wq[3];
MathExtra::normalize4(qhalf);
// re-compute omega at 1/2 step from m at 1/2 step and q at 1/2 step
// recompute wq
omega_from_mq(qhalf,m,moments,w);
MathExtra::multiply_vec_quat(w,qhalf,wq);
// 2nd half of update from dq/dt = 1/2 w q
qhalf[0] += 0.5*dtq * wq[0];
qhalf[1] += 0.5*dtq * wq[1];
qhalf[2] += 0.5*dtq * wq[2];
qhalf[3] += 0.5*dtq * wq[3];
MathExtra::normalize4(qhalf);
// corrected Richardson update
q[0] = 2.0*qhalf[0] - qfull[0];
q[1] = 2.0*qhalf[1] - qfull[1];
q[2] = 2.0*qhalf[2] - qfull[2];
q[3] = 2.0*qhalf[3] - qfull[3];
MathExtra::normalize4(q);
}
/* ----------------------------------------------------------------------
compute omega from angular momentum
w = omega = angular velocity in space frame
wbody = angular velocity in body frame
project space-frame angular momentum onto body axes
and divide by principal moments
------------------------------------------------------------------------- */
void FixNPTASphere::omega_from_mq(double *q, double *m, double *inertia,
double *w)
{
double rot[3][3];
MathExtra::quat_to_mat(q,rot);
double wbody[3];
MathExtra::transpose_times_column3(rot,m,wbody);
wbody[0] /= inertia[0];
wbody[1] /= inertia[1];
wbody[2] /= inertia[2];
MathExtra::times_column3(rot,wbody,w);
}
/* ----------------------------------------------------------------------
calculate the moment of inertia for an ellipsoid, from mass and radii
shape = x,y,z radii in body frame
------------------------------------------------------------------------- */
void FixNPTASphere::calculate_inertia(double mass, double *shape,
double *inertia)
{
inertia[0] = mass*(shape[1]*shape[1]+shape[2]*shape[2])/5.0;
inertia[1] = mass*(shape[0]*shape[0]+shape[2]*shape[2])/5.0;
inertia[2] = mass*(shape[0]*shape[0]+shape[1]*shape[1])/5.0;
}

View File

@ -11,29 +11,28 @@
See the README file in the top-level LAMMPS directory. See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#ifndef FIX_VOL_RESCALE_H #ifndef FIX_NPT_ASPHERE_H
#define FIX_VOL_RESCALE_H #define FIX_NPT_ASPHERE_H
#include "fix.h" #include "fix_npt.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class FixVolRescale : public Fix { class FixNPTASphere : public FixNPT {
public: public:
FixVolRescale(class LAMMPS *, int, char **); FixNPTASphere(class LAMMPS *, int, char **);
~FixVolRescale(); ~FixNPTASphere() {}
int setmask();
void init(); void init();
void end_of_step(); void initial_integrate();
void final_integrate();
private: private:
int xflag,yflag,zflag; double dtq;
double xlo_start,xlo_stop,xhi_start,xhi_stop; double ang_factor;
double ylo_start,ylo_stop,yhi_start,yhi_stop;
double zlo_start,zlo_stop,zhi_start,zhi_stop; void richardson(double *, double *, double *);
int kspace_flag; // 1 if KSpace invoked, 0 if not void omega_from_mq(double *, double *, double *, double *);
int nrigid; // number of rigid fixes void calculate_inertia(double mass, double *shape, double *inertia);
int *rfix; // indices of rigid fixes
}; };
} }

237
src/ASPHERE/fix_nvt_asphere.cpp Executable file
View File

@ -0,0 +1,237 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_nvt_asphere.h"
#include "math_extra.h"
#include "atom.h"
#include "force.h"
#include "comm.h"
#include "group.h"
#include "update.h"
#include "modify.h"
#include "compute.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
FixNVTASphere::FixNVTASphere(LAMMPS *lmp, int narg, char **arg) :
FixNVT(lmp, narg, arg)
{
if (atom->quat == NULL || atom->angmom == NULL || atom->torque == NULL)
error->all("Fix nvt/asphere requires atom attributes "
"quat, angmom, torque");
}
/* ---------------------------------------------------------------------- */
void FixNVTASphere::init()
{
FixNVT::init();
dtq = 0.5 * update->dt;
}
/* ---------------------------------------------------------------------- */
void FixNVTASphere::initial_integrate()
{
double dtfm;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
t_target = t_start + delta * (t_stop-t_start);
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
eta += dtv*eta_dot;
factor = exp(-dthalf*eta_dot);
// update v and x of only atoms in NVT group
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **quat = atom->quat;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] = v[i][0]*factor + dtfm*f[i][0];
v[i][1] = v[i][1]*factor + dtfm*f[i][1];
v[i][2] = v[i][2]*factor + dtfm*f[i][2];
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
// update angular momentum by 1/2 step
// update quaternion a full step via Richardson iteration
// returns new normalized quaternion
angmom[i][0] = angmom[i][0] * factor + dtf * torque[i][0];
angmom[i][1] = angmom[i][1] * factor + dtf * torque[i][1];
angmom[i][2] = angmom[i][2] * factor + dtf * torque[i][2];
double inertia[3];
calculate_inertia(atom->mass[type[i]],atom->shape[type[i]],inertia);
richardson(quat[i],angmom[i],inertia);
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVTASphere::final_integrate()
{
double dtfm;
// update v of only atoms in NVT group
double **v = atom->v;
double **f = atom->f;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]] * factor;
v[i][0] = v[i][0]*factor + dtfm*f[i][0];
v[i][1] = v[i][1]*factor + dtfm*f[i][1];
v[i][2] = v[i][2]*factor + dtfm*f[i][2];
angmom[i][0] = angmom[i][0] * factor + dtf * torque[i][0];
angmom[i][1] = angmom[i][1] * factor + dtf * torque[i][1];
angmom[i][2] = angmom[i][2] * factor + dtf * torque[i][2];
}
}
// compute current T
t_current = temperature->compute_scalar();
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
}
/* ----------------------------------------------------------------------
Richardson iteration to update quaternion accurately
------------------------------------------------------------------------- */
void FixNVTASphere::richardson(double *q, double *m, double *moments)
{
// compute omega at 1/2 step from m at 1/2 step and q at 0
double w[3];
omega_from_mq(q,m,moments,w);
// full update from dq/dt = 1/2 w q
double wq[4];
MathExtra::multiply_vec_quat(w,q,wq);
double qfull[4];
qfull[0] = q[0] + dtq * wq[0];
qfull[1] = q[1] + dtq * wq[1];
qfull[2] = q[2] + dtq * wq[2];
qfull[3] = q[3] + dtq * wq[3];
MathExtra::normalize4(qfull);
// 1st half of update from dq/dt = 1/2 w q
double qhalf[4];
qhalf[0] = q[0] + 0.5*dtq * wq[0];
qhalf[1] = q[1] + 0.5*dtq * wq[1];
qhalf[2] = q[2] + 0.5*dtq * wq[2];
qhalf[3] = q[3] + 0.5*dtq * wq[3];
MathExtra::normalize4(qhalf);
// re-compute omega at 1/2 step from m at 1/2 step and q at 1/2 step
// recompute wq
omega_from_mq(qhalf,m,moments,w);
MathExtra::multiply_vec_quat(w,qhalf,wq);
// 2nd half of update from dq/dt = 1/2 w q
qhalf[0] += 0.5*dtq * wq[0];
qhalf[1] += 0.5*dtq * wq[1];
qhalf[2] += 0.5*dtq * wq[2];
qhalf[3] += 0.5*dtq * wq[3];
MathExtra::normalize4(qhalf);
// corrected Richardson update
q[0] = 2.0*qhalf[0] - qfull[0];
q[1] = 2.0*qhalf[1] - qfull[1];
q[2] = 2.0*qhalf[2] - qfull[2];
q[3] = 2.0*qhalf[3] - qfull[3];
MathExtra::normalize4(q);
}
/* ----------------------------------------------------------------------
compute omega from angular momentum
w = omega = angular velocity in space frame
wbody = angular velocity in body frame
project space-frame angular momentum onto body axes
and divide by principal moments
------------------------------------------------------------------------- */
void FixNVTASphere::omega_from_mq(double *q, double *m, double *inertia,
double *w)
{
double rot[3][3];
MathExtra::quat_to_mat(q,rot);
double wbody[3];
MathExtra::transpose_times_column3(rot,m,wbody);
wbody[0] /= inertia[0];
wbody[1] /= inertia[1];
wbody[2] /= inertia[2];
MathExtra::times_column3(rot,wbody,w);
}
/* ----------------------------------------------------------------------
calculate the moment of inertia for an ELLIPSOID, from mass and radii
shape = x,y,z radii in body frame
------------------------------------------------------------------------- */
void FixNVTASphere::calculate_inertia(double mass, double *shape,
double *inertia)
{
inertia[0] = mass*(shape[1]*shape[1]+shape[2]*shape[2])/5.0;
inertia[1] = mass*(shape[0]*shape[0]+shape[2]*shape[2])/5.0;
inertia[2] = mass*(shape[0]*shape[0]+shape[1]*shape[1])/5.0;
}

39
src/ASPHERE/fix_nvt_asphere.h Executable file
View File

@ -0,0 +1,39 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
#ifndef FIX_NVT_ASPHERE_H
#define FIX_NVT_ASPHERE_H
#include "fix_nvt.h"
namespace LAMMPS_NS {
class FixNVTASphere : public FixNVT {
public:
FixNVTASphere(class LAMMPS *, int, char **);
~FixNVTASphere() {}
void init();
void initial_integrate();
void final_integrate();
private:
double dtq;
void richardson(double *, double *, double *);
void omega_from_mq(double *, double *, double *, double *);
void calculate_inertia(double mass, double *shape, double *inertia);
};
}
#endif

32
src/DIPOLE/Install.csh Normal file
View File

@ -0,0 +1,32 @@
# Install/unInstall package classes in LAMMPS
if ($1 == 1) then
cp style_dipole.h ..
cp atom_vec_dipole.cpp ..
cp compute_temp_dipole.cpp ..
cp fix_nve_dipole.cpp ..
cp pair_dipole_cut.cpp ..
cp atom_vec_dipole.h ..
cp compute_temp_dipole.h ..
cp fix_nve_dipole.h ..
cp pair_dipole_cut.h ..
else if ($1 == 0) then
rm ../style_dipole.h
touch ../style_dipole.h
rm ../atom_vec_dipole.cpp
rm ../compute_temp_dipole.cpp
rm ../fix_nve_dipole.cpp
rm ../pair_dipole_cut.cpp
rm ../atom_vec_dipole.h
rm ../compute_temp_dipole.h
rm ../fix_nve_dipole.h
rm ../pair_dipole_cut.h
endif

View File

@ -0,0 +1,657 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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 "stdlib.h"
#include "atom_vec_dipole.h"
#include "atom.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 10000
/* ---------------------------------------------------------------------- */
AtomVecDipole::AtomVecDipole(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
mass_type = 1;
shape_type = 1;
dipole_type = 1;
comm_x_only = comm_f_only = 0;
size_comm = 6;
size_reverse = 6;
size_border = 10;
size_data_atom = 9;
size_data_vel = 7;
xcol_data = 4;
}
/* ----------------------------------------------------------------------
grow atom arrays
n = 0 grows arrays by DELTA
n > 0 allocates arrays to size n
------------------------------------------------------------------------- */
void AtomVecDipole::grow(int n)
{
if (n == 0) nmax += DELTA;
else nmax = n;
atom->nmax = nmax;
tag = atom->tag = (int *)
memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
type = atom->type = (int *)
memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
mask = atom->mask = (int *)
memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
image = atom->image = (int *)
memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
q = atom->q = (double *)
memory->srealloc(atom->q,nmax*sizeof(double),"atom:q");
mu = atom->mu =
memory->grow_2d_double_array(atom->mu,nmax,3,"atom:mu");
omega = atom->omega =
memory->grow_2d_double_array(atom->omega,nmax,3,"atom:omega");
torque = atom->torque =
memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
}
/* ---------------------------------------------------------------------- */
void AtomVecDipole::copy(int i, int j)
{
tag[j] = tag[i];
type[j] = type[i];
mask[j] = mask[i];
image[j] = image[i];
x[j][0] = x[i][0];
x[j][1] = x[i][1];
x[j][2] = x[i][2];
v[j][0] = v[i][0];
v[j][1] = v[i][1];
v[j][2] = v[i][2];
q[j] = q[i];
mu[j][0] = mu[i][0];
mu[j][1] = mu[i][1];
mu[j][2] = mu[i][2];
omega[j][0] = omega[i][0];
omega[j][1] = omega[i][1];
omega[j][2] = omega[i][2];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
m = 0;
if (pbc_flag == 0) {
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0];
buf[m++] = x[j][1];
buf[m++] = x[j][2];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
}
} else {
if (domain->triclinic == 0) {
dx = pbc[0]*domain->xprd;
dy = pbc[1]*domain->yprd;
dz = pbc[2]*domain->zprd;
} else {
dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
dz = pbc[2]*domain->zprd;
}
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0] + dx;
buf[m++] = x[j][1] + dy;
buf[m++] = x[j][2] + dz;
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_comm_one(int i, double *buf)
{
buf[0] = mu[i][0];
buf[1] = mu[i][1];
buf[2] = mu[i][2];
return 3;
}
/* ---------------------------------------------------------------------- */
void AtomVecDipole::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
x[i][0] = buf[m++];
x[i][1] = buf[m++];
x[i][2] = buf[m++];
mu[i][0] = buf[m++];
mu[i][1] = buf[m++];
mu[i][2] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_comm_one(int i, double *buf)
{
mu[i][0] = buf[0];
mu[i][1] = buf[1];
mu[i][2] = buf[2];
return 3;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_reverse(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = f[i][0];
buf[m++] = f[i][1];
buf[m++] = f[i][2];
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_reverse_one(int i, double *buf)
{
buf[0] = torque[i][0];
buf[1] = torque[i][1];
buf[2] = torque[i][2];
return 3;
}
/* ---------------------------------------------------------------------- */
void AtomVecDipole::unpack_reverse(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
f[j][0] += buf[m++];
f[j][1] += buf[m++];
f[j][2] += buf[m++];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_reverse_one(int i, double *buf)
{
torque[i][0] = buf[0];
torque[i][1] = buf[1];
torque[i][2] = buf[2];
return 3;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_border(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
m = 0;
if (pbc_flag == 0) {
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0];
buf[m++] = x[j][1];
buf[m++] = x[j][2];
buf[m++] = tag[j];
buf[m++] = type[j];
buf[m++] = mask[j];
buf[m++] = q[j];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
}
} else {
if (domain->triclinic == 0) {
dx = pbc[0]*domain->xprd;
dy = pbc[1]*domain->yprd;
dz = pbc[2]*domain->zprd;
} else {
dx = pbc[0];
dy = pbc[1];
dz = pbc[2];
}
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0] + dx;
buf[m++] = x[j][1] + dy;
buf[m++] = x[j][2] + dz;
buf[m++] = tag[j];
buf[m++] = type[j];
buf[m++] = mask[j];
buf[m++] = q[j];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_border_one(int i, double *buf)
{
buf[0] = q[i];
buf[1] = mu[i][0];
buf[2] = mu[i][1];
buf[3] = mu[i][2];
return 4;
}
/* ---------------------------------------------------------------------- */
void AtomVecDipole::unpack_border(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (i == nmax) grow(0);
x[i][0] = buf[m++];
x[i][1] = buf[m++];
x[i][2] = buf[m++];
tag[i] = static_cast<int> (buf[m++]);
type[i] = static_cast<int> (buf[m++]);
mask[i] = static_cast<int> (buf[m++]);
q[i] = buf[m++];
mu[i][0] = buf[m++];
mu[i][1] = buf[m++];
mu[i][2] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_border_one(int i, double *buf)
{
q[i] = buf[0];
mu[i][0] = buf[1];
mu[i][1] = buf[2];
mu[i][2] = buf[3];
return 4;
}
/* ----------------------------------------------------------------------
pack all atom quantities for shipping to another proc
xyz must be 1st 3 values, so that comm::exchange can test on them
------------------------------------------------------------------------- */
int AtomVecDipole::pack_exchange(int i, double *buf)
{
int m = 1;
buf[m++] = x[i][0];
buf[m++] = x[i][1];
buf[m++] = x[i][2];
buf[m++] = v[i][0];
buf[m++] = v[i][1];
buf[m++] = v[i][2];
buf[m++] = tag[i];
buf[m++] = type[i];
buf[m++] = mask[i];
buf[m++] = image[i];
buf[m++] = q[i];
buf[m++] = mu[i][0];
buf[m++] = mu[i][1];
buf[m++] = mu[i][2];
buf[m++] = omega[i][0];
buf[m++] = omega[i][1];
buf[m++] = omega[i][2];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
buf[0] = m;
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_exchange(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
int m = 1;
x[nlocal][0] = buf[m++];
x[nlocal][1] = buf[m++];
x[nlocal][2] = buf[m++];
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
tag[nlocal] = static_cast<int> (buf[m++]);
type[nlocal] = static_cast<int> (buf[m++]);
mask[nlocal] = static_cast<int> (buf[m++]);
image[nlocal] = static_cast<int> (buf[m++]);
q[nlocal] = buf[m++];
mu[nlocal][0] = buf[m++];
mu[nlocal][1] = buf[m++];
mu[nlocal][2] = buf[m++];
omega[nlocal][0] = buf[m++];
omega[nlocal][1] = buf[m++];
omega[nlocal][2] = buf[m++];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
m += modify->fix[atom->extra_grow[iextra]]->
unpack_exchange(nlocal,&buf[m]);
atom->nlocal++;
return m;
}
/* ----------------------------------------------------------------------
size of restart data for all atoms owned by this proc
include extra data stored by fixes
------------------------------------------------------------------------- */
int AtomVecDipole::size_restart()
{
int i;
int nlocal = atom->nlocal;
int n = 18 * nlocal;
if (atom->nextra_restart)
for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
for (i = 0; i < nlocal; i++)
n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
return n;
}
/* ----------------------------------------------------------------------
pack atom I's data for restart file including extra quantities
xyz must be 1st 3 values, so that read_restart can test on them
molecular types may be negative, but write as positive
------------------------------------------------------------------------- */
int AtomVecDipole::pack_restart(int i, double *buf)
{
int m = 1;
buf[m++] = x[i][0];
buf[m++] = x[i][1];
buf[m++] = x[i][2];
buf[m++] = tag[i];
buf[m++] = type[i];
buf[m++] = mask[i];
buf[m++] = image[i];
buf[m++] = v[i][0];
buf[m++] = v[i][1];
buf[m++] = v[i][2];
buf[m++] = q[i];
buf[m++] = mu[i][0];
buf[m++] = mu[i][1];
buf[m++] = mu[i][2];
buf[m++] = omega[i][0];
buf[m++] = omega[i][1];
buf[m++] = omega[i][2];
if (atom->nextra_restart)
for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
buf[0] = m;
return m;
}
/* ----------------------------------------------------------------------
unpack data for one atom from restart file including extra quantities
------------------------------------------------------------------------- */
int AtomVecDipole::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
atom->nextra_store,
"atom:extra");
}
int m = 1;
x[nlocal][0] = buf[m++];
x[nlocal][1] = buf[m++];
x[nlocal][2] = buf[m++];
tag[nlocal] = static_cast<int> (buf[m++]);
type[nlocal] = static_cast<int> (buf[m++]);
mask[nlocal] = static_cast<int> (buf[m++]);
image[nlocal] = static_cast<int> (buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
q[nlocal] = buf[m++];
mu[nlocal][0] = buf[m++];
mu[nlocal][1] = buf[m++];
mu[nlocal][2] = buf[m++];
omega[nlocal][0] = buf[m++];
omega[nlocal][1] = buf[m++];
omega[nlocal][2] = buf[m++];
double **extra = atom->extra;
if (atom->nextra_store) {
int size = static_cast<int> (buf[0]) - m;
for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
}
atom->nlocal++;
return m;
}
/* ----------------------------------------------------------------------
create one atom of itype at coord
set other values to defaults
------------------------------------------------------------------------- */
void AtomVecDipole::create_atom(int itype, double *coord)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = 0;
type[nlocal] = itype;
x[nlocal][0] = coord[0];
x[nlocal][1] = coord[1];
x[nlocal][2] = coord[2];
mask[nlocal] = 1;
image[nlocal] = (512 << 20) | (512 << 10) | 512;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
q[nlocal] = 0.0;
mu[nlocal][0] = 0.0;
mu[nlocal][1] = 0.0;
mu[nlocal][2] = 0.0;
omega[nlocal][0] = 0.0;
omega[nlocal][1] = 0.0;
omega[nlocal][2] = 0.0;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack one line from Atoms section of data file
initialize other atom quantities
------------------------------------------------------------------------- */
void AtomVecDipole::data_atom(double *coord, int imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one("Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one("Invalid atom type in Atoms section of data file");
q[nlocal] = atof(values[2]);
x[nlocal][0] = coord[0];
x[nlocal][1] = coord[1];
x[nlocal][2] = coord[2];
mu[nlocal][0] = atof(values[6]);
mu[nlocal][1] = atof(values[7]);
mu[nlocal][2] = atof(values[8]);
image[nlocal] = imagetmp;
mask[nlocal] = 1;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
omega[nlocal][0] = 0.0;
omega[nlocal][1] = 0.0;
omega[nlocal][2] = 0.0;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack hybrid quantities from one line in Atoms section of data file
initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */
int AtomVecDipole::data_atom_hybrid(int nlocal, char **values)
{
q[nlocal] = atof(values[0]);
mu[nlocal][0] = atof(values[1]);
mu[nlocal][1] = atof(values[2]);
mu[nlocal][2] = atof(values[3]);
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
omega[nlocal][0] = 0.0;
omega[nlocal][1] = 0.0;
omega[nlocal][2] = 0.0;
return 4;
}
/* ----------------------------------------------------------------------
unpack one line from Velocities section of data file
------------------------------------------------------------------------- */
void AtomVecDipole::data_vel(int m, char **values)
{
v[m][0] = atof(values[0]);
v[m][1] = atof(values[1]);
v[m][2] = atof(values[2]);
omega[m][0] = atof(values[3]);
omega[m][1] = atof(values[4]);
omega[m][2] = atof(values[5]);
}
/* ----------------------------------------------------------------------
unpack hybrid quantities from one line in Velocities section of data file
------------------------------------------------------------------------- */
int AtomVecDipole::data_vel_hybrid(int m, char **values)
{
omega[m][0] = atof(values[0]);
omega[m][1] = atof(values[1]);
omega[m][2] = atof(values[2]);
return 3;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
------------------------------------------------------------------------- */
int AtomVecDipole::memory_usage()
{
int bytes = 0;
if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
if (atom->memcheck("type")) bytes += nmax * sizeof(int);
if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
if (atom->memcheck("image")) bytes += nmax * sizeof(int);
if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
if (atom->memcheck("q")) bytes += nmax * sizeof(double);
if (atom->memcheck("mu")) bytes += nmax*3 * sizeof(double);
if (atom->memcheck("omega")) bytes += nmax*3 * sizeof(double);
if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,58 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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.
------------------------------------------------------------------------- */
#ifndef ATOM_VEC_DIPOLE_H
#define ATOM_VEC_DIPOLE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecDipole : public AtomVec {
public:
AtomVecDipole(class LAMMPS *, int, char **);
void grow(int);
void copy(int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_one(int, double *);
void unpack_comm(int, int, double *);
int unpack_comm_one(int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_one(int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_one(int, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_one(int, double *);
void unpack_border(int, int, double *);
int unpack_border_one(int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
void data_atom(double *, int, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
int memory_usage();
private:
int *tag,*type,*mask,*image;
double **x,**v,**f;
double *q,**mu,**omega,**torque;
};
}
#endif

View File

@ -0,0 +1,144 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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 "mpi.h"
#include "compute_temp_dipole.h"
#include "atom.h"
#include "force.h"
#include "group.h"
#include "modify.h"
#include "fix.h"
#include "error.h"
using namespace LAMMPS_NS;
// moment of inertia for a sphere
#define INERTIA 0.4
/* ---------------------------------------------------------------------- */
ComputeTempDipole::ComputeTempDipole(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all("Illegal compute temp/dipole command");
if (atom->omega == NULL || atom->shape == NULL)
error->all("Compute temp/dipole requires atom attributes omega, shape");
scalar_flag = vector_flag = 1;
size_vector = 6;
extensive = 0;
tempflag = 1;
vector = new double[6];
inertia = new double[atom->ntypes + 1];
}
/* ---------------------------------------------------------------------- */
ComputeTempDipole::~ComputeTempDipole()
{
delete [] vector;
delete [] inertia;
}
/* ---------------------------------------------------------------------- */
void ComputeTempDipole::init()
{
fix_dof = 0;
for (int i = 0; i < modify->nfix; i++)
fix_dof += modify->fix[i]->dof(igroup);
recount();
// moment of inertia for each particle type
double *mass = atom->mass;
double **shape = atom->shape;
for (int i = 1; i <= atom->ntypes; i++)
inertia[i] = INERTIA * mass[i] * 0.25*shape[i][0]*shape[i][0];
}
/* ---------------------------------------------------------------------- */
void ComputeTempDipole::recount()
{
double natoms = group->count(igroup);
dof = 2.0 * force->dimension * natoms;
dof -= extra_dof + fix_dof;
if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
else tfactor = 0.0;
}
/* ---------------------------------------------------------------------- */
double ComputeTempDipole::compute_scalar()
{
double **v = atom->v;
double *mass = atom->mass;
double **omega = atom->omega;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
// rotational and translational kinetic energy
double t = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
mass[type[i]]
+ (omega[i][0] * omega[i][0] + omega[i][1] * omega[i][1] +
omega[i][2] * omega[i][2]) * inertia[type[i]];
MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
if (dynamic) recount();
scalar *= tfactor;
return scalar;
}
/* ---------------------------------------------------------------------- */
void ComputeTempDipole::compute_vector()
{
int i;
double **v = atom->v;
double *mass = atom->mass;
double **omega = atom->omega;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double rmass,imass,t[6];
for (i = 0; i < 6; i++) t[i] = 0.0;
// rotational and translational kinetic energy
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
rmass = mass[type[i]];
imass = inertia[type[i]];
t[0] += rmass*v[i][0]*v[i][0] + imass*omega[i][0]*omega[i][0];
t[1] += rmass*v[i][1]*v[i][1] + imass*omega[i][1]*omega[i][1];
t[2] += rmass*v[i][2]*v[i][2] + imass*omega[i][2]*omega[i][2];
t[3] += rmass*v[i][0]*v[i][1] + imass*omega[i][0]*omega[i][1];
t[4] += rmass*v[i][0]*v[i][2] + imass*omega[i][0]*omega[i][2];
t[5] += rmass*v[i][1]*v[i][2] + imass*omega[i][1]*omega[i][2];
}
MPI_Allreduce(&t,&vector,6,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
}

View File

@ -0,0 +1,39 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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.
------------------------------------------------------------------------- */
#ifndef COMPUTE_TEMP_DIPOLE_H
#define COMPUTE_TEMP_DIPOLE_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeTempDipole : public Compute {
public:
ComputeTempDipole(class LAMMPS *, int, char **);
~ComputeTempDipole();
void init();
double compute_scalar();
void compute_vector();
private:
int fix_dof;
double tfactor;
double *inertia;
void recount();
};
}
#endif

View File

@ -0,0 +1,189 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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 "math.h"
#include "string.h"
#include "fix_nve_dipole.h"
#include "atom.h"
#include "force.h"
#include "update.h"
#include "respa.h"
#include "error.h"
using namespace LAMMPS_NS;
// moment of inertia for a sphere
#define INERTIA 0.4
/* ---------------------------------------------------------------------- */
FixNVEDipole::FixNVEDipole(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 3) error->all("Illegal fix nve/dipole command");
if (atom->mu == NULL || atom->omega == NULL ||
atom->torque == NULL || atom->shape == NULL)
error->all("Fix nve/dipole requires atom attributes "
"mu, omega, torque, shape");
inertia = new double[atom->ntypes+1];
}
/* ---------------------------------------------------------------------- */
FixNVEDipole::~FixNVEDipole()
{
delete [] inertia;
}
/* ---------------------------------------------------------------------- */
int FixNVEDipole::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixNVEDipole::init()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
if (strcmp(update->integrate_style,"respa") == 0)
step_respa = ((Respa *) update->integrate)->step;
// moment of inertia for each particle type
double *mass = atom->mass;
double **shape = atom->shape;
for (int i = 1; i <= atom->ntypes; i++)
inertia[i] = INERTIA * mass[i] * 0.25*shape[i][0]*shape[i][0];
}
/* ---------------------------------------------------------------------- */
void FixNVEDipole::initial_integrate()
{
double dtfm,msq,scale;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **mu = atom->mu;
double **omega = atom->omega;
double **torque = atom->torque;
double *mass = atom->mass;
double *dipole = atom->dipole;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double g[3],h[3];
// update v,x for all particles
// update omega,mu for all dipoles
// d_omega/dt = torque / inertia
// d_mu/dt = omega cross mu
// renormalize mu to dipole length
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
if (dipole[type[i]] > 0.0) {
dtfm = dtf / inertia[type[i]];
omega[i][0] += dtfm * torque[i][0];
omega[i][1] += dtfm * torque[i][1];
omega[i][2] += dtfm * torque[i][2];
g[0] = mu[i][0] + dtv * (omega[i][1]*mu[i][2] - omega[i][2]*mu[i][1]);
g[1] = mu[i][1] + dtv * (omega[i][2]*mu[i][0] - omega[i][0]*mu[i][2]);
g[2] = mu[i][2] + dtv * (omega[i][0]*mu[i][1] - omega[i][1]*mu[i][0]);
msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2];
scale = dipole[type[i]]/sqrt(msq);
mu[i][0] = g[0]*scale;
mu[i][1] = g[1]*scale;
mu[i][2] = g[2]*scale;
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVEDipole::final_integrate()
{
double dtfm;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double *mass = atom->mass;
double *dipole = atom->dipole;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
// update v for all particles
// update omega for all dipoles
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
if (dipole[type[i]] > 0.0) {
dtfm = dtf / inertia[type[i]];
omega[i][0] += dtfm * torque[i][0];
omega[i][1] += dtfm * torque[i][1];
omega[i][2] += dtfm * torque[i][2];
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVEDipole::initial_integrate_respa(int ilevel, int flag)
{
if (flag) return; // only used by NPT,NPH
dtv = step_respa[ilevel];
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
if (ilevel == 0) initial_integrate();
else final_integrate();
}
/* ---------------------------------------------------------------------- */
void FixNVEDipole::final_integrate_respa(int ilevel)
{
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
final_integrate();
}

View File

@ -0,0 +1,40 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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.
------------------------------------------------------------------------- */
#ifndef FIX_NVE_DIPOLE_H
#define FIX_NVE_DIPOLE_H
#include "fix.h"
namespace LAMMPS_NS {
class FixNVEDipole : public Fix {
public:
FixNVEDipole(class LAMMPS *, int, char **);
~FixNVEDipole();
int setmask();
void init();
void initial_integrate();
void final_integrate();
void initial_integrate_respa(int,int);
void final_integrate_respa(int);
private:
double dtv,dtf;
double *step_respa;
double *inertia;
};
}
#endif

View File

@ -0,0 +1,625 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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 "math.h"
#include "stdlib.h"
#include "pair_dipole_cut.h"
#include "atom.h"
#include "neighbor.h"
#include "comm.h"
#include "force.h"
#include "update.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* ---------------------------------------------------------------------- */
PairDipoleCut::PairDipoleCut(LAMMPS *lmp) : Pair(lmp) {}
/* ---------------------------------------------------------------------- */
PairDipoleCut::~PairDipoleCut()
{
if (allocated) {
memory->destroy_2d_int_array(setflag);
memory->destroy_2d_double_array(cutsq);
memory->destroy_2d_double_array(cut_lj);
memory->destroy_2d_double_array(cut_ljsq);
memory->destroy_2d_double_array(cut_coul);
memory->destroy_2d_double_array(cut_coulsq);
memory->destroy_2d_double_array(epsilon);
memory->destroy_2d_double_array(sigma);
memory->destroy_2d_double_array(lj1);
memory->destroy_2d_double_array(lj2);
memory->destroy_2d_double_array(lj3);
memory->destroy_2d_double_array(lj4);
memory->destroy_2d_double_array(offset);
}
}
/* ---------------------------------------------------------------------- */
void PairDipoleCut::compute(int eflag, int vflag)
{
int i,j,k,numneigh,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv;
double forcecoulx,forcecouly,forcecoulz,fforce,crossx,crossy,crossz;
double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
double fq,fx,fy,fz;
double pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double forcelj,factor_coul,factor_lj;
double factor,phicoul,philj;
int *neighs;
double **f;
eng_vdwl = eng_coul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (vflag == 2) f = update->f_pair;
else f = atom->f;
double **x = atom->x;
double *q = atom->q;
double **mu = atom->mu;
double **torque = atom->torque;
int *type = atom->type;
double *dipole = atom->dipole;
int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
double qqrd2e = force->qqrd2e;
// loop over neighbors of my atoms
for (i = 0; i < nlocal; i++) {
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
neighs = neighbor->firstneigh[i];
numneigh = neighbor->numneigh[i];
for (k = 0; k < numneigh; k++) {
j = neighs[k];
if (j < nall) factor_coul = factor_lj = 1.0;
else {
factor_coul = special_coul[j/nall];
factor_lj = special_lj[j/nall];
j = j % nall;
}
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
// atom can have both a charge and dipole
// i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
if (rsq < cut_coulsq[itype][jtype]) {
forcecoulx = forcecouly = forcecoulz = 0.0;
tixcoul = tiycoul = tizcoul = 0.0;
tjxcoul = tjycoul = tjzcoul = 0.0;
if (qtmp != 0.0 && q[j] != 0.0) {
r3inv = r2inv*rinv;
pre1 = qtmp*q[j]*r3inv;
forcecoulx += pre1*delx;
forcecouly += pre1*dely;
forcecoulz += pre1*delz;
}
if (dipole[itype] > 0.0 && dipole[jtype] > 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
r7inv = r5inv*r2inv;
pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*r5inv*pdotp - 15.0*r7inv*pidotr*pjdotr;
pre2 = 3.0*r5inv*pjdotr;
pre3 = 3.0*r5inv*pidotr;
pre4 = -1.0*r3inv;
forcecoulx += pre1*delx + pre2*mu[i][0] + pre3*mu[j][0];
forcecouly += pre1*dely + pre2*mu[i][1] + pre3*mu[j][1];
forcecoulz += pre1*delz + pre2*mu[i][2] + pre3*mu[j][2];
crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
}
if (dipole[itype] > 0.0 && q[j] != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pre1 = 3.0*q[j]*r5inv * pidotr;
pre2 = q[j]*r3inv;
forcecoulx += pre2*mu[i][0] - pre1*delx;
forcecouly += pre2*mu[i][1] - pre1*dely;
forcecoulz += pre2*mu[i][2] - pre1*delz;
tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
}
if (dipole[jtype] > 0.0 && qtmp != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*qtmp*r5inv * pjdotr;
pre2 = qtmp*r3inv;
forcecoulx += pre1*delx - pre2*mu[j][0];
forcecouly += pre1*dely - pre2*mu[j][1];
forcecoulz += pre1*delz - pre2*mu[j][2];
tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
}
}
// LJ interaction
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = factor_lj * forcelj*r2inv;
} else fforce = 0.0;
// total force
fq = factor_coul*qqrd2e;
fx = fq*forcecoulx + delx*fforce;
fy = fq*forcecouly + dely*fforce;
fz = fq*forcecoulz + delz*fforce;
// force & torque accumulation
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
torque[i][0] += fq*tixcoul;
torque[i][1] += fq*tiycoul;
torque[i][2] += fq*tizcoul;
if (newton_pair || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] += fq*tjxcoul;
torque[j][1] += fq*tjycoul;
torque[j][2] += fq*tjzcoul;
}
if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq[itype][jtype]) {
phicoul = qtmp*q[j]*rinv;
if (dipole[itype] > 0.0 && dipole[jtype] > 0.0)
phicoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr;
if (dipole[itype] > 0.0 && q[j] != 0.0)
phicoul += -q[j]*r3inv*pidotr;
if (dipole[jtype] > 0.0 && qtmp != 0.0)
phicoul += qtmp*r3inv*pjdotr;
eng_coul += factor*factor_coul*qqrd2e*phicoul;
}
if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj;
}
}
if (vflag == 1) {
if (newton_pair == 0 && j >= nlocal) {
fx *= 0.5; fy *= 0.5; fz *= 0.5;
}
virial[0] += delx*fx;
virial[1] += dely*fy;
virial[2] += delz*fz;
virial[3] += delx*fy;
virial[4] += delx*fz;
virial[5] += dely*fz;
}
}
}
}
if (vflag == 2) virial_compute();
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairDipoleCut::allocate()
{
allocated = 1;
int n = atom->ntypes;
setflag = memory->create_2d_int_array(n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
cutsq = memory->create_2d_double_array(n+1,n+1,"pair:cutsq");
cut_lj = memory->create_2d_double_array(n+1,n+1,"pair:cut_lj");
cut_ljsq = memory->create_2d_double_array(n+1,n+1,"pair:cut_ljsq");
cut_coul = memory->create_2d_double_array(n+1,n+1,"pair:cut_coul");
cut_coulsq = memory->create_2d_double_array(n+1,n+1,"pair:cut_coulsq");
epsilon = memory->create_2d_double_array(n+1,n+1,"pair:epsilon");
sigma = memory->create_2d_double_array(n+1,n+1,"pair:sigma");
lj1 = memory->create_2d_double_array(n+1,n+1,"pair:lj1");
lj2 = memory->create_2d_double_array(n+1,n+1,"pair:lj2");
lj3 = memory->create_2d_double_array(n+1,n+1,"pair:lj3");
lj4 = memory->create_2d_double_array(n+1,n+1,"pair:lj4");
offset = memory->create_2d_double_array(n+1,n+1,"pair:offset");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairDipoleCut::settings(int narg, char **arg)
{
if (narg < 1 || narg > 2)
error->all("Incorrect args in pair_style command");
cut_lj_global = atof(arg[0]);
if (narg == 1) cut_coul_global = cut_lj_global;
else cut_coul_global = atof(arg[1]);
// reset cutoffs that have been explicitly set
if (allocated) {
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i+1; j <= atom->ntypes; j++)
if (setflag[i][j]) {
cut_lj[i][j] = cut_lj_global;
cut_coul[i][j] = cut_coul_global;
}
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairDipoleCut::coeff(int narg, char **arg)
{
if (narg < 4 || narg > 6)
error->all("Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
double epsilon_one = atof(arg[2]);
double sigma_one = atof(arg[3]);
double cut_lj_one = cut_lj_global;
double cut_coul_one = cut_coul_global;
if (narg >= 5) cut_coul_one = cut_lj_one = atof(arg[4]);
if (narg == 6) cut_coul_one = atof(arg[5]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
epsilon[i][j] = epsilon_one;
sigma[i][j] = sigma_one;
cut_lj[i][j] = cut_lj_one;
cut_coul[i][j] = cut_coul_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all("Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairDipoleCut::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j],
sigma[i][i],sigma[j][j]);
sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]);
cut_lj[i][j] = mix_distance(cut_lj[i][i],cut_lj[j][j]);
cut_coul[i][j] = mix_distance(cut_coul[i][i],cut_coul[j][j]);
}
double cut = MAX(cut_lj[i][j],cut_coul[i][j]);
cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j];
cut_coulsq[i][j] = cut_coul[i][j] * cut_coul[i][j];
lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0);
lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0);
lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0);
lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0);
if (offset_flag) {
double ratio = sigma[i][j] / cut_lj[i][j];
offset[i][j] = 4.0 * epsilon[i][j] * (pow(ratio,12.0) - pow(ratio,6.0));
} else offset[i][j] = 0.0;
cut_ljsq[j][i] = cut_ljsq[i][j];
cut_coulsq[j][i] = cut_coulsq[i][j];
lj1[j][i] = lj1[i][j];
lj2[j][i] = lj2[i][j];
lj3[j][i] = lj3[i][j];
lj4[j][i] = lj4[i][j];
offset[j][i] = offset[i][j];
return cut;
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairDipoleCut::init_style()
{
if (atom->q == NULL || atom->mu == NULL ||
atom->torque == NULL || atom->dipole == NULL)
error->all("Pair dipole/cut requires atom attributes "
"q, mu, torque, dipole");
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairDipoleCut::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&epsilon[i][j],sizeof(double),1,fp);
fwrite(&sigma[i][j],sizeof(double),1,fp);
fwrite(&cut_lj[i][j],sizeof(double),1,fp);
fwrite(&cut_coul[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairDipoleCut::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&epsilon[i][j],sizeof(double),1,fp);
fread(&sigma[i][j],sizeof(double),1,fp);
fread(&cut_lj[i][j],sizeof(double),1,fp);
fread(&cut_coul[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut_lj[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut_coul[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairDipoleCut::write_restart_settings(FILE *fp)
{
fwrite(&cut_lj_global,sizeof(double),1,fp);
fwrite(&cut_coul_global,sizeof(double),1,fp);
fwrite(&offset_flag,sizeof(int),1,fp);
fwrite(&mix_flag,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairDipoleCut::read_restart_settings(FILE *fp)
{
if (comm->me == 0) {
fread(&cut_lj_global,sizeof(double),1,fp);
fread(&cut_coul_global,sizeof(double),1,fp);
fread(&offset_flag,sizeof(int),1,fp);
fread(&mix_flag,sizeof(int),1,fp);
}
MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut_coul_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
}
/* ---------------------------------------------------------------------- */
void PairDipoleCut::single(int i, int j, int itype, int jtype, double rsq,
double factor_coul, double factor_lj, int eflag,
One &one)
{
double rinv,r2inv,r6inv,r3inv,r5inv,r7inv;
double forcecoulx,forcecouly,forcecoulz,fforce,crossx,crossy,crossz;
double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
double pdotp,pdotr,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double fq,forcelj,phicoul,philj;
double delx = atom->x[i][0] - atom->x[j][0];
double dely = atom->x[i][1] - atom->x[j][1];
double delz = atom->x[i][2] - atom->x[j][2];
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
forcecoulx = forcecouly = forcecoulz = 0.0;
tixcoul = tiycoul = tizcoul = 0.0;
tjxcoul = tjycoul = tjzcoul = 0.0;
if (rsq < cut_coulsq[itype][jtype]) {
double **mu = atom->mu;
if (atom->q[i] != 0.0 && atom->q[j] != 0.0) {
r3inv = r2inv*rinv;
pre1 = atom->q[i]*atom->q[j]*r3inv;
forcecoulx += pre1*delx;
forcecouly += pre1*dely;
forcecoulz += pre1*delz;
}
if (atom->dipole[itype] > 0.0 && atom->dipole[jtype] > 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
r7inv = r5inv*r2inv;
pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*r5inv*pdotp - 15.0*r7inv*pidotr*pjdotr;
pre2 = 3.0*r5inv*pjdotr;
pre3 = 3.0*r5inv*pidotr;
pre4 = -1.0*r3inv;
forcecoulx += pre1*delx + pre2*mu[i][0] + pre3*mu[j][0];
forcecouly += pre1*dely + pre2*mu[i][1] + pre3*mu[j][1];
forcecoulz += pre1*delz + pre2*mu[i][2] + pre3*mu[j][2];
crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
} else if (atom->dipole[itype] > 0.0 && atom->q[j] != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pdotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pre1 = 3.0*atom->q[j]*r5inv * pdotr;
pre2 = atom->q[j]*r3inv;
forcecoulx += pre2*mu[i][0] - pre1*delx;
forcecouly += pre2*mu[i][1] - pre1*dely;
forcecoulz += pre2*mu[i][2] - pre1*delz;
tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
} else if (atom->dipole[jtype] > 0.0 && atom->q[i] != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*atom->q[i]*r5inv * pdotr;
pre2 = atom->q[i]*r3inv;
forcecoulx += pre1*delx - pre2*mu[j][0];
forcecouly += pre1*dely - pre2*mu[j][1];
forcecoulz += pre1*delz - pre2*mu[j][2];
tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
}
}
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = factor_lj * forcelj*r2inv;
} else fforce = 0.0;
fq = factor_coul*force->qqrd2e;
one.fx = fq*forcecoulx + delx*fforce;
one.fy = fq*forcecouly + dely*fforce;
one.fz = fq*forcecoulz + delz*fforce;
one.tix = fq*tixcoul;
one.tiy = fq*tiycoul;
one.tiz = fq*tizcoul;
one.tjx = fq*tjxcoul;
one.tjy = fq*tjycoul;
one.tjz = fq*tjzcoul;
if (eflag) {
if (rsq < cut_coulsq[itype][jtype]) {
phicoul = atom->q[i]*atom->q[j]*rinv;
if (atom->dipole[itype] > 0.0 && atom->dipole[jtype] > 0.0)
phicoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr;
else if (atom->dipole[itype] > 0.0 && atom->q[j] != 0.0)
phicoul += -pre2*pdotr;
else if (atom->dipole[jtype] > 0.0 && atom->q[i] != 0.0)
phicoul += pre2*pdotr;
one.eng_coul = factor_coul*force->qqrd2e*phicoul;
} else one.eng_coul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
one.eng_vdwl = factor_lj*philj;
} else one.eng_vdwl = 0.0;
}
}

View File

@ -0,0 +1,48 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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.
------------------------------------------------------------------------- */
#ifndef PAIR_DIPOLE_CUT_H
#define PAIR_DIPOLE_CUT_H
#include "pair.h"
namespace LAMMPS_NS {
class PairDipoleCut : public Pair {
public:
PairDipoleCut(class LAMMPS *);
~PairDipoleCut();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
void single(int, int, int, int, double, double, double, int, One &);
private:
double cut_lj_global,cut_coul_global;
double **cut_lj,**cut_ljsq;
double **cut_coul,**cut_coulsq;
double **epsilon,**sigma;
double **lj1,**lj2,**lj3,**lj4,**offset;
void allocate();
};
}
#endif

44
src/DIPOLE/style_dipole.h Normal file
View File

@ -0,0 +1,44 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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 AtomInclude
#include "atom_vec_dipole.h"
#endif
#ifdef AtomClass
AtomStyle(dipole,AtomVecDipole)
#endif
#ifdef ComputeInclude
#include "compute_temp_dipole.h"
#endif
#ifdef ComputeClass
ComputeStyle(temp/dipole,ComputeTempDipole)
#endif
#ifdef FixInclude
#include "fix_nve_dipole.h"
#endif
#ifdef FixClass
FixStyle(nve/dipole,FixNVEDipole)
#endif
#ifdef PairInclude
#include "pair_dipole_cut.h"
#endif
#ifdef PairClass
PairStyle(dipole/cut,PairDipoleCut)
#endif

View File

@ -4,14 +4,12 @@ if ($1 == 1) then
cp style_manybody.h .. cp style_manybody.h ..
cp pair_airebo.cpp ..
cp pair_eam.cpp .. cp pair_eam.cpp ..
cp pair_eam_alloy.cpp .. cp pair_eam_alloy.cpp ..
cp pair_eam_fs.cpp .. cp pair_eam_fs.cpp ..
cp pair_sw.cpp .. cp pair_sw.cpp ..
cp pair_tersoff.cpp .. cp pair_tersoff.cpp ..
cp pair_airebo.h ..
cp pair_eam.h .. cp pair_eam.h ..
cp pair_eam_alloy.h .. cp pair_eam_alloy.h ..
cp pair_eam_fs.h .. cp pair_eam_fs.h ..
@ -23,14 +21,12 @@ else if ($1 == 0) then
rm ../style_manybody.h rm ../style_manybody.h
touch ../style_manybody.h touch ../style_manybody.h
rm ../pair_airebo.cpp
rm ../pair_eam.cpp rm ../pair_eam.cpp
rm ../pair_eam_alloy.cpp rm ../pair_eam_alloy.cpp
rm ../pair_eam_fs.cpp rm ../pair_eam_fs.cpp
rm ../pair_sw.cpp rm ../pair_sw.cpp
rm ../pair_tersoff.cpp rm ../pair_tersoff.cpp
rm ../pair_airebo.h
rm ../pair_eam.h rm ../pair_eam.h
rm ../pair_eam_alloy.h rm ../pair_eam_alloy.h
rm ../pair_eam_fs.h rm ../pair_eam_fs.h

View File

@ -12,7 +12,6 @@
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#ifdef PairInclude #ifdef PairInclude
#include "pair_airebo.h"
#include "pair_eam.h" #include "pair_eam.h"
#include "pair_eam_alloy.h" #include "pair_eam_alloy.h"
#include "pair_eam_fs.h" #include "pair_eam_fs.h"
@ -21,7 +20,6 @@
#endif #endif
#ifdef PairClass #ifdef PairClass
PairStyle(airebo,PairAIREBO)
PairStyle(eam,PairEAM) PairStyle(eam,PairEAM)
PairStyle(eam/alloy,PairEAMAlloy) PairStyle(eam/alloy,PairEAMAlloy)
PairStyle(eam/fs,PairEAMFS) PairStyle(eam/fs,PairEAMFS)

193
src/compute_temp_deform.cpp Normal file
View File

@ -0,0 +1,193 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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: Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "string.h"
#include "compute_temp_deform.h"
#include "domain.h"
#include "atom.h"
#include "force.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "group.h"
#include "comm.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp
/* ---------------------------------------------------------------------- */
ComputeTempDeform::ComputeTempDeform(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all("Illegal compute temp/deform command");
scalar_flag = vector_flag = 1;
size_vector = 6;
extensive = 0;
tempflag = 1;
vector = new double[6];
}
/* ---------------------------------------------------------------------- */
ComputeTempDeform::~ComputeTempDeform()
{
delete [] vector;
}
/* ---------------------------------------------------------------------- */
void ComputeTempDeform::init()
{
int i;
fix_dof = 0;
for (i = 0; i < modify->nfix; i++)
fix_dof += modify->fix[i]->dof(igroup);
recount();
// check fix deform remap settings
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP &&
comm->me == 0)
error->warning("Using fix nvt/sllod with inconsistent fix deform remapping");
break;
}
if (i == modify->nfix && comm->me == 0)
error->warning("Using fix nvt/sllod with no fix deform defined");
}
/* ---------------------------------------------------------------------- */
void ComputeTempDeform::recount()
{
double natoms = group->count(igroup);
dof = force->dimension * natoms;
dof -= extra_dof + fix_dof;
if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
else tfactor = 0.0;
}
/* ---------------------------------------------------------------------- */
double ComputeTempDeform::compute_scalar()
{
double lamda[3],vstream[3],vthermal[3];
double **x = atom->x;
double **v = atom->v;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
// lamda = 0-1 triclinic lamda coords
// vstream = streaming velocity = Hrate*lamda + Hratelo
// vthermal = thermal velocity = v - vstream
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
double t = 0.0;
if (mass) {
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
vthermal[2]*vthermal[2]) * mass[type[i]];
}
}
else
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
vthermal[2]*vthermal[2]) * rmass[i];
}
MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
scalar *= tfactor;
return scalar;
}
/* ---------------------------------------------------------------------- */
void ComputeTempDeform::compute_vector()
{
double lamda[3],vstream[3],vthermal[3];
double **x = atom->x;
double **v = atom->v;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
double massone,t[6];
for (int i = 0; i < 6; i++) t[i] = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
if (mass) massone = mass[type[i]];
else massone = rmass[i];
t[0] += massone * vthermal[0]*vthermal[0];
t[1] += massone * vthermal[1]*vthermal[1];
t[2] += massone * vthermal[2]*vthermal[2];
t[3] += massone * vthermal[0]*vthermal[1];
t[4] += massone * vthermal[0]*vthermal[2];
t[5] += massone * vthermal[1]*vthermal[2];
}
MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
for (int i = 0; i < 6; i++) vector[i] *= force->mvv2e;
}

38
src/compute_temp_deform.h Normal file
View File

@ -0,0 +1,38 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
#ifndef COMPUTE_TEMP_DEFORM_H
#define COMPUTE_TEMP_DEFORM_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeTempDeform : public Compute {
public:
ComputeTempDeform(class LAMMPS *, int, char **);
~ComputeTempDeform();
void init();
double compute_scalar();
void compute_vector();
private:
int fix_dof;
double tfactor;
void recount();
};
}
#endif

674
src/fix_deform.cpp Normal file
View File

@ -0,0 +1,674 @@
/* ----------------------------------------------------------------------
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: Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_deform.h"
#include "atom.h"
#include "update.h"
#include "comm.h"
#include "domain.h"
#include "lattice.h"
#include "force.h"
#include "modify.h"
#include "kspace.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{NONE,FINAL,DELTA,SCALE,VEL,RATE,VOLUME};
enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE};
// same as domain.cpp, fix_nvt_sllod.cpp, compute_temp_deform.cpp
enum{NO_REMAP,X_REMAP,V_REMAP};
/* ---------------------------------------------------------------------- */
FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
{
if (narg < 4) error->all("Illegal fix deform command");
box_change = 1;
nevery = atoi(arg[3]);
if (nevery <= 0) error->all("Illegal fix deform command");
// set defaults
set = new Set[6];
set[0].style = set[1].style = set[2].style =
set[3].style = set[4].style = set[5].style = NONE;
// parse arguments
triclinic = domain->triclinic;
int index;
int iarg = 4;
while (iarg < narg) {
if (strcmp(arg[iarg],"x") == 0 || strcmp(arg[iarg],"y") == 0 ||
strcmp(arg[iarg],"z") == 0) {
if (strcmp(arg[iarg],"x") == 0) index = 0;
else if (strcmp(arg[iarg],"y") == 0) index = 1;
else if (strcmp(arg[iarg],"z") == 0) index = 2;
if (iarg+2 > narg) error->all("Illegal fix deform command");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+4 > narg) error->all("Illegal fix deform command");
set[index].style = FINAL;
set[index].flo = atof(arg[iarg+2]);
set[index].fhi = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg+1],"delta") == 0) {
if (iarg+4 > narg) error->all("Illegal fix deform command");
set[index].style = DELTA;
set[index].dlo = atof(arg[iarg+2]);
set[index].dhi = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg+1],"scale") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = SCALE;
set[index].scale = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"vel") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = VEL;
set[index].vel = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"rate") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = RATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"volume") == 0) {
set[index].style = VOLUME;
iarg += 2;
} else error->all("Illegal fix deform command");
} else if (strcmp(arg[iarg],"xy") == 0 || strcmp(arg[iarg],"xz") == 0 ||
strcmp(arg[iarg],"yz") == 0) {
if (triclinic == 0)
error->all("Fix deform tilt factors require triclinic box");
if (strcmp(arg[iarg],"xy") == 0) index = 5;
else if (strcmp(arg[iarg],"xz") == 0) index = 4;
else if (strcmp(arg[iarg],"yz") == 0) index = 3;
if (iarg+2 > narg) error->all("Illegal fix deform command");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = FINAL;
set[index].ftilt = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"delta") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = DELTA;
set[index].dtilt = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"vel") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = VEL;
set[index].vel = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"rate") == 0) {
if (iarg+3 > narg) error->all("Illegal fix deform command");
set[index].style = RATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else error->all("Illegal fix deform command");
} else break;
}
// read options from end of input line
options(narg-iarg,&arg[iarg]);
// check periodicity
if ((set[0].style && domain->xperiodic == 0) ||
(set[1].style && domain->yperiodic == 0) ||
(set[2].style && domain->zperiodic == 0))
error->all("Cannot fix deform on a non-periodic boundary");
if (set[3].style && (domain->yperiodic == 0 || domain->zperiodic == 0))
error->all("Cannot fix deform on a non-periodic boundary");
if (set[4].style && (domain->xperiodic == 0 || domain->zperiodic == 0))
error->all("Cannot fix deform on a non-periodic boundary");
if (set[5].style && (domain->xperiodic == 0 || domain->yperiodic == 0))
error->all("Cannot fix deform on a non-periodic boundary");
// setup scaling
if (scaleflag && domain->lattice == NULL)
error->all("Use of fix deform with undefined lattice");
if (scaleflag) {
xscale = domain->lattice->xlattice;
yscale = domain->lattice->ylattice;
zscale = domain->lattice->zlattice;
}
else xscale = yscale = zscale = 1.0;
// apply scaling to input parameters with dist/vel units
// for 3,4,5 scale is in 1st dimension, e.g. x for xz
double map[6];
map[0] = xscale; map[1] = yscale; map[2] = zscale;
map[3] = yscale; map[4] = xscale; map[5] = xscale;
for (int i = 0; i < 3; i++) {
if (set[i].style == FINAL) {
set[i].flo *= map[i];
set[i].fhi *= map[i];
} else if (set[i].style == DELTA) {
set[i].dlo *= map[i];
set[i].dhi *= map[i];
} else if (set[i].style == VEL) {
set[i].vel *= map[i];
}
}
for (int i = 3; i < 6; i++) {
if (set[i].style == FINAL) set[i].ftilt *= map[i];
else if (set[i].style == DELTA) set[i].dtilt *= map[i];
else if (set[i].style == VEL) set[i].vel *= map[i];
}
// set initial/final values for box size and shape for FINAL,DELTA,SCALE
// final not possible for VEL,RATE since don't know length of run yet
// final = initial if no setting
for (int i = 0; i < 3; i++) {
set[i].lo_target = set[i].lo_stop = set[i].lo_start = domain->boxlo[i];
set[i].hi_target = set[i].hi_stop = set[i].hi_start = domain->boxhi[i];
if (set[i].style == FINAL) {
set[i].lo_stop = set[i].flo;
set[i].hi_stop = set[i].fhi;
} else if (set[i].style == DELTA) {
set[i].lo_stop = set[i].lo_start + set[i].dlo;
set[i].hi_stop = set[i].hi_start + set[i].dhi;
} else if (set[i].style == SCALE) {
set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*set[i].scale*(set[i].hi_start-set[i].lo_start);
set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*set[i].scale*(set[i].hi_start-set[i].lo_start);
}
}
for (int i = 3; i < 6; i++) {
if (i == 5) set[i].tilt_start = domain->xy;
else if (i == 4) set[i].tilt_start = domain->xz;
else if (i == 3) set[i].tilt_start = domain->yz;
set[i].tilt_flip = set[i].tilt_target =
set[i].tilt_stop = set[i].tilt_start;
if (set[i].style == FINAL) {
set[i].tilt_stop = set[i].ftilt;
} else if (set[i].style == DELTA) {
set[i].tilt_stop = set[i].tilt_start + set[i].dtilt;
}
}
// for VOLUME, setup links to other dims
// fixed, dynamic1,2, vol_start
for (int i = 0; i < 3; i++) {
set[i].vol_start = domain->xprd * domain->yprd * domain->zprd;
if (set[i].style != VOLUME) continue;
int other1 = (i+1) % 3;
int other2 = (i+2) % 3;
if (set[other1].style == NONE) {
if (set[other2].style == NONE || set[other2].style == VOLUME)
error->all("Fix deform volume setting is invalid");
set[i].substyle = ONE_FROM_ONE;
set[i].fixed = other1;
set[i].dynamic1 = other2;
} else if (set[other2].style == NONE) {
if (set[other1].style == NONE || set[other1].style == VOLUME)
error->all("Fix deform volume setting is invalid");
set[i].substyle = ONE_FROM_ONE;
set[i].fixed = other2;
set[i].dynamic1 = other1;
} else if (set[other1].style == VOLUME) {
if (set[other2].style == NONE || set[other2].style == VOLUME)
error->all("Fix deform volume setting is invalid");
set[i].substyle = TWO_FROM_ONE;
set[i].fixed = other1;
set[i].dynamic1 = other2;
} else if (set[other2].style == VOLUME) {
if (set[other1].style == NONE || set[other1].style == VOLUME)
error->all("Fix deform volume setting is invalid");
set[i].substyle = TWO_FROM_ONE;
set[i].fixed = other2;
set[i].dynamic1 = other1;
} else {
set[i].substyle = ONE_FROM_TWO;
set[i].dynamic2 = other1;
set[i].dynamic2 = other2;
}
}
// initial settings
// reneighboring only forced if flips will occur due to shape changes
if (set[3].style || set[4].style || set[5].style) force_reneighbor = 1;
next_reneighbor = -1;
nrigid = 0;
rfix = NULL;
flip = 0;
}
/* ---------------------------------------------------------------------- */
FixDeform::~FixDeform()
{
delete [] set;
delete [] rfix;
}
/* ---------------------------------------------------------------------- */
int FixDeform::setmask()
{
int mask = 0;
mask |= PRE_EXCHANGE;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixDeform::init()
{
// error if more than one fix deform
// domain, fix nvt/sllod, compute temp/deform only work on single h_rate
int count = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) count++;
if (count > 1) error->warning("More than one fix deform");
// Kspace setting
if (force->kspace) kspace_flag = 1;
else kspace_flag = 0;
// elapsed time for entire simulation, including multiple runs if defined
// cannot be 0.0 since can't deform a finite distance in 0 time
double delt = (update->endstep - update->beginstep) * update->dt;
if (delt == 0.0) error->all("Cannot use fix deform for 0 timestep run");
// set final values for box size and shape for VEL,RATE
// now possible since length of run is known
for (int i = 0; i < 3; i++) {
if (set[i].style == VEL) {
set[i].lo_stop = set[i].lo_start - 0.5*delt*set[i].vel;
set[i].hi_stop = set[i].hi_start + 0.5*delt*set[i].vel;
} else if (set[i].style == RATE) {
set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*((set[i].hi_start-set[i].lo_start)*pow(1.0+set[i].rate,delt));
set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*((set[i].hi_start-set[i].lo_start)*pow(1.0+set[i].rate,delt));
}
}
for (int i = 3; i < 6; i++) {
if (set[i].style == VEL) {
set[i].tilt_stop = set[i].tilt_start + delt*set[i].vel;
} else if (set[i].style == RATE) {
set[i].tilt_stop = set[i].tilt_start * pow(1.0+set[i].rate,delt);
}
}
// if using tilt RATE, then initial tilt must be non-zero
for (int i = 3; i < 6; i++)
if (set[i].style == RATE)
if ((i == 5 && domain->xy == 0.0) ||
(i == 4 && domain->xz == 0.0) ||
(i == 3 && domain->yz == 0.0))
error->all("Cannot use fix deform rate to tilt a box with zero tilt");
// if yz changes and will cause box flip, then xy cannot be changing
// this is b/c the flips would induce continuous changes in xz
// in order to keep the edge vectors of the flipped shape matrix
// a linear combination of the edge vectors of the unflipped shape matrix
if (set[3].style && set[5].style)
if (set[3].tilt_stop < -0.5*(set[1].hi_start-set[1].lo_start) ||
set[3].tilt_stop > 0.5*(set[1].hi_start-set[1].lo_start) ||
set[3].tilt_stop < -0.5*(set[1].hi_stop-set[1].lo_stop) ||
set[3].tilt_stop > 0.5*(set[1].hi_stop-set[1].lo_stop))
error->all("Fix deform is changing yz by too much with changing xy");
// set domain->h_rate values for use by domain and other fixes/computes
// initialize all rates to 0.0
// cannot set rate now for RATE,VOLUME styles since not constant
h_rate = domain->h_rate;
h_ratelo = domain->h_ratelo;
for (int i = 0; i < 3; i++) {
h_rate[i] = h_ratelo[i] = 0.0;
if (set[i].style == FINAL || set[i].style == DELTA ||
set[i].style == SCALE || set[i].style == VEL) {
double dlo_dt = (set[i].lo_stop - set[i].lo_start) / delt;
double dhi_dt = (set[i].hi_stop - set[i].hi_start) / delt;
h_rate[i] = dhi_dt - dlo_dt;
h_ratelo[i] = dlo_dt;
}
}
for (int i = 3; i < 6; i++) {
h_rate[i] = 0.0;
if (set[i].style == FINAL || set[i].style == DELTA ||
set[i].style == VEL)
h_rate[i] = (set[i].tilt_stop - set[i].tilt_start) / delt;
}
// detect if any rigid fixes exist so rigid bodies can be rescaled
// rfix[] = indices to each fix rigid
delete [] rfix;
nrigid = 0;
rfix = NULL;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) nrigid++;
if (nrigid) {
rfix = new int[nrigid];
nrigid = 0;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i;
}
}
/* ----------------------------------------------------------------------
box flipped on previous step
perform irregular comm to migrate atoms to new procs
reset box tilts for flipped config and create new box in domain
remap to put far-away atoms back into new box
perform irregular on atoms in lamda coords to get atoms to new procs
force reneighboring on next timestep
------------------------------------------------------------------------- */
void FixDeform::pre_exchange()
{
if (flip == 0) return;
domain->yz = set[3].tilt_target = set[3].tilt_flip;
domain->xz = set[4].tilt_target = set[4].tilt_flip;
domain->xy = set[5].tilt_target = set[5].tilt_flip;
domain->set_global_box();
domain->set_local_box();
double **x = atom->x;
int *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
domain->remap(x[i],image[i]);
domain->x2lamda(atom->nlocal);
comm->irregular();
domain->lamda2x(atom->nlocal);
flip = 0;
}
/* ---------------------------------------------------------------------- */
void FixDeform::end_of_step()
{
int i;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
// set new box size
// for RATE, set target directly based on current time and set h_rate
// for others except VOLUME, target is linear value between start and stop
for (i = 0; i < 3; i++) {
if (set[i].style == NONE) continue;
if (set[i].style == RATE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*((set[i].hi_start-set[i].lo_start)*pow(1.0+set[i].rate,delt));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*((set[i].hi_start-set[i].lo_start)*pow(1.0+set[i].rate,delt));
h_rate[i] = set[i].rate * domain->h[i];
h_ratelo[i] = -0.5*h_rate[i];
} else if (set[i].style != VOLUME) {
set[i].lo_target = set[i].lo_start +
delta*(set[i].lo_stop - set[i].lo_start);
set[i].hi_target = set[i].hi_start +
delta*(set[i].hi_stop - set[i].hi_start);
}
}
// set new box size for VOLUME dims that are linked to other dims
// also need to set h_rate
for (int i = 0; i < 3; i++) {
if (set[i].style != VOLUME) continue;
if (set[i].substyle == ONE_FROM_ONE) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
} else if (set[i].substyle == ONE_FROM_TWO) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].dynamic2].hi_target -
set[set[i].dynamic2].lo_target));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].dynamic2].hi_target -
set[set[i].dynamic2].lo_target));
} else if (set[i].substyle == TWO_FROM_ONE) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*sqrt(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start -
set[set[i].fixed].lo_start) *
(set[i].hi_start - set[i].lo_start));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*sqrt(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start -
set[set[i].fixed].lo_start) *
(set[i].hi_start - set[i].lo_start));
}
}
// for triclinic, set new box shape
// for RATE, set target directly based on current time and set h_rate
// for all others, target is linear value between start and stop values
if (triclinic) {
double *h = domain->h;
for (i = 3; i < 6; i++) {
if (set[i].style == NONE) continue;
if (set[i].style == RATE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].tilt_target = set[i].tilt_start * pow(1.0+set[i].rate,delt);
h_rate[i] = set[i].rate * domain->h[i];
} else if (set[i].style) {
set[i].tilt_target = set[i].tilt_start +
delta*(set[i].tilt_stop - set[i].tilt_start);
}
// tilt_target can be large positive or large negative value
// add/subtract box lengths until tilt_target is closest to current value
int idenom;
if (i == 5) idenom = 0;
else if (i == 4) idenom = 0;
else if (i == 3) idenom = 1;
double denom = set[idenom].hi_target - set[idenom].lo_target;
double current = h[i]/h[idenom];
while (set[i].tilt_target/denom - current > 0.0)
set[i].tilt_target -= denom;
while (set[i].tilt_target/denom - current < 0.0)
set[i].tilt_target += denom;
if (fabs(set[i].tilt_target/denom - 1.0 - current) <
fabs(set[i].tilt_target/denom - current))
set[i].tilt_target -= denom;
}
}
// if any tilt targets exceed bounds, set flip flag and new tilt_flip values
// flip will be performed on next timestep before reneighboring
// when yz flips and xy is non-zero, xz must also change
// this is to keep the edge vectors of the flipped shape matrix
// a linear combination of the edge vectors of the unflipped shape matrix
if (triclinic) {
double xprd = set[0].hi_target - set[0].lo_target;
double yprd = set[1].hi_target - set[1].lo_target;
if (set[3].tilt_target < -0.5*yprd || set[3].tilt_target > 0.5*yprd ||
set[4].tilt_target < -0.5*xprd || set[4].tilt_target > 0.5*xprd ||
set[5].tilt_target < -0.5*xprd || set[5].tilt_target > 0.5*xprd) {
flip = 1;
next_reneighbor = update->ntimestep + 1;
set[3].tilt_flip = set[3].tilt_target;
set[4].tilt_flip = set[4].tilt_target;
set[5].tilt_flip = set[5].tilt_target;
if (set[3].tilt_flip < -0.5*yprd) {
set[3].tilt_flip += yprd;
set[4].tilt_flip += set[5].tilt_flip;
} else if (set[3].tilt_flip >= 0.5*yprd) {
set[3].tilt_flip -= yprd;
set[4].tilt_flip -= set[5].tilt_flip;
}
if (set[4].tilt_flip < -0.5*xprd) set[4].tilt_flip += xprd;
if (set[4].tilt_flip > 0.5*xprd) set[4].tilt_flip -= xprd;
if (set[5].tilt_flip < -0.5*xprd) set[5].tilt_flip += xprd;
if (set[5].tilt_flip > 0.5*xprd) set[5].tilt_flip -= xprd;
}
}
// convert atoms to lamda coords
if (remapflag == X_REMAP) {
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
domain->x2lamda(x[i],x[i]);
}
// reset global and local box to new size/shape
domain->boxlo[0] = set[0].lo_target;
domain->boxlo[1] = set[1].lo_target;
domain->boxlo[2] = set[2].lo_target;
domain->boxhi[0] = set[0].hi_target;
domain->boxhi[1] = set[1].hi_target;
domain->boxhi[2] = set[2].hi_target;
if (triclinic) {
domain->yz = set[3].tilt_target;
domain->xz = set[4].tilt_target;
domain->xy = set[5].tilt_target;
}
domain->set_global_box();
domain->set_local_box();
// convert affine atoms back to box coords
if (remapflag == X_REMAP) {
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
domain->lamda2x(x[i],x[i]);
}
// remap centers-of-mass of rigid bodies
// needs to be new call, not dilate
// check where else fix dilate is called from
/*
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->dilate(2,oldlo,oldhi,newlo,newhi);
*/
// redo KSpace coeffs since box has changed
if (kspace_flag) force->kspace->setup();
}
/* ---------------------------------------------------------------------- */
void FixDeform::options(int narg, char **arg)
{
if (narg < 0) error->all("Illegal fix deform command");
remapflag = X_REMAP;
scaleflag = 1;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"remap") == 0) {
if (iarg+2 > narg) error->all("Illegal fix deform command");
if (strcmp(arg[iarg+1],"x") == 0) remapflag = X_REMAP;
else if (strcmp(arg[iarg+1],"v") == 0) remapflag = V_REMAP;
else if (strcmp(arg[iarg+1],"none") == 0) remapflag = NO_REMAP;
else error->all("Illegal fix deform command");
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all("Illegal fix deform command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all("Illegal fix deform command");
iarg += 2;
} else error->all("Illegal fix deform command");
}
}

View File

@ -11,41 +11,54 @@
See the README file in the top-level LAMMPS directory. See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#ifndef FIX_UNIAXIAL_H #ifndef FIX_DEFORM_H
#define FIX_UNIAXIAL_H #define FIX_DEFORM_H
#include "fix.h" #include "fix.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class FixUniaxial : public Fix { class FixDeform : public Fix {
public: public:
FixUniaxial(class LAMMPS *, int, char **); int remapflag;
~FixUniaxial();
FixDeform(class LAMMPS *, int, char **);
~FixDeform();
int setmask(); int setmask();
void init(); void init();
void pre_exchange();
void end_of_step(); void end_of_step();
private: private:
int dir; double xlo_start,xhi_start,ylo_start,yhi_start,zlo_start,zhi_start;
double lambda_final; double xlo_stop,xhi_stop,ylo_stop,yhi_stop,zlo_stop,zhi_stop;
double alpha0; // asymmetry parameter double xy_start,xz_start,yz_start;
double xy_stop,xz_stop,yz_stop;
double xscale,yscale,zscale;
int triclinic,scaleflag,flip;
double *h_rate,*h_ratelo;
double lambdai[3]; // initial struct Set {
double lambdaf[3]; // final int style,substyle;
double domainloi[3]; // initial box lo/hi double flo,fhi,ftilt;
double domainhii[3]; double dlo,dhi,dtilt;
double *domainlo[3]; // pointers to make loop over dims possible double scale,vel,rate;
double *domainhi[3]; double lo_start,hi_start;
double *domainprd[3]; double lo_stop,hi_stop;
double lo_target,hi_target;
double tilt_start,tilt_stop,tilt_target;
double vol_start,tilt_flip;
int fixed,dynamic1,dynamic2;
};
Set *set;
int kspace_flag; // 1 if KSpace invoked, 0 if not int kspace_flag; // 1 if KSpace invoked, 0 if not
int nrigid; // number of rigid fixes int nrigid; // number of rigid fixes
int *rfix; // indices of rigid fixes int *rfix; // indices of rigid fixes
};
#endif void options(int, char **);
};
} }
#endif

278
src/fix_nvt_sllod.cpp Normal file
View File

@ -0,0 +1,278 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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: Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "stdlib.h"
#include "fix_nvt_sllod.h"
#include "math_extra.h"
#include "atom.h"
#include "force.h"
#include "domain.h"
#include "comm.h"
#include "group.h"
#include "update.h"
#include "respa.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "compute.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp
/* ---------------------------------------------------------------------- */
FixNVTSlodd::FixNVTSlodd(LAMMPS *lmp, int narg, char **arg) :
FixNVT(lmp, narg, arg) {}
/* ---------------------------------------------------------------------- */
void FixNVTSlodd::init()
{
FixNVT::init();
// check fix deform remap settings
int i;
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
if (((FixDeform *) modify->fix[i])->remapflag == X_REMAP &&
comm->me == 0)
error->warning("Using compute temp/deform with fix deform remapping coords");
break;
}
if (i == modify->nfix && comm->me == 0)
error->warning("Using compute temp/deform with no fix deform defined");
}
/* ---------------------------------------------------------------------- */
void FixNVTSlodd::initial_integrate()
{
double dtfm;
double delta = update->ntimestep - update->firststep;
delta /= update->nsteps;
t_target = t_start + delta * (t_stop-t_start);
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
eta += dtv*eta_dot;
factor = exp(-dthalf*eta_dot);
// update vthermal and x of only atoms in NVT group
// lamda = 0-1 triclinic lamda coords
// vstream = streaming velocity = Hrate*lamda + Hratelo
// vthermal = thermal velocity = v - vstream
// vdelu = Hrate*Hinv*vthermal
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
double h_two[6],lamda[3],vstream[3],vthermal[3],vdelu[3];
MathExtra::multiply_shape_shape(h_rate,domain->h_inv,h_two);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
vdelu[0] = h_two[0]*vthermal[0] + h_two[5]*vthermal[1] +
h_two[4]*vthermal[2];
vdelu[1] = h_two[1]*vthermal[1] + h_two[3]*vthermal[2];
vdelu[2] = h_two[2]*vthermal[2];
v[i][0] = vstream[0] +
vthermal[0]*factor + dtfm*f[i][0] - dthalf*vdelu[0];
v[i][1] = vstream[1] +
vthermal[1]*factor + dtfm*f[i][1] - dthalf*vdelu[1];
v[i][2] = vstream[2] +
vthermal[2]*factor + dtfm*f[i][2] - dthalf*vdelu[2];
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVTSlodd::final_integrate()
{
double dtfm;
// update vthermal of only atoms in NVT group
// lamda = 0-1 triclinic lamda coords
// vstream = streaming velocity = Hrate*lamda + Hratelo
// vthermal = thermal velocity = v - vstream
// vdelu = Hrate*Hinv*vthermal
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
double h_two[6],lamda[3],vstream[3],vthermal[3],vdelu[3];
MathExtra::multiply_shape_shape(h_rate,domain->h_inv,h_two);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
vdelu[0] = h_two[0]*vthermal[0] + h_two[5]*vthermal[1] +
h_two[4]*vthermal[2];
vdelu[1] = h_two[1]*vthermal[1] + h_two[3]*vthermal[2];
vdelu[2] = h_two[2]*vthermal[2];
v[i][0] = vstream[0] +
vthermal[0]*factor + dtfm*f[i][0] - dthalf*vdelu[0];
v[i][1] = vstream[1] +
vthermal[1]*factor + dtfm*f[i][1] - dthalf*vdelu[1];
v[i][2] = vstream[2] +
vthermal[2]*factor + dtfm*f[i][2] - dthalf*vdelu[2];
}
}
// compute current T
t_current = temperature->compute_scalar();
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
}
/* ---------------------------------------------------------------------- */
void FixNVTSlodd::initial_integrate_respa(int ilevel, int flag)
{
if (flag) return; // only used by NPT,NPH
// set timesteps by level
double dtfm;
dtv = step_respa[ilevel];
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
dthalf = 0.5 * step_respa[ilevel];
// atom quantities
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
// outermost level - update eta_dot and apply to v
// all other levels - NVE update of v
if (ilevel == nlevels_respa-1) {
double delta = update->ntimestep - update->firststep;
delta /= update->nsteps;
t_target = t_start + delta * (t_stop-t_start);
// update eta_dot
f_eta = t_freq*t_freq * (t_current/t_target - 1.0);
eta_dot += f_eta*dthalf;
eta_dot *= drag_factor;
eta += dtv*eta_dot;
factor = exp(-dthalf*eta_dot);
} else factor = 1.0;
// update v of only atoms in NVT group
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
double h_two[6],lamda[3],vstream[3],vthermal[3],vdelu[3];
MathExtra::multiply_shape_shape(h_rate,domain->h_inv,h_two);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
vthermal[0] = v[i][0] - vstream[0];
vthermal[1] = v[i][1] - vstream[1];
vthermal[2] = v[i][2] - vstream[2];
vdelu[0] = h_two[0]*vthermal[0] + h_two[5]*vthermal[1] +
h_two[4]*vthermal[2];
vdelu[1] = h_two[1]*vthermal[1] + h_two[3]*vthermal[2];
vdelu[2] = h_two[2]*vthermal[2];
v[i][0] = vstream[0] +
vthermal[0]*factor + dtfm*f[i][0] - dthalf*vdelu[0];
v[i][1] = vstream[1] +
vthermal[1]*factor + dtfm*f[i][1] - dthalf*vdelu[1];
v[i][2] = vstream[2] +
vthermal[2]*factor + dtfm*f[i][2] - dthalf*vdelu[2];
}
}
// innermost level - also update x of only atoms in NVT group
if (ilevel == 0) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
}
}
}
}

33
src/fix_nvt_sllod.h Normal file
View File

@ -0,0 +1,33 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
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.
------------------------------------------------------------------------- */
#ifndef FIX_NVT_SLODD_H
#define FIX_NVT_SLODD_H
#include "fix_nvt.h"
namespace LAMMPS_NS {
class FixNVTSlodd : public FixNVT {
public:
FixNVTSlodd(class LAMMPS *, int, char **);
~FixNVTSlodd() {}
void init();
void initial_integrate();
void final_integrate();
void initial_integrate_respa(int,int);
};
}
#endif

View File

@ -1,212 +0,0 @@
/* ----------------------------------------------------------------------
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: Carsten Svaneborg
(Max Planck Institute for Complex Systems, Dresden, Germany)
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_uniaxial.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "domain.h"
#include "modify.h"
#include "comm.h"
#include "kspace.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
FixUniaxial::FixUniaxial(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 6) error->all("Illegal fix uniaxial command");
box_change = 1;
nevery = atoi(arg[3]);
if (nevery <= 0) error->all("Illegal fix uniaxial command");
if (strcmp(arg[4],"x") == 0) dir = 0;
else if (strcmp(arg[4],"y") == 0) dir = 1;
else if (strcmp(arg[4],"z") == 0) dir = 2;
else error->all("Illegal fix uniaxial command");
lambda_final = atof(arg[5]);
if (lambda_final <= 0) error->all("Illegal fix uniaxial command");
if (domain->nonperiodic)
error->all("Cannot use fix uniaxial on non-periodic system");
if (domain->triclinic)
error->all("Cannot use fix uniaxial with triclinic box");
nrigid = 0;
rfix = NULL;
}
/* ---------------------------------------------------------------------- */
FixUniaxial::~FixUniaxial()
{
delete [] rfix;
}
/* ---------------------------------------------------------------------- */
int FixUniaxial::setmask()
{
int mask = 0;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixUniaxial::init()
{
// store pointers to domain variable so can loop over dimensions
domainlo[0] = &domain->boxlo[0];
domainlo[1] = &domain->boxlo[1];
domainlo[2] = &domain->boxlo[2];
domainhi[0] = &domain->boxhi[0];
domainhi[1] = &domain->boxhi[1];
domainhi[2] = &domain->boxhi[2];
domainprd[0] = &domain->xprd;
domainprd[1] = &domain->yprd;
domainprd[2] = &domain->zprd;
double L = pow((domain->boxhi[0]-domain->boxlo[0])*
(domain->boxhi[1]-domain->boxlo[1])*
(domain->boxhi[2]-domain->boxlo[2]) ,1.0/3.0);
// save box sizes for coordinate rescaling
// calculate strains and asymmetry parameter
// alpha=lampdai[first]/lampbdai[second] for the two perp directions
alpha0 = 1.0;
for (int m = 0; m < 3; m++) {
domainloi[m] = *domainlo[m];
domainhii[m] = *domainhi[m];
lambdai[m] = (*domainhi[m] - *domainlo[m])/L;
lambdaf[m] = ( m==dir ? lambda_final : 1.0/sqrt(lambda_final) ) ;
if (m != dir) {
alpha0*= lambdai[m];
alpha0=1.0/alpha0;
}
}
if (comm->me == 0) {
if (screen) {
fprintf(screen,"Initial strain = %g %g %g\n",
lambdai[0],lambdai[1],lambdai[2]);
fprintf(screen,"Target strain = %g %g %g\n",
lambdaf[0],lambdaf[1],lambdaf[2]);
}
if (logfile) {
fprintf(logfile,"Initial strain = %g %g %g\n",
lambdai[0],lambdai[1],lambdai[2]);
fprintf(logfile,"Target strain = %g %g %g\n",
lambdaf[0],lambdaf[1],lambdaf[2]);
}
}
if (force->kspace) kspace_flag = 1;
else kspace_flag = 0;
// detect if any fix rigid exist so rigid bodies can be re-scaled
// rfix[] = indices to each fix rigid
delete [] rfix;
nrigid = 0;
rfix = NULL;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
strcmp(modify->fix[i]->style,"poems") == 0) nrigid++;
if (nrigid) {
rfix = new int[nrigid];
nrigid = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
strcmp(modify->fix[i]->style,"poems") == 0) rfix[nrigid++] = i;
}
}
/* ---------------------------------------------------------------------- */
void FixUniaxial::end_of_step()
{
int i,m;
double oldlo,oldhi,newlo,newhi,ratio;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
double lvalue[3];
// linear interpolation of strain in specified direction
lvalue[dir] = lambdai[dir]*(1.0-delta) + lambdaf[dir]*delta;
// linear interpolation of asymmetry parameter in the perp direction
double alpha = alpha0*(1-delta) + delta;
// calculate strains perpendicular to dir
for (m = 0; m < 3; m++)
if (m != dir) {
lvalue[m] = sqrt(alpha/lvalue[dir]);
alpha=1.0/alpha;
}
// apply appropriate rescaling in each dimension
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (m = 0; m < 3; m++) {
oldlo = *domainlo[m];
oldhi = *domainhi[m];
newlo = domainloi[m] * lvalue[m]/lambdai[m];
newhi = domainhii[m] * lvalue[m]/lambdai[m];
ratio = (newhi - newlo) / *domainprd[m];
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
x[i][m] = newlo + (x[i][m] - oldlo) * ratio;
*domainlo[m] = newlo;
*domainhi[m] = newhi;
domain->prd[m] = *domainprd[m] = newhi - newlo;
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->dilate(m,oldlo,oldhi,newlo,newhi);
}
// redo KSpace coeffs since volume has changed
if (kspace_flag) force->kspace->setup();
}

View File

@ -1,194 +0,0 @@
/* ----------------------------------------------------------------------
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 "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_volume_rescale.h"
#include "update.h"
#include "force.h"
#include "modify.h"
#include "kspace.h"
#include "domain.h"
#include "atom.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
FixVolRescale::FixVolRescale(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 7) error->all("Illegal fix volume/rescale command");
box_change = 1;
nevery = atoi(arg[3]);
if (nevery <= 0) error->all("Illegal fix volume/rescale command");
xflag = yflag = zflag = 0;
int iarg = 4;
while (iarg < narg) {
if (strcmp(arg[iarg],"x") == 0) {
if (iarg+3 > narg) error->all("Illegal fix volume/rescale command");
if (domain->xperiodic == 0)
error->all("Cannot fix volume/rescale on a non-periodic boundary");
xflag = 1;
xlo_stop = atof(arg[iarg+1]);
xhi_stop = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg],"y") == 0) {
if (iarg+3 > narg) error->all("Illegal fix volume/rescale command");
if (domain->yperiodic == 0)
error->all("Cannot fix volume/rescale on a non-periodic boundary");
yflag = 1;
ylo_stop = atof(arg[iarg+1]);
yhi_stop = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg],"z") == 0) {
if (iarg+3 > narg) error->all("Illegal fix volume/rescale command");
if (domain->zperiodic == 0)
error->all("Cannot fix volume/rescale on a non-periodic boundary");
zflag = 1;
zlo_stop = atof(arg[iarg+1]);
zhi_stop = atof(arg[iarg+2]);
iarg += 3;
} else error->all("Illegal fix volume/rescale command");
}
if (domain->triclinic)
error->all("Cannot use fix volume/rescale with triclinic box");
nrigid = 0;
rfix = NULL;
}
/* ---------------------------------------------------------------------- */
FixVolRescale::~FixVolRescale()
{
delete [] rfix;
}
/* ---------------------------------------------------------------------- */
int FixVolRescale::setmask()
{
int mask = 0;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixVolRescale::init()
{
xlo_start = domain->boxlo[0];
xhi_start = domain->boxhi[0];
ylo_start = domain->boxlo[1];
yhi_start = domain->boxhi[1];
zlo_start = domain->boxlo[2];
zhi_start = domain->boxhi[2];
if (force->kspace) kspace_flag = 1;
else kspace_flag = 0;
// detect if any fix rigid exist so rigid bodies can be rescaled
// rfix[] = indices to each fix rigid
delete [] rfix;
nrigid = 0;
rfix = NULL;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
strcmp(modify->fix[i]->style,"poems") == 0) nrigid++;
if (nrigid) {
rfix = new int[nrigid];
nrigid = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
strcmp(modify->fix[i]->style,"poems") == 0) rfix[nrigid++] = i;
}
}
/* ---------------------------------------------------------------------- */
void FixVolRescale::end_of_step()
{
int i;
double oldlo,oldhi,newlo,newhi,ratio;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (xflag) {
oldlo = domain->boxlo[0];
oldhi = domain->boxhi[0];
newlo = xlo_start + delta * (xlo_stop-xlo_start);
newhi = xhi_start + delta * (xhi_stop-xhi_start);
ratio = (newhi - newlo) / domain->xprd;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
x[i][0] = newlo + (x[i][0] - oldlo) * ratio;
domain->boxlo[0] = newlo;
domain->boxhi[0] = newhi;
domain->prd[0] = domain->xprd = newhi - newlo;
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->dilate(0,oldlo,oldhi,newlo,newhi);
}
if (yflag) {
oldlo = domain->boxlo[1];
oldhi = domain->boxhi[1];
newlo = ylo_start + delta * (ylo_stop-ylo_start);
newhi = yhi_start + delta * (yhi_stop-yhi_start);
ratio = (newhi - newlo) / domain->yprd;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
x[i][1] = newlo + (x[i][1] - oldlo) * ratio;
domain->boxlo[1] = newlo;
domain->boxhi[1] = newhi;
domain->prd[1] = domain->yprd = newhi - newlo;
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->dilate(1,oldlo,oldhi,newlo,newhi);
}
if (zflag) {
oldlo = domain->boxlo[2];
oldhi = domain->boxhi[2];
newlo = zlo_start + delta * (zlo_stop-zlo_start);
newhi = zhi_start + delta * (zhi_stop-zhi_start);
ratio = (newhi - newlo) / domain->zprd;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
x[i][2] = newlo + (x[i][2] - oldlo) * ratio;
domain->boxlo[2] = newlo;
domain->boxhi[2] = newhi;
domain->prd[2] = domain->zprd = newhi - newlo;
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->dilate(2,oldlo,oldhi,newlo,newhi);
}
// redo KSpace coeffs since volume has changed
if (kspace_flag) force->kspace->setup();
}

435
src/math_extra.h Executable file
View File

@ -0,0 +1,435 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#ifndef MATH_EXTRA_H
#define MATH_EXTRA_H
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "error.h"
namespace MathExtra {
// 3 vector operations
inline void normalize3(const double *v, double *ans);
inline double dot3(const double *v1, const double *v2);
inline void cross3(const double *v1, const double *v2, double *ans);
// 3x3 matrix operations
inline double det3(const double mat[3][3]);
inline void diag_times3(const double *diagonal, const double mat[3][3],
double ans[3][3]);
inline void plus3(const double m[3][3], const double m2[3][3],
double ans[3][3]);
inline void transpose_times3(const double mat1[3][3],
const double mat2[3][3],
double ans[3][3]);
inline void invert3(const double mat[3][3], double ans[3][3]);
inline void times_column3(const double mat[3][3], const double*vec,
double *ans);
inline void transpose_times_column3(const double mat[3][3],const double*vec,
double *ans);
inline void row_times3(const double *v, const double m[3][3],
double *ans);
inline void mldivide3(const double mat[3][3], const double *vec,
double *ans, LAMMPS_NS::Error *error);
inline void write3(const double mat[3][3]);
// quaternion operations
inline void normalize4(double *quat);
inline void quat_to_mat(const double *quat, double mat[3][3]);
inline void quat_to_mat_trans(const double *quat, double mat[3][3]);
inline void axisangle_to_quat(const double *v, const double angle,
double *quat);
inline void multiply_quat_quat(const double *one, const double *two,
double *ans);
inline void multiply_vec_quat(const double *one, const double *two,
double *ans);
// shape matrix operations
inline void multiply_shape_shape(const double *one, const double *two,
double *ans);
};
/* ----------------------------------------------------------------------
normalize a vector
------------------------------------------------------------------------- */
void MathExtra::normalize3(const double *v, double *ans)
{
double den = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
ans[0] = v[0]/den;
ans[1] = v[1]/den;
ans[2] = v[2]/den;
}
/* ----------------------------------------------------------------------
dot product of 2 vectors
------------------------------------------------------------------------- */
double MathExtra::dot3(const double *v1, const double *v2)
{
return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
}
/* ----------------------------------------------------------------------
cross product of 2 vectors
------------------------------------------------------------------------- */
void MathExtra::cross3(const double *v1, const double *v2, double *ans)
{
ans[0] = v1[1]*v2[2]-v1[2]*v2[1];
ans[1] = v1[2]*v2[0]-v1[0]*v2[2];
ans[2] = v1[0]*v2[1]-v1[1]*v2[0];
}
/* ----------------------------------------------------------------------
determinant of a matrix
------------------------------------------------------------------------- */
double MathExtra::det3(const double m[3][3])
{
double ans = m[0][0]*m[1][1]*m[2][2] - m[0][0]*m[1][2]*m[2][1] -
m[1][0]*m[0][1]*m[2][2] + m[1][0]*m[0][2]*m[2][1] +
m[2][0]*m[0][1]*m[1][2] - m[2][0]*m[0][2]*m[1][1];
return ans;
}
/* ----------------------------------------------------------------------
diagonal matrix times a full matrix
------------------------------------------------------------------------- */
void MathExtra::diag_times3(const double *d, const double m[3][3],
double ans[3][3])
{
ans[0][0] = d[0]*m[0][0];
ans[0][1] = d[0]*m[0][1];
ans[0][2] = d[0]*m[0][2];
ans[1][0] = d[1]*m[1][0];
ans[1][1] = d[1]*m[1][1];
ans[1][2] = d[1]*m[1][2];
ans[2][0] = d[2]*m[2][0];
ans[2][1] = d[2]*m[2][1];
ans[2][2] = d[2]*m[2][2];
}
/* ----------------------------------------------------------------------
add two matrices
------------------------------------------------------------------------- */
void MathExtra::plus3(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]+m2[0][0];
ans[0][1] = m[0][1]+m2[0][1];
ans[0][2] = m[0][2]+m2[0][2];
ans[1][0] = m[1][0]+m2[1][0];
ans[1][1] = m[1][1]+m2[1][1];
ans[1][2] = m[1][2]+m2[1][2];
ans[2][0] = m[2][0]+m2[2][0];
ans[2][1] = m[2][1]+m2[2][1];
ans[2][2] = m[2][2]+m2[2][2];
}
/* ----------------------------------------------------------------------
multiply the transpose of mat1 times mat2
------------------------------------------------------------------------- */
void MathExtra::transpose_times3(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]*m2[0][0]+m[1][0]*m2[1][0]+m[2][0]*m2[2][0];
ans[0][1] = m[0][0]*m2[0][1]+m[1][0]*m2[1][1]+m[2][0]*m2[2][1];
ans[0][2] = m[0][0]*m2[0][2]+m[1][0]*m2[1][2]+m[2][0]*m2[2][2];
ans[1][0] = m[0][1]*m2[0][0]+m[1][1]*m2[1][0]+m[2][1]*m2[2][0];
ans[1][1] = m[0][1]*m2[0][1]+m[1][1]*m2[1][1]+m[2][1]*m2[2][1];
ans[1][2] = m[0][1]*m2[0][2]+m[1][1]*m2[1][2]+m[2][1]*m2[2][2];
ans[2][0] = m[0][2]*m2[0][0]+m[1][2]*m2[1][0]+m[2][2]*m2[2][0];
ans[2][1] = m[0][2]*m2[0][1]+m[1][2]*m2[1][1]+m[2][2]*m2[2][1];
ans[2][2] = m[0][2]*m2[0][2]+m[1][2]*m2[1][2]+m[2][2]*m2[2][2];
}
/* ----------------------------------------------------------------------
invert a matrix
does NOT checks for singular or badly scaled matrix
------------------------------------------------------------------------- */
void MathExtra::invert3(const double m[3][3], double ans[3][3])
{
double den = m[0][0]*m[1][1]*m[2][2]-m[0][0]*m[1][2]*m[2][1];
den += -m[1][0]*m[0][1]*m[2][2]+m[1][0]*m[0][2]*m[2][1];
den += m[2][0]*m[0][1]*m[1][2]-m[2][0]*m[0][2]*m[1][1];
ans[0][0] = (m[1][1]*m[2][2]-m[1][2]*m[2][1]) / den;
ans[0][1] = -(m[0][1]*m[2][2]-m[0][2]*m[2][1]) / den;
ans[0][2] = (m[0][1]*m[1][2]-m[0][2]*m[1][1]) / den;
ans[1][0] = -(m[1][0]*m[2][2]-m[1][2]*m[2][0]) / den;
ans[1][1] = (m[0][0]*m[2][2]-m[0][2]*m[2][0]) / den;
ans[1][2] = -(m[0][0]*m[1][2]-m[0][2]*m[1][0]) / den;
ans[2][0] = (m[1][0]*m[2][1]-m[1][1]*m[2][0]) / den;
ans[2][1] = -(m[0][0]*m[2][1]-m[0][1]*m[2][0]) / den;
ans[2][2] = (m[0][0]*m[1][1]-m[0][1]*m[1][0]) / den;
}
/* ----------------------------------------------------------------------
matrix times vector
------------------------------------------------------------------------- */
void MathExtra::times_column3(const double m[3][3], const double *v,
double *ans)
{
ans[0] = m[0][0]*v[0]+m[0][1]*v[1]+m[0][2]*v[2];
ans[1] = m[1][0]*v[0]+m[1][1]*v[1]+m[1][2]*v[2];
ans[2] = m[2][0]*v[0]+m[2][1]*v[1]+m[2][2]*v[2];
}
/* ----------------------------------------------------------------------
transposed matrix times vector
------------------------------------------------------------------------- */
void MathExtra::transpose_times_column3(const double m[3][3], const double *v,
double *ans)
{
ans[0] = m[0][0]*v[0]+m[1][0]*v[1]+m[2][0]*v[2];
ans[1] = m[0][1]*v[0]+m[1][1]*v[1]+m[2][1]*v[2];
ans[2] = m[0][2]*v[0]+m[1][2]*v[1]+m[2][2]*v[2];
}
/* ----------------------------------------------------------------------
row vector times matrix
------------------------------------------------------------------------- */
void MathExtra::row_times3(const double *v, const double m[3][3],
double *ans)
{
ans[0] = m[0][0]*v[0]+v[1]*m[1][0]+v[2]*m[2][0];
ans[1] = v[0]*m[0][1]+m[1][1]*v[1]+v[2]*m[2][1];
ans[2] = v[0]*m[0][2]+v[1]*m[1][2]+m[2][2]*v[2];
}
/* ----------------------------------------------------------------------
solve Ax = b or M ans = v
use gaussian elimination & partial pivoting on matrix
------------------------------------------------------------------------- */
void MathExtra::mldivide3(const double m[3][3], const double *v, double *ans,
LAMMPS_NS::Error *error)
{
// create augmented matrix for pivoting
double aug[3][4];
for (unsigned i = 0; i < 3; i++) {
aug[i][3] = v[i];
for (unsigned j = 0; j < 3; j++) aug[i][j] = m[i][j];
}
for (unsigned i = 0; i < 2; i++) {
unsigned p = i;
for (unsigned j = i+1; j < 3; j++) {
if (fabs(aug[j][i]) > fabs(aug[i][i])) {
double tempv[4];
memcpy(tempv,aug[i],4*sizeof(double));
memcpy(aug[i],aug[j],4*sizeof(double));
memcpy(aug[j],tempv,4*sizeof(double));
}
}
while (aug[p][i] == 0 && p < 3) p++;
if (p == 3) error->all("Bad matrix inversion in MathExtra::mldivide3");
else
if (p != i) {
double tempv[4];
memcpy(tempv,aug[i],4*sizeof(double));
memcpy(aug[i],aug[p],4*sizeof(double));
memcpy(aug[p],tempv,4*sizeof(double));
}
for (unsigned j = i+1; j < 3; j++) {
double m = aug[j][i]/aug[i][i];
for (unsigned k=i+1; k<4; k++) aug[j][k]-=m*aug[i][k];
}
}
if (aug[2][2] == 0)
error->all("Bad matrix inversion in MathExtra::mldivide3");
// back substitution
ans[2] = aug[2][3]/aug[2][2];
for (int i = 1; i >= 0; i--) {
double sumax = 0.0;
for (unsigned j = i+1; j < 3; j++) sumax += aug[i][j]*ans[j];
ans[i] = (aug[i][3]-sumax) / aug[i][i];
}
}
/* ----------------------------------------------------------------------
output a matrix
------------------------------------------------------------------------- */
void MathExtra::write3(const double mat[3][3])
{
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 3; j++) printf("%g ",mat[i][j]);
printf("\n");
}
}
/* ----------------------------------------------------------------------
normalize a quaternion
------------------------------------------------------------------------- */
void MathExtra::normalize4(double *quat)
{
double den = sqrt(quat[0]*quat[0]+quat[1]*quat[1] +
quat[2]*quat[2]+quat[3]*quat[3]);
quat[0] /= den;
quat[1] /= den;
quat[2] /= den;
quat[3] /= den;
}
/* ----------------------------------------------------------------------
compute rotation matrix from quaternion
quat = [w i j k]
------------------------------------------------------------------------- */
void MathExtra::quat_to_mat(const double *quat, double mat[3][3])
{
double w2 = quat[0]*quat[0];
double i2 = quat[1]*quat[1];
double j2 = quat[2]*quat[2];
double k2 = quat[3]*quat[3];
double twoij = 2.0*quat[1]*quat[2];
double twoik = 2.0*quat[1]*quat[3];
double twojk = 2.0*quat[2]*quat[3];
double twoiw = 2.0*quat[1]*quat[0];
double twojw = 2.0*quat[2]*quat[0];
double twokw = 2.0*quat[3]*quat[0];
mat[0][0] = w2+i2-j2-k2;
mat[0][1] = twoij-twokw;
mat[0][2] = twojw+twoik;
mat[1][0] = twoij+twokw;
mat[1][1] = w2-i2+j2-k2;
mat[1][2] = twojk-twoiw;
mat[2][0] = twoik-twojw;
mat[2][1] = twojk+twoiw;
mat[2][2] = w2-i2-j2+k2;
}
/* ----------------------------------------------------------------------
compute rotation matrix from quaternion conjugate
quat = [w i j k]
------------------------------------------------------------------------- */
void MathExtra::quat_to_mat_trans(const double *quat, double mat[3][3])
{
double w2 = quat[0]*quat[0];
double i2 = quat[1]*quat[1];
double j2 = quat[2]*quat[2];
double k2 = quat[3]*quat[3];
double twoij = 2.0*quat[1]*quat[2];
double twoik = 2.0*quat[1]*quat[3];
double twojk = 2.0*quat[2]*quat[3];
double twoiw = 2.0*quat[1]*quat[0];
double twojw = 2.0*quat[2]*quat[0];
double twokw = 2.0*quat[3]*quat[0];
mat[0][0] = w2+i2-j2-k2;
mat[1][0] = twoij-twokw;
mat[2][0] = twojw+twoik;
mat[0][1] = twoij+twokw;
mat[1][1] = w2-i2+j2-k2;
mat[2][1] = twojk-twoiw;
mat[0][2] = twoik-twojw;
mat[1][2] = twojk+twoiw;
mat[2][2] = w2-i2-j2+k2;
}
/* ----------------------------------------------------------------------
compute quaternion from axis-angle rotation
v MUST be a unit vector
------------------------------------------------------------------------- */
void MathExtra::axisangle_to_quat(const double *v, const double angle,
double *quat)
{
double halfa = 0.5*angle;
double sina = sin(halfa);
quat[0] = cos(halfa);
quat[1] = v[0]*sina;
quat[2] = v[1]*sina;
quat[3] = v[2]*sina;
}
/* ----------------------------------------------------------------------
multiply 2 quaternions
effectively concatenates rotations
NOT a commutative operation
------------------------------------------------------------------------- */
void MathExtra::multiply_quat_quat(const double *one, const double *two,
double *ans)
{
ans[0] = one[0]*two[0]-one[1]*two[1]-one[2]*two[2]-one[3]*two[3];
ans[1] = one[0]*two[1]+one[1]*two[0]+one[2]*two[3]-one[3]*two[2];
ans[2] = one[0]*two[2]-one[1]*two[3]+one[2]*two[0]+one[3]*two[1];
ans[3] = one[0]*two[3]+one[1]*two[2]-one[2]*two[1]+one[3]*two[0];
}
/* ----------------------------------------------------------------------
multiply 3 vector times quaternion
3 vector one is treated as quaternion (0,one)
------------------------------------------------------------------------- */
void MathExtra::multiply_vec_quat(const double *one, const double *two,
double *ans)
{
ans[0] = -one[0]*two[1]-one[1]*two[2]-one[2]*two[3];
ans[1] = one[0]*two[0]+one[1]*two[3]-one[2]*two[2];
ans[2] = -one[0]*two[3]+one[1]*two[0]+one[2]*two[1];
ans[3] = one[0]*two[2]-one[1]*two[1]+one[2]*two[0];
}
/* ----------------------------------------------------------------------
multiply 2 shape matrices
upper-triangular 3x3, stored as 6-vector in Voigt notation
------------------------------------------------------------------------- */
void MathExtra::multiply_shape_shape(const double *one, const double *two,
double *ans)
{
ans[0] = one[0]*two[0];
ans[1] = one[1]*two[1];
ans[2] = one[2]*two[2];
ans[3] = one[1]*two[3] + one[3]*two[2];
ans[4] = one[0]*two[4] + one[5]*two[3] + one[4]*two[2];
ans[5] = one[0]*two[5] + one[5]*two[1];
}
#endif

0
src/style_asphere.h Normal file
View File

View File

@ -1,56 +0,0 @@
/* ----------------------------------------------------------------------
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 AngleInclude
#include "angle_class2.h"
#endif
#ifdef AngleClass
AngleStyle(class2,AngleClass2)
#endif
#ifdef BondInclude
#include "bond_class2.h"
#endif
#ifdef BondClass
BondStyle(class2,BondClass2)
#endif
#ifdef DihedralInclude
#include "dihedral_class2.h"
#endif
#ifdef DihedralClass
DihedralStyle(class2,DihedralClass2)
#endif
#ifdef ImproperInclude
#include "improper_class2.h"
#endif
#ifdef ImproperClass
ImproperStyle(class2,ImproperClass2)
#endif
#ifdef PairInclude
#include "pair_lj_class2.h"
#include "pair_lj_class2_coul_cut.h"
#include "pair_lj_class2_coul_long.h"
#endif
#ifdef PairClass
PairStyle(lj/class2,PairLJClass2)
PairStyle(lj/class2/coul/cut,PairLJClass2CoulCut)
PairStyle(lj/class2/coul/long,PairLJClass2CoulLong)
#endif

0
src/style_colloid.h Normal file
View File

0
src/style_dipole.h Normal file
View File

View File

@ -1,28 +0,0 @@
/* ----------------------------------------------------------------------
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 AtomInclude
#include "atom_vec_dpd.h"
#endif
#ifdef AtomClass
AtomStyle(dpd,AtomVecDPD)
#endif
#ifdef PairInclude
#include "pair_dpd.h"
#endif
#ifdef PairClass
PairStyle(dpd,PairDPD)
#endif

View File

@ -1,50 +0,0 @@
/* ----------------------------------------------------------------------
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 AtomInclude
#include "atom_vec_granular.h"
#endif
#ifdef AtomClass
AtomStyle(granular,AtomVecGranular)
# endif
#ifdef FixInclude
#include "fix_freeze.h"
#include "fix_gran_diag.h"
#include "fix_nve_gran.h"
#include "fix_pour.h"
#include "fix_shear_history.h"
#include "fix_wall_gran.h"
#endif
#ifdef FixClass
FixStyle(freeze,FixFreeze)
FixStyle(gran/diag,FixGranDiag)
FixStyle(nve/gran,FixNVEGran)
FixStyle(pour,FixPour)
FixStyle(SHEAR_HISTORY,FixShearHistory)
FixStyle(wall/gran,FixWallGran)
#endif
#ifdef PairInclude
#include "pair_gran_hertzian.h"
#include "pair_gran_history.h"
#include "pair_gran_no_history.h"
#endif
#ifdef PairClass
PairStyle(gran/hertzian,PairGranHertzian)
PairStyle(gran/history,PairGranHistory)
PairStyle(gran/no_history,PairGranNoHistory)
#endif

View File

@ -1,38 +0,0 @@
/* ----------------------------------------------------------------------
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 KSpaceInclude
#include "ewald.h"
#include "pppm.h"
#include "pppm_tip4p.h"
#endif
#ifdef KSpaceClass
KSpaceStyle(ewald,Ewald)
KSpaceStyle(pppm,PPPM)
KSpaceStyle(pppm/tip4p,PPPMTIP4P)
#endif
#ifdef PairInclude
#include "pair_buck_coul_long.h"
#include "pair_lj_cut_coul_long.h"
#include "pair_lj_cut_coul_long_tip4p.h"
#include "pair_lj_charmm_coul_long.h"
#endif
#ifdef PairClass
PairStyle(buck/coul/long,PairBuckCoulLong)
PairStyle(lj/cut/coul/long,PairLJCutCoulLong)
PairStyle(lj/cut/coul/long/tip4p,PairLJCutCoulLongTIP4P)
PairStyle(lj/charmm/coul/long,PairLJCharmmCoulLong)
#endif

View File

@ -1,30 +0,0 @@
/* ----------------------------------------------------------------------
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 PairInclude
#include "pair_airebo.h"
#include "pair_eam.h"
#include "pair_eam_alloy.h"
#include "pair_eam_fs.h"
#include "pair_sw.h"
#include "pair_tersoff.h"
#endif
#ifdef PairClass
PairStyle(airebo,PairAIREBO)
PairStyle(eam,PairEAM)
PairStyle(eam/alloy,PairEAMAlloy)
PairStyle(eam/fs,PairEAMFS)
PairStyle(sw,PairSW)
PairStyle(tersoff,PairTersoff)
#endif

View File

@ -1,116 +0,0 @@
/* ----------------------------------------------------------------------
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 AngleInclude
#include "angle_charmm.h"
#include "angle_cosine.h"
#include "angle_cosine_squared.h"
#include "angle_harmonic.h"
#include "angle_hybrid.h"
#endif
#ifdef AngleClass
AngleStyle(charmm,AngleCharmm)
AngleStyle(cosine,AngleCosine)
AngleStyle(cosine/squared,AngleCosineSquared)
AngleStyle(harmonic,AngleHarmonic)
AngleStyle(hybrid,AngleHybrid)
#endif
#ifdef AtomInclude
#include "atom_vec_angle.h"
#include "atom_vec_bond.h"
#include "atom_vec_full.h"
#include "atom_vec_molecular.h"
#endif
#ifdef AtomClass
AtomStyle(angle,AtomVecAngle)
AtomStyle(bond,AtomVecBond)
AtomStyle(full,AtomVecFull)
AtomStyle(molecular,AtomVecMolecular)
#endif
#ifdef BondInclude
#include "bond_fene.h"
#include "bond_fene_expand.h"
#include "bond_harmonic.h"
#include "bond_hybrid.h"
#include "bond_morse.h"
#include "bond_nonlinear.h"
#include "bond_quartic.h"
#endif
#ifdef BondClass
BondStyle(fene,BondFENE)
BondStyle(fene/expand,BondFENEExpand)
BondStyle(harmonic,BondHarmonic)
BondStyle(hybrid,BondHybrid)
BondStyle(morse,BondMorse)
BondStyle(nonlinear,BondNonlinear)
BondStyle(quartic,BondQuartic)
#endif
#ifdef DihedralInclude
#include "dihedral_charmm.h"
#include "dihedral_harmonic.h"
#include "dihedral_helix.h"
#include "dihedral_hybrid.h"
#include "dihedral_multi_harmonic.h"
#include "dihedral_opls.h"
#endif
#ifdef DihedralClass
DihedralStyle(charmm,DihedralCharmm)
DihedralStyle(harmonic,DihedralHarmonic)
DihedralStyle(helix,DihedralHelix)
DihedralStyle(hybrid,DihedralHybrid)
DihedralStyle(multi/harmonic,DihedralMultiHarmonic)
DihedralStyle(opls,DihedralOPLS)
#endif
#ifdef DumpInclude
#include "dump_bond.h"
#endif
#ifdef DumpClass
DumpStyle(bond,DumpBond)
#endif
#ifdef FixInclude
#endif
#ifdef FixClass
#endif
#ifdef ImproperInclude
#include "improper_cvff.h"
#include "improper_harmonic.h"
#include "improper_hybrid.h"
#endif
#ifdef ImproperClass
ImproperStyle(cvff,ImproperCvff)
ImproperStyle(harmonic,ImproperHarmonic)
ImproperStyle(hybrid,ImproperHybrid)
#endif
#ifdef PairInclude
#include "pair_lj_charmm_coul_charmm.h"
#include "pair_lj_charmm_coul_charmm_implicit.h"
#endif
#ifdef PairClass
PairStyle(lj/charmm/coul/charmm,PairLJCharmmCoulCharmm)
PairStyle(lj/charmm/coul/charmm/implicit,PairLJCharmmCoulCharmmImplicit)
#endif

View File

@ -1,30 +0,0 @@
/* ----------------------------------------------------------------------
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 PairInclude
#include "pair_eam_opt.h"
#include "pair_eam_alloy_opt.h"
#include "pair_eam_fs_opt.h"
#include "pair_lj_charmm_coul_long_opt.h"
#include "pair_lj_cut_opt.h"
#include "pair_morse_opt.h"
#endif
#ifdef PairClass
PairStyle(eam/opt,PairEAMOpt)
PairStyle(eam/alloy/opt,PairEAMAlloyOpt)
PairStyle(eam/fs/opt,PairEAMFSOpt)
PairStyle(lj/cut/opt,PairLJCutOpt)
PairStyle(lj/charmm/coul/long/opt,PairLJCharmmCoulLongOpt)
PairStyle(morse/opt,PairMorseOpt)
#endif

View File

@ -1,20 +0,0 @@
/* ----------------------------------------------------------------------
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 DumpInclude
#include "dump_xtc.h"
#endif
#ifdef DumpClass
DumpStyle(xtc,DumpXTC)
#endif