From 1a55f94e8a8f575fb2ac07af56e708a1cc874e18 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Tue, 3 Oct 2006 17:52:58 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@64 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/KSPACE/pppm.cpp | 1 + src/angle.cpp | 37 - src/angle_charmm.cpp | 310 --- src/angle_charmm.h | 37 - src/angle_cosine.cpp | 241 --- src/angle_cosine.h | 37 - src/angle_cosine_squared.cpp | 264 --- src/angle_cosine_squared.h | 37 - src/angle_harmonic.cpp | 263 --- src/angle_harmonic.h | 37 - src/angle_hybrid.cpp | 262 --- src/angle_hybrid.h | 46 - src/atom_angle.cpp | 290 --- src/atom_angle.h | 34 - src/atom_bond.cpp | 266 --- src/atom_bond.h | 34 - src/atom_full.cpp | 353 ---- src/atom_full.h | 34 - src/atom_molecular.cpp | 344 ---- src/atom_molecular.h | 34 - src/bond.cpp | 40 - src/bond_fene.cpp | 272 --- src/bond_fene.h | 38 - src/bond_fene_expand.cpp | 292 --- src/bond_fene_expand.h | 38 - src/bond_harmonic.cpp | 204 -- src/bond_harmonic.h | 37 - src/bond_hybrid.cpp | 273 --- src/bond_morse.cpp | 214 --- src/bond_morse.h | 37 - src/bond_nonlinear.cpp | 211 --- src/bond_nonlinear.h | 37 - src/bond_quartic.cpp | 340 ---- src/bond_quartic.h | 39 - src/delete_atoms.cpp | 1 - src/dihedral.cpp | 42 - src/dihedral_charmm.cpp | 450 ----- src/dihedral_charmm.h | 39 - src/dihedral_harmonic.cpp | 356 ---- src/dihedral_harmonic.h | 36 - src/dihedral_helix.cpp | 340 ---- src/dihedral_helix.h | 35 - src/dihedral_hybrid.cpp | 259 --- src/dihedral_hybrid.h | 45 - src/dihedral_multi_harmonic.cpp | 339 ---- src/dihedral_multi_harmonic.h | 35 - src/dihedral_opls.cpp | 349 ---- src/dihedral_opls.h | 35 - src/dump_bond.cpp | 136 -- src/dump_bond.h | 34 - src/ewald.cpp | 846 --------- src/ewald.h | 52 - src/fft3d.cpp | 999 ---------- src/fft3d.h | 242 --- src/fft3d_wrap.cpp | 53 - src/fft3d_wrap.h | 32 - src/improper.cpp | 36 - src/improper_cvff.cpp | 352 ---- src/improper_cvff.h | 36 - src/improper_harmonic.cpp | 286 --- src/improper_harmonic.h | 35 - src/improper_hybrid.cpp | 246 --- src/improper_hybrid.h | 44 - src/input.cpp | 8 + src/pair_buck_coul_long.cpp | 446 ----- src/pair_buck_coul_long.h | 47 - src/pair_eam.cpp | 927 --------- src/pair_eam_alloy.cpp | 472 ----- src/pair_eam_alloy.h | 32 - src/pair_eam_fs.cpp | 771 -------- src/pair_eam_fs.h | 40 - src/pair_lj_charmm_coul_charmm.cpp | 493 ----- src/pair_lj_charmm_coul_charmm.h | 47 - src/pair_lj_charmm_coul_charmm_implicit.cpp | 214 --- src/pair_lj_charmm_coul_charmm_implicit.h | 25 - src/pair_lj_charmm_coul_long.cpp | 1160 ------------ src/pair_lj_cut_coul_long.cpp | 1104 ----------- src/pair_lj_cut_coul_long.h | 59 - src/pair_lj_cut_coul_long_tip4p.cpp | 528 ------ src/pair_lj_cut_coul_long_tip4p.h | 41 - src/pppm.cpp | 1868 ------------------- src/pppm.h | 94 - src/pppm_tip4p.cpp | 261 --- src/pppm_tip4p.h | 31 - src/remap.cpp | 506 ----- src/remap.h | 56 - src/remap_wrap.cpp | 46 - src/remap_wrap.h | 31 - src/style_kspace.h | 38 - src/style_manybody.h | 24 - src/style_molecule.h | 116 -- 91 files changed, 9 insertions(+), 20299 deletions(-) delete mode 100644 src/angle.cpp delete mode 100644 src/angle_charmm.cpp delete mode 100644 src/angle_charmm.h delete mode 100644 src/angle_cosine.cpp delete mode 100644 src/angle_cosine.h delete mode 100644 src/angle_cosine_squared.cpp delete mode 100644 src/angle_cosine_squared.h delete mode 100644 src/angle_harmonic.cpp delete mode 100644 src/angle_harmonic.h delete mode 100644 src/angle_hybrid.cpp delete mode 100644 src/angle_hybrid.h delete mode 100644 src/atom_angle.cpp delete mode 100644 src/atom_angle.h delete mode 100644 src/atom_bond.cpp delete mode 100644 src/atom_bond.h delete mode 100644 src/atom_full.cpp delete mode 100644 src/atom_full.h delete mode 100644 src/atom_molecular.cpp delete mode 100644 src/atom_molecular.h delete mode 100644 src/bond.cpp delete mode 100644 src/bond_fene.cpp delete mode 100644 src/bond_fene.h delete mode 100644 src/bond_fene_expand.cpp delete mode 100644 src/bond_fene_expand.h delete mode 100644 src/bond_harmonic.cpp delete mode 100644 src/bond_harmonic.h delete mode 100644 src/bond_hybrid.cpp delete mode 100644 src/bond_morse.cpp delete mode 100644 src/bond_morse.h delete mode 100644 src/bond_nonlinear.cpp delete mode 100644 src/bond_nonlinear.h delete mode 100755 src/bond_quartic.cpp delete mode 100644 src/bond_quartic.h delete mode 100644 src/dihedral.cpp delete mode 100644 src/dihedral_charmm.cpp delete mode 100644 src/dihedral_charmm.h delete mode 100644 src/dihedral_harmonic.cpp delete mode 100644 src/dihedral_harmonic.h delete mode 100644 src/dihedral_helix.cpp delete mode 100644 src/dihedral_helix.h delete mode 100644 src/dihedral_hybrid.cpp delete mode 100644 src/dihedral_hybrid.h delete mode 100644 src/dihedral_multi_harmonic.cpp delete mode 100644 src/dihedral_multi_harmonic.h delete mode 100644 src/dihedral_opls.cpp delete mode 100644 src/dihedral_opls.h delete mode 100644 src/dump_bond.cpp delete mode 100644 src/dump_bond.h delete mode 100644 src/ewald.cpp delete mode 100644 src/ewald.h delete mode 100644 src/fft3d.cpp delete mode 100644 src/fft3d.h delete mode 100644 src/fft3d_wrap.cpp delete mode 100644 src/fft3d_wrap.h delete mode 100644 src/improper.cpp delete mode 100644 src/improper_cvff.cpp delete mode 100644 src/improper_cvff.h delete mode 100644 src/improper_harmonic.cpp delete mode 100644 src/improper_harmonic.h delete mode 100644 src/improper_hybrid.cpp delete mode 100644 src/improper_hybrid.h delete mode 100644 src/pair_buck_coul_long.cpp delete mode 100644 src/pair_buck_coul_long.h delete mode 100644 src/pair_eam.cpp delete mode 100644 src/pair_eam_alloy.cpp delete mode 100644 src/pair_eam_alloy.h delete mode 100644 src/pair_eam_fs.cpp delete mode 100644 src/pair_eam_fs.h delete mode 100644 src/pair_lj_charmm_coul_charmm.cpp delete mode 100644 src/pair_lj_charmm_coul_charmm.h delete mode 100644 src/pair_lj_charmm_coul_charmm_implicit.cpp delete mode 100644 src/pair_lj_charmm_coul_charmm_implicit.h delete mode 100644 src/pair_lj_charmm_coul_long.cpp delete mode 100644 src/pair_lj_cut_coul_long.cpp delete mode 100644 src/pair_lj_cut_coul_long.h delete mode 100644 src/pair_lj_cut_coul_long_tip4p.cpp delete mode 100644 src/pair_lj_cut_coul_long_tip4p.h delete mode 100644 src/pppm.cpp delete mode 100644 src/pppm.h delete mode 100644 src/pppm_tip4p.cpp delete mode 100644 src/pppm_tip4p.h delete mode 100644 src/remap.cpp delete mode 100644 src/remap.h delete mode 100644 src/remap_wrap.cpp delete mode 100644 src/remap_wrap.h diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 8f486a58a6..ad47238fdf 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -18,6 +18,7 @@ #include "mpi.h" #include "string.h" #include "stdio.h" +#include "stdlib.h" #include "math.h" #include "pppm.h" #include "atom.h" diff --git a/src/angle.cpp b/src/angle.cpp deleted file mode 100644 index 3b689700f9..0000000000 --- a/src/angle.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "angle.h" -#include "atom.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -Angle::Angle() -{ - allocated = 0; - PI = 4.0*atan(1.0); -} - -/* ---------------------------------------------------------------------- - check if all coeffs are set -------------------------------------------------------------------------- */ - -void Angle::init() -{ - if (!allocated) error->all("Angle coeffs are not set"); - for (int i = 1; i <= atom->nangletypes; i++) - if (setflag[i] == 0) error->all("All angle coeffs are not set"); -} - diff --git a/src/angle_charmm.cpp b/src/angle_charmm.cpp deleted file mode 100644 index e23cd9684a..0000000000 --- a/src/angle_charmm.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "angle_charmm.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -AngleCharmm::~AngleCharmm() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(theta0); - memory->sfree(k_ub); - memory->sfree(r_ub); - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCharmm::compute(int eflag, int vflag) -{ - int i1,i2,i3,n,type,factor; - double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dtheta,tk; - double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; - double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **anglelist = neighbor->anglelist; - int nanglelist = neighbor->nanglelist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nanglelist; n++) { - - i1 = anglelist[n][0]; - i2 = anglelist[n][1]; - i3 = anglelist[n][2]; - type = anglelist[n][3]; - - if (newton_bond) factor = 3; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - } - rfactor = factor/3.0; - - // 1st bond - - delx1 = x[i1][0] - x[i2][0]; - dely1 = x[i1][1] - x[i2][1]; - delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - r1 = sqrt(rsq1); - - // 2nd bond - - delx2 = x[i3][0] - x[i2][0]; - dely2 = x[i3][1] - x[i2][1]; - delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - r2 = sqrt(rsq2); - - // Urey-Bradley bond - - delxUB = x[i3][0] - x[i1][0]; - delyUB = x[i3][1] - x[i1][1]; - delzUB = x[i3][2] - x[i1][2]; - domain->minimum_image(&delxUB,&delyUB,&delzUB); - - rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB; - rUB = sqrt(rsqUB); - - // angle (cos and sin) - - c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - s = sqrt(1.0 - c*c); - if (s < SMALL) s = SMALL; - s = 1.0/s; - - // harmonic force & energy - - dtheta = acos(c) - theta0[type]; - tk = k[type] * dtheta; - - if (eflag) energy += rfactor * tk*dtheta; - - a = 2.0 * tk * s; - - a11 = a*c / rsq1; - a12 = -a / (r1*r2); - a22 = a*c / rsq2; - - vx1 = a11*delx1 + a12*delx2; - vx2 = a22*delx2 + a12*delx1; - vy1 = a11*dely1 + a12*dely2; - vy2 = a22*dely2 + a12*dely1; - vz1 = a11*delz1 + a12*delz2; - vz2 = a22*delz2 + a12*delz1; - - // Urey-Bradley force & energy - - dr = rUB - r_ub[type]; - rk = k_ub[type] * dr; - - if (rUB > 0.0) forceUB = -2.0*rk/rUB; - else forceUB = 0.0; - - if (eflag) energy += rfactor * rk*dr; - - // apply force to each of 3 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= vx1 + delxUB*forceUB; - f[i1][1] -= vy1 + delyUB*forceUB; - f[i1][2] -= vz1 + delzUB*forceUB; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += vx1 + vx2; - f[i2][1] += vy1 + vy2; - f[i2][2] += vz1 + vz2; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] -= vx2 - delxUB*forceUB; - f[i3][1] -= vy2 - delyUB*forceUB; - f[i3][2] -= vz2 - delzUB*forceUB; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (delx1*vx1 + delx2*vx2 - delxUB*delxUB*forceUB); - virial[1] -= rfactor * (dely1*vy1 + dely2*vy2 - delyUB*delyUB*forceUB); - virial[2] -= rfactor * (delz1*vz1 + delz2*vz2 - delzUB*delzUB*forceUB); - virial[3] -= rfactor * (delx1*vy1 + delx2*vy2 - delxUB*delyUB*forceUB); - virial[4] -= rfactor * (delx1*vz1 + delx2*vz2 - delxUB*delzUB*forceUB); - virial[5] -= rfactor * (dely1*vz1 + dely2*vz2 - delyUB*delzUB*forceUB); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCharmm::allocate() -{ - allocated = 1; - int n = atom->nangletypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"angle:k"); - theta0 = (double *) memory->smalloc((n+1)*sizeof(double),"angle:theta0"); - k_ub = (double *) memory->smalloc((n+1)*sizeof(double),"angle:k_ub"); - r_ub = (double *) memory->smalloc((n+1)*sizeof(double),"angle:r_ub"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"angle:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void AngleCharmm::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this angle style"); - if (narg != 5) error->all("Incorrect args for angle coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nangletypes,ilo,ihi); - - double k_one = atof(arg[1]); - double theta0_one = atof(arg[2]); - double k_ub_one = atof(arg[3]); - double r_ub_one = atof(arg[4]); - - // convert theta0 from degrees to radians - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; - k_ub[i] = k_ub_one; - r_ub[i] = r_ub_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for angle coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double AngleCharmm::equilibrium_angle(int i) -{ - return theta0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void AngleCharmm::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nangletypes,fp); - fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp); - fwrite(&k_ub[1],sizeof(double),atom->nangletypes,fp); - fwrite(&r_ub[1],sizeof(double),atom->nangletypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void AngleCharmm::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nangletypes,fp); - fread(&theta0[1],sizeof(double),atom->nangletypes,fp); - fread(&k_ub[1],sizeof(double),atom->nangletypes,fp); - fread(&r_ub[1],sizeof(double),atom->nangletypes,fp); - } - MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world); - MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k_ub[1],atom->nangletypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r_ub[1],atom->nangletypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -double AngleCharmm::single(int type, int i1, int i2, int i3, double rfactor) -{ - double **x = atom->x; - - double delx1 = x[i1][0] - x[i2][0]; - double dely1 = x[i1][1] - x[i2][1]; - double delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); - - double delx2 = x[i3][0] - x[i2][0]; - double dely2 = x[i3][1] - x[i2][1]; - double delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); - - double delxUB = x[i3][0] - x[i1][0]; - double delyUB = x[i3][1] - x[i1][1]; - double delzUB = x[i3][2] - x[i1][2]; - domain->minimum_image(&delxUB,&delyUB,&delzUB); - double rUB = sqrt(delxUB*delxUB + delyUB*delyUB + delzUB*delzUB); - - double c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - double dtheta = acos(c) - theta0[type]; - double tk = k[type] * dtheta; - double dr = rUB - r_ub[type]; - double rk = k_ub[type] * dr; - - return (rfactor * (tk*dtheta + rk*dr)); -} diff --git a/src/angle_charmm.h b/src/angle_charmm.h deleted file mode 100644 index 278e8e2493..0000000000 --- a/src/angle_charmm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 ANGLE_CHARMM_H -#define ANGLE_CHARMM_H - -#include "stdio.h" -#include "angle.h" - -class AngleCharmm : public Angle { - public: - AngleCharmm() {} - ~AngleCharmm(); - void compute(int, int); - void coeff(int, int, char **); - double equilibrium_angle(int); - void write_restart(FILE *); - void read_restart(FILE *); - double single(int, int, int, int, double); - - private: - double *k,*theta0,*k_ub,*r_ub; - - void allocate(); -}; - -#endif diff --git a/src/angle_cosine.cpp b/src/angle_cosine.cpp deleted file mode 100644 index 6f33f0e7ba..0000000000 --- a/src/angle_cosine.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "angle_cosine.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -AngleCosine::~AngleCosine() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCosine::compute(int eflag, int vflag) -{ - int i1,i2,i3,n,type,factor; - double delx1,dely1,delz1,delx2,dely2,delz2,rfactor; - double rsq1,rsq2,r1,r2,c,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **anglelist = neighbor->anglelist; - int nanglelist = neighbor->nanglelist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nanglelist; n++) { - - i1 = anglelist[n][0]; - i2 = anglelist[n][1]; - i3 = anglelist[n][2]; - type = anglelist[n][3]; - - if (newton_bond) factor = 3; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - } - rfactor = factor/3.0; - - // 1st bond - - delx1 = x[i1][0] - x[i2][0]; - dely1 = x[i1][1] - x[i2][1]; - delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - r1 = sqrt(rsq1); - - // 2nd bond - - delx2 = x[i3][0] - x[i2][0]; - dely2 = x[i3][1] - x[i2][1]; - delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - r2 = sqrt(rsq2); - - // c = cosine of angle - - c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - // force & energy - - if (eflag) energy += rfactor * k[type]*(1.0+c); - - a = -k[type]; - - a11 = a*c / rsq1; - a12 = -a / (r1*r2); - a22 = a*c / rsq2; - - vx1 = a11*delx1 + a12*delx2; - vx2 = a22*delx2 + a12*delx1; - vy1 = a11*dely1 + a12*dely2; - vy2 = a22*dely2 + a12*dely1; - vz1 = a11*delz1 + a12*delz2; - vz2 = a22*delz2 + a12*delz1; - - // apply force to each of 3 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= vx1; - f[i1][1] -= vy1; - f[i1][2] -= vz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += vx1 + vx2; - f[i2][1] += vy1 + vy2; - f[i2][2] += vz1 + vz2; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] -= vx2; - f[i3][1] -= vy2; - f[i3][2] -= vz2; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (delx1*vx1 + delx2*vx2); - virial[1] -= rfactor * (dely1*vy1 + dely2*vy2); - virial[2] -= rfactor * (delz1*vz1 + delz2*vz2); - virial[3] -= rfactor * (delx1*vy1 + delx2*vy2); - virial[4] -= rfactor * (delx1*vz1 + delx2*vz2); - virial[5] -= rfactor * (dely1*vz1 + dely2*vz2); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCosine::allocate() -{ - allocated = 1; - int n = atom->nangletypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"angle:k"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"angle:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void AngleCosine::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this angle style"); - if (narg != 2) error->all("Incorrect args for angle coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nangletypes,ilo,ihi); - - double k_one = atof(arg[1]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for angle coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double AngleCosine::equilibrium_angle(int i) -{ - return PI; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void AngleCosine::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nangletypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void AngleCosine::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) fread(&k[1],sizeof(double),atom->nangletypes,fp); - MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -double AngleCosine::single(int type, int i1, int i2, int i3, double rfactor) -{ - double **x = atom->x; - - double delx1 = x[i1][0] - x[i2][0]; - double dely1 = x[i1][1] - x[i2][1]; - double delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); - - double delx2 = x[i3][0] - x[i2][0]; - double dely2 = x[i3][1] - x[i2][1]; - double delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); - - double c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - return (rfactor * k[type]*(1.0+c)); -} diff --git a/src/angle_cosine.h b/src/angle_cosine.h deleted file mode 100644 index 6adf7e6846..0000000000 --- a/src/angle_cosine.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 ANGLE_COSINE_H -#define ANGLE_COSINE_H - -#include "stdio.h" -#include "angle.h" - -class AngleCosine : public Angle { - public: - AngleCosine() {} - ~AngleCosine(); - void compute(int, int); - void coeff(int, int, char **); - double equilibrium_angle(int); - void write_restart(FILE *); - void read_restart(FILE *); - double single(int, int, int, int, double); - - private: - double *k; - - void allocate(); -}; - -#endif diff --git a/src/angle_cosine_squared.cpp b/src/angle_cosine_squared.cpp deleted file mode 100644 index 581204cee4..0000000000 --- a/src/angle_cosine_squared.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Naveen Michaud-Agrawal (Johns Hopkins U) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "angle_cosine_squared.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -AngleCosineSquared::~AngleCosineSquared() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(theta0); - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCosineSquared::compute(int eflag, int vflag) -{ - int i1,i2,i3,n,type,factor; - double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dcostheta,tk; - double rsq1,rsq2,r1,r2,c,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **anglelist = neighbor->anglelist; - int nanglelist = neighbor->nanglelist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nanglelist; n++) { - - i1 = anglelist[n][0]; - i2 = anglelist[n][1]; - i3 = anglelist[n][2]; - type = anglelist[n][3]; - - if (newton_bond) factor = 3; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - } - rfactor = factor/3.0; - - // 1st bond - - delx1 = x[i1][0] - x[i2][0]; - dely1 = x[i1][1] - x[i2][1]; - delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - r1 = sqrt(rsq1); - - // 2nd bond - - delx2 = x[i3][0] - x[i2][0]; - dely2 = x[i3][1] - x[i2][1]; - delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - r2 = sqrt(rsq2); - - // angle (cos and sin) - - c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - // force & energy - - dcostheta = c - cos(theta0[type]); - tk = k[type] * dcostheta; - - if (eflag) energy += rfactor * tk*dcostheta; - - a = -2.0 * tk; - - a11 = a*c / rsq1; - a12 = -a / (r1*r2); - a22 = a*c / rsq2; - - vx1 = a11*delx1 + a12*delx2; - vx2 = a22*delx2 + a12*delx1; - vy1 = a11*dely1 + a12*dely2; - vy2 = a22*dely2 + a12*dely1; - vz1 = a11*delz1 + a12*delz2; - vz2 = a22*delz2 + a12*delz1; - - // apply force to each of 3 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= vx1; - f[i1][1] -= vy1; - f[i1][2] -= vz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += vx1 + vx2; - f[i2][1] += vy1 + vy2; - f[i2][2] += vz1 + vz2; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] -= vx2; - f[i3][1] -= vy2; - f[i3][2] -= vz2; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (delx1*vx1 + delx2*vx2); - virial[1] -= rfactor * (dely1*vy1 + dely2*vy2); - virial[2] -= rfactor * (delz1*vz1 + delz2*vz2); - virial[3] -= rfactor * (delx1*vy1 + delx2*vy2); - virial[4] -= rfactor * (delx1*vz1 + delx2*vz2); - virial[5] -= rfactor * (dely1*vz1 + dely2*vz2); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleCosineSquared::allocate() -{ - allocated = 1; - int n = atom->nangletypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"angle:k"); - theta0 = (double *) memory->smalloc((n+1)*sizeof(double),"angle:theta0"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"angle:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more types -------------------------------------------------------------------------- */ - -void AngleCosineSquared::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this angle style"); - if (narg != 3) error->all("Incorrect args for angle coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nangletypes,ilo,ihi); - - double k_one = atof(arg[1]); - double theta0_one = atof(arg[2]); - - // convert theta0 from degrees to radians - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for angle coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double AngleCosineSquared::equilibrium_angle(int i) -{ - return theta0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void AngleCosineSquared::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nangletypes,fp); - fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void AngleCosineSquared::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nangletypes,fp); - fread(&theta0[1],sizeof(double),atom->nangletypes,fp); - } - MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world); - MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -double AngleCosineSquared::single(int type, int i1, int i2, int i3, - double rfactor) -{ - double **x = atom->x; - - double delx1 = x[i1][0] - x[i2][0]; - double dely1 = x[i1][1] - x[i2][1]; - double delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); - - double delx2 = x[i3][0] - x[i2][0]; - double dely2 = x[i3][1] - x[i2][1]; - double delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); - - double c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - double dcostheta = c - cos(theta0[type]); - double tk = k[type] * dcostheta; - return (rfactor * tk*dcostheta); -} diff --git a/src/angle_cosine_squared.h b/src/angle_cosine_squared.h deleted file mode 100644 index cc7ce9b14f..0000000000 --- a/src/angle_cosine_squared.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 ANGLE_COSINE_SQUARED_H -#define ANGLE_COSINE_SQUARED_H - -#include "stdio.h" -#include "angle.h" - -class AngleCosineSquared : public Angle { - public: - AngleCosineSquared() {} - ~AngleCosineSquared(); - void compute(int, int); - void coeff(int, int, char **); - double equilibrium_angle(int); - void write_restart(FILE *); - void read_restart(FILE *); - double single(int, int, int, int, double); - - private: - double *k,*theta0; - - void allocate(); -}; - -#endif diff --git a/src/angle_harmonic.cpp b/src/angle_harmonic.cpp deleted file mode 100644 index 6b9b2a9ccf..0000000000 --- a/src/angle_harmonic.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "angle_harmonic.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -AngleHarmonic::~AngleHarmonic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(theta0); - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleHarmonic::compute(int eflag, int vflag) -{ - int i1,i2,i3,n,type,factor; - double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dtheta,tk; - double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **anglelist = neighbor->anglelist; - int nanglelist = neighbor->nanglelist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nanglelist; n++) { - - i1 = anglelist[n][0]; - i2 = anglelist[n][1]; - i3 = anglelist[n][2]; - type = anglelist[n][3]; - - if (newton_bond) factor = 3; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - } - rfactor = factor/3.0; - - // 1st bond - - delx1 = x[i1][0] - x[i2][0]; - dely1 = x[i1][1] - x[i2][1]; - delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - r1 = sqrt(rsq1); - - // 2nd bond - - delx2 = x[i3][0] - x[i2][0]; - dely2 = x[i3][1] - x[i2][1]; - delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - r2 = sqrt(rsq2); - - // angle (cos and sin) - - c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - s = sqrt(1.0 - c*c); - if (s < SMALL) s = SMALL; - s = 1.0/s; - - // force & energy - - dtheta = acos(c) - theta0[type]; - tk = k[type] * dtheta; - - if (eflag) energy += rfactor * tk*dtheta; - - a = 2.0 * tk * s; - - a11 = a*c / rsq1; - a12 = -a / (r1*r2); - a22 = a*c / rsq2; - - vx1 = a11*delx1 + a12*delx2; - vx2 = a22*delx2 + a12*delx1; - vy1 = a11*dely1 + a12*dely2; - vy2 = a22*dely2 + a12*dely1; - vz1 = a11*delz1 + a12*delz2; - vz2 = a22*delz2 + a12*delz1; - - // apply force to each of 3 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= vx1; - f[i1][1] -= vy1; - f[i1][2] -= vz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += vx1 + vx2; - f[i2][1] += vy1 + vy2; - f[i2][2] += vz1 + vz2; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] -= vx2; - f[i3][1] -= vy2; - f[i3][2] -= vz2; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (delx1*vx1 + delx2*vx2); - virial[1] -= rfactor * (dely1*vy1 + dely2*vy2); - virial[2] -= rfactor * (delz1*vz1 + delz2*vz2); - virial[3] -= rfactor * (delx1*vy1 + delx2*vy2); - virial[4] -= rfactor * (delx1*vz1 + delx2*vz2); - virial[5] -= rfactor * (dely1*vz1 + dely2*vz2); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleHarmonic::allocate() -{ - allocated = 1; - int n = atom->nangletypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"angle:k"); - theta0 = (double *) memory->smalloc((n+1)*sizeof(double),"angle:theta0"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"angle:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more types -------------------------------------------------------------------------- */ - -void AngleHarmonic::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this angle style"); - if (narg != 3) error->all("Incorrect args for angle coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nangletypes,ilo,ihi); - - double k_one = atof(arg[1]); - double theta0_one = atof(arg[2]); - - // convert theta0 from degrees to radians - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for angle coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double AngleHarmonic::equilibrium_angle(int i) -{ - return theta0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void AngleHarmonic::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nangletypes,fp); - fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void AngleHarmonic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nangletypes,fp); - fread(&theta0[1],sizeof(double),atom->nangletypes,fp); - } - MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world); - MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -double AngleHarmonic::single(int type, int i1, int i2, int i3, double rfactor) -{ - double **x = atom->x; - - double delx1 = x[i1][0] - x[i2][0]; - double dely1 = x[i1][1] - x[i2][1]; - double delz1 = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1); - - double delx2 = x[i3][0] - x[i2][0]; - double dely2 = x[i3][1] - x[i2][1]; - double delz2 = x[i3][2] - x[i2][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2); - - double c = delx1*delx2 + dely1*dely2 + delz1*delz2; - c /= r1*r2; - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - double dtheta = acos(c) - theta0[type]; - double tk = k[type] * dtheta; - return (rfactor * tk*dtheta); -} diff --git a/src/angle_harmonic.h b/src/angle_harmonic.h deleted file mode 100644 index 8b097f9e1a..0000000000 --- a/src/angle_harmonic.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 ANGLE_HARMONIC_H -#define ANGLE_HARMONIC_H - -#include "stdio.h" -#include "angle.h" - -class AngleHarmonic : public Angle { - public: - AngleHarmonic() {} - ~AngleHarmonic(); - void compute(int, int); - void coeff(int, int, char **); - double equilibrium_angle(int); - void write_restart(FILE *); - void read_restart(FILE *); - double single(int, int, int, int, double); - - private: - double *k,*theta0; - - void allocate(); -}; - -#endif diff --git a/src/angle_hybrid.cpp b/src/angle_hybrid.cpp deleted file mode 100644 index 12d7a0093e..0000000000 --- a/src/angle_hybrid.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* ----------------------------------------------------------------------- - 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 "angle_hybrid.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define EXTRA 1000 - -/* ---------------------------------------------------------------------- - set all global defaults -------------------------------------------------------------------------- */ - -AngleHybrid::AngleHybrid() -{ - nstyles = 0; -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -AngleHybrid::~AngleHybrid() -{ - if (nstyles) { - for (int i = 0; i < nstyles; i++) delete styles[i]; - delete [] styles; - for (int i = 0; i < nstyles; i++) delete [] keywords[i]; - delete [] keywords; - } - - if (allocated) { - memory->sfree(setflag); - memory->sfree(map); - delete [] nanglelist; - delete [] maxangle; - for (int i = 0; i < nstyles; i++) - memory->destroy_2d_int_array(anglelist[i]); - delete [] anglelist; - } -} - -/* ---------------------------------------------------------------------- */ - -void AngleHybrid::compute(int eflag, int vflag) -{ - int i,m,n; - - // save ptrs to original anglelist - - int nanglelist_orig = neighbor->nanglelist; - int **anglelist_orig = neighbor->anglelist; - - // if this is re-neighbor step, create sub-style anglelists - // nanglelist[] = length of each sub-style list - // realloc sub-style anglelist if necessary - // load sub-style anglelist with 4 values from original anglelist - - if (neighbor->ago == 0) { - for (m = 0; m < nstyles; m++) nanglelist[m] = 0; - for (i = 0; i < nanglelist_orig; i++) - nanglelist[map[anglelist_orig[i][3]]]++; - for (m = 0; m < nstyles; m++) { - if (nanglelist[m] > maxangle[m]) { - memory->destroy_2d_int_array(anglelist[m]); - maxangle[m] = nanglelist[m] + EXTRA; - anglelist[m] = (int **) - memory->create_2d_int_array(maxangle[m],4,"angle_hybrid:anglelist"); - } - nanglelist[m] = 0; - } - for (i = 0; i < nanglelist_orig; i++) { - m = map[anglelist_orig[i][3]]; - n = nanglelist[m]; - anglelist[m][n][0] = anglelist_orig[i][0]; - anglelist[m][n][1] = anglelist_orig[i][1]; - anglelist[m][n][2] = anglelist_orig[i][2]; - anglelist[m][n][3] = anglelist_orig[i][3]; - nanglelist[m]++; - } - } - - // call each sub-style's compute function - // must set neighbor->anglelist to sub-style anglelist before call - // accumulate sub-style energy,virial in hybrid's energy,virial - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - for (m = 0; m < nstyles; m++) { - if (styles[m] == NULL) continue; - neighbor->nanglelist = nanglelist[m]; - neighbor->anglelist = anglelist[m]; - styles[m]->compute(eflag,vflag); - if (eflag) energy += styles[m]->energy; - if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; - } - - // restore ptrs to original anglelist - - neighbor->nanglelist = nanglelist_orig; - neighbor->anglelist = anglelist_orig; -} - -/* ---------------------------------------------------------------------- */ - -void AngleHybrid::allocate() -{ - allocated = 1; - int n = atom->nangletypes; - - map = (int *) memory->smalloc((n+1)*sizeof(int),"angle:map"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"angle:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; - - nanglelist = new int[nstyles]; - maxangle = new int[nstyles]; - anglelist = new int**[nstyles]; - for (int m = 0; m < nstyles; m++) maxangle[m] = 0; - for (int m = 0; m < nstyles; m++) anglelist[m] = NULL; -} - -/* ---------------------------------------------------------------------- - create one angle style for each arg in list -------------------------------------------------------------------------- */ - -void AngleHybrid::settings(int narg, char **arg) -{ - nstyles = narg; - styles = new Angle*[nstyles]; - keywords = new char*[nstyles]; - - for (int m = 0; m < nstyles; m++) { - for (int i = 0; i < m; i++) - if (strcmp(arg[m],arg[i]) == 0) - error->all("Angle style hybrid cannot use same angle style twice"); - if (strcmp(arg[m],"hybrid") == 0) - error->all("Angle style hybrid cannot have hybrid as an argument"); - styles[m] = force->new_angle(arg[m]); - keywords[m] = new char[strlen(arg[m])+1]; - strcpy(keywords[m],arg[m]); - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one type ----------------------------------------------------------------------- */ - -void AngleHybrid::coeff(int which, int narg, char **arg) -{ - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nangletypes,ilo,ihi); - - // 2nd arg = angle style name (harmonic, etc) - - int m; - for (m = 0; m < nstyles; m++) - if (strcmp(arg[1],keywords[m]) == 0) break; - if (m == nstyles) error->all("Angle coeff for hybrid has invalid style"); - - // set low-level coefficients for each angletype - // replace 2nd arg with i, call coeff() with no 1st arg - // if sub-style is NULL for "none", still set setflag - - for (int i = ilo; i <= ihi; i++) { - sprintf(arg[1],"%d",i); - map[i] = m; - if (styles[m]) styles[m]->coeff(which,narg-1,&arg[1]); - setflag[i] = 1; - } -} - -/* ---------------------------------------------------------------------- - return an equilbrium angle length -------------------------------------------------------------------------- */ - -double AngleHybrid::equilibrium_angle(int i) -{ - return styles[map[i]]->equilibrium_angle(i); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void AngleHybrid::write_restart(FILE *fp) -{ - fwrite(&nstyles,sizeof(int),1,fp); - - int n; - for (int m = 0; m < nstyles; m++) { - n = strlen(keywords[m]) + 1; - fwrite(&n,sizeof(int),1,fp); - fwrite(keywords[m],sizeof(char),n,fp); - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void AngleHybrid::read_restart(FILE *fp) -{ - allocate(); - - int me = comm->me; - if (me == 0) fread(&nstyles,sizeof(int),1,fp); - MPI_Bcast(&nstyles,1,MPI_INT,0,world); - styles = new Angle*[nstyles]; - keywords = new char*[nstyles]; - - int n; - for (int m = 0; m < nstyles; m++) { - if (me == 0) fread(&n,sizeof(int),1,fp); - MPI_Bcast(&n,1,MPI_INT,0,world); - keywords[m] = new char[n]; - if (me == 0) fread(keywords[m],sizeof(char),n,fp); - MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_angle(keywords[m]); - } -} - -/* ---------------------------------------------------------------------- */ - -double AngleHybrid::single(int type, int i1, int i2, int i3, double rfactor) -{ - if (styles[map[type]]) - return styles[map[type]]->single(type,i1,i2,i3,rfactor); - else return 0.0; -} - -/* ---------------------------------------------------------------------- - memory usage -------------------------------------------------------------------------- */ - -int AngleHybrid::memory_usage() -{ - int bytes = 0; - for (int m = 0; m < nstyles; m++) bytes += maxangle[m]*4 * sizeof(int); - for (int m = 0; m < nstyles; m++) - if (styles[m]) bytes += styles[m]->memory_usage(); - return bytes; -} diff --git a/src/angle_hybrid.h b/src/angle_hybrid.h deleted file mode 100644 index 250238cfc3..0000000000 --- a/src/angle_hybrid.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 ANGLE_HYBRID_H -#define ANGLE_HYBRID_H - -#include "stdio.h" -#include "angle.h" - -class AngleHybrid : public Angle { - public: - AngleHybrid(); - ~AngleHybrid(); - void compute(int, int); - void settings(int, char **); - void coeff(int, int, char **); - double equilibrium_angle(int); - void write_restart(FILE *); - void read_restart(FILE *); - double single(int, int, int, int, double); - int memory_usage(); - - private: - int nstyles; // # of different angle styles - Angle **styles; // class list for each Angle style - char **keywords; // keyword for each Angle style - int *map; // which style each angle type points to - - int *nanglelist; // # of angles in sub-style anglelists - int *maxangle; // max # of angles sub-style lists can store - int ***anglelist; // anglelist for each sub-style - - void allocate(); -}; - -#endif diff --git a/src/atom_angle.cpp b/src/atom_angle.cpp deleted file mode 100644 index f8d9716571..0000000000 --- a/src/atom_angle.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "atom_angle.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" - -/* ---------------------------------------------------------------------- */ - -AtomAngle::AtomAngle(int narg, char **arg) : Atom(narg, arg) {} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::copy(int i, int j) -{ - int k; - - 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]; - - molecule[j] = molecule[i]; - num_bond[j] = num_bond[i]; - num_angle[j] = num_angle[i]; - nspecial[j][0] = nspecial[i][0]; - nspecial[j][1] = nspecial[i][1]; - nspecial[j][2] = nspecial[i][2]; - - for (k = 0; k < num_bond[j]; k++) { - bond_type[j][k] = bond_type[i][k]; - bond_atom[j][k] = bond_atom[i][k]; - } - - for (k = 0; k < num_angle[j]; k++) { - angle_type[j][k] = angle_type[i][k]; - angle_atom1[j][k] = angle_atom1[i][k]; - angle_atom2[j][k] = angle_atom2[i][k]; - angle_atom3[j][k] = angle_atom3[i][k]; - } - - for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - modify->fix[extra_grow[iextra]]->copy_arrays(i,j); -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::pack_comm(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::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]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::pack_border(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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++] = molecule[j]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - buf[m++] = tag[j]; - buf[m++] = type[j]; - buf[m++] = mask[j]; - buf[m++] = molecule[j]; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomAngle::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 (buf[m++]); - type[i] = static_cast (buf[m++]); - mask[i] = static_cast (buf[m++]); - molecule[i] = static_cast (buf[m++]); - } -} - -/* ---------------------------------------------------------------------- - pack all atom quantities for shipping to another proc - xyz must be 1st 3 values, so that comm::exchange can test on them -------------------------------------------------------------------------- */ - -int AtomAngle::pack_exchange(int i, double *buf) -{ - int k; - - 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++] = molecule[i]; - - buf[m++] = num_bond[i]; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = bond_type[i][k]; - buf[m++] = bond_atom[i][k]; - } - - buf[m++] = num_angle[i]; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = angle_type[i][k]; - buf[m++] = angle_atom1[i][k]; - buf[m++] = angle_atom2[i][k]; - buf[m++] = angle_atom3[i][k]; - } - - buf[m++] = nspecial[i][0]; - buf[m++] = nspecial[i][1]; - buf[m++] = nspecial[i][2]; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->pack_exchange(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomAngle::unpack_exchange(double *buf) -{ - int k; - if (nlocal == nmax) grow(0); - - int m = 1; - x[nlocal][0] = buf[m++]; - x[nlocal][1] = buf[m++]; - x[nlocal][2] = buf[m++]; - tag[nlocal] = static_cast (buf[m++]); - type[nlocal] = static_cast (buf[m++]); - mask[nlocal] = static_cast (buf[m++]); - image[nlocal] = static_cast (buf[m++]); - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = static_cast (buf[m++]); - - num_bond[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = static_cast (buf[m++]); - bond_atom[nlocal][k] = static_cast (buf[m++]); - } - - num_angle[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = static_cast (buf[m++]); - angle_atom1[nlocal][k] = static_cast (buf[m++]); - angle_atom2[nlocal][k] = static_cast (buf[m++]); - angle_atom3[nlocal][k] = static_cast (buf[m++]); - } - - nspecial[nlocal][0] = static_cast (buf[m++]); - nspecial[nlocal][1] = static_cast (buf[m++]); - nspecial[nlocal][2] = static_cast (buf[m++]); - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = static_cast (buf[m++]); - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->unpack_exchange(nlocal,&buf[m]); - - nlocal++; - return m; -} diff --git a/src/atom_angle.h b/src/atom_angle.h deleted file mode 100644 index a395c577a8..0000000000 --- a/src/atom_angle.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_ANGLE_H -#define ATOM_ANGLE_H - -#include "atom.h" - -class AtomAngle : public Atom { - public: - AtomAngle(int, char **); - ~AtomAngle() {} - void copy(int, int); - void pack_comm(int, int *, double *, int *); - void unpack_comm(int, int, double *); - void pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - void pack_border(int, int *, double *, int *); - void unpack_border(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); -}; - -#endif diff --git a/src/atom_bond.cpp b/src/atom_bond.cpp deleted file mode 100644 index fe3c5fe82e..0000000000 --- a/src/atom_bond.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "atom_bond.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" - -/* ---------------------------------------------------------------------- */ - -AtomBond::AtomBond(int narg, char **arg) : Atom(narg, arg) {} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::copy(int i, int j) -{ - int k; - - 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]; - - molecule[j] = molecule[i]; - num_bond[j] = num_bond[i]; - nspecial[j][0] = nspecial[i][0]; - nspecial[j][1] = nspecial[i][1]; - nspecial[j][2] = nspecial[i][2]; - - for (k = 0; k < num_bond[j]; k++) { - bond_type[j][k] = bond_type[i][k]; - bond_atom[j][k] = bond_atom[i][k]; - } - - for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - modify->fix[extra_grow[iextra]]->copy_arrays(i,j); -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::pack_comm(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::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]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::pack_border(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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++] = molecule[j]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - buf[m++] = tag[j]; - buf[m++] = type[j]; - buf[m++] = mask[j]; - buf[m++] = molecule[j]; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomBond::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 (buf[m++]); - type[i] = static_cast (buf[m++]); - mask[i] = static_cast (buf[m++]); - molecule[i] = static_cast (buf[m++]); - } -} - -/* ---------------------------------------------------------------------- - pack all atom quantities for shipping to another proc - xyz must be 1st 3 values, so that comm::exchange can test on them -------------------------------------------------------------------------- */ - -int AtomBond::pack_exchange(int i, double *buf) -{ - int k; - - 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++] = molecule[i]; - - buf[m++] = num_bond[i]; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = bond_type[i][k]; - buf[m++] = bond_atom[i][k]; - } - - buf[m++] = nspecial[i][0]; - buf[m++] = nspecial[i][1]; - buf[m++] = nspecial[i][2]; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->pack_exchange(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomBond::unpack_exchange(double *buf) -{ - int k; - if (nlocal == nmax) grow(0); - - int m = 1; - x[nlocal][0] = buf[m++]; - x[nlocal][1] = buf[m++]; - x[nlocal][2] = buf[m++]; - tag[nlocal] = static_cast (buf[m++]); - type[nlocal] = static_cast (buf[m++]); - mask[nlocal] = static_cast (buf[m++]); - image[nlocal] = static_cast (buf[m++]); - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = static_cast (buf[m++]); - - num_bond[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = static_cast (buf[m++]); - bond_atom[nlocal][k] = static_cast (buf[m++]); - } - - nspecial[nlocal][0] = static_cast (buf[m++]); - nspecial[nlocal][1] = static_cast (buf[m++]); - nspecial[nlocal][2] = static_cast (buf[m++]); - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = static_cast (buf[m++]); - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->unpack_exchange(nlocal,&buf[m]); - - nlocal++; - return m; -} diff --git a/src/atom_bond.h b/src/atom_bond.h deleted file mode 100644 index f44f7d073f..0000000000 --- a/src/atom_bond.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_BOND_H -#define ATOM_BOND_H - -#include "atom.h" - -class AtomBond : public Atom { - public: - AtomBond(int, char **); - ~AtomBond() {} - void copy(int, int); - void pack_comm(int, int *, double *, int *); - void unpack_comm(int, int, double *); - void pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - void pack_border(int, int *, double *, int *); - void unpack_border(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); -}; - -#endif diff --git a/src/atom_full.cpp b/src/atom_full.cpp deleted file mode 100644 index 935108e770..0000000000 --- a/src/atom_full.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "atom_full.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" - -/* ---------------------------------------------------------------------- */ - -AtomFull::AtomFull(int narg, char **arg) : Atom(narg, arg) {} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::copy(int i, int j) -{ - int k; - - 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]; - - molecule[j] = molecule[i]; - num_bond[j] = num_bond[i]; - num_angle[j] = num_angle[i]; - num_dihedral[j] = num_dihedral[i]; - num_improper[j] = num_improper[i]; - nspecial[j][0] = nspecial[i][0]; - nspecial[j][1] = nspecial[i][1]; - nspecial[j][2] = nspecial[i][2]; - - for (k = 0; k < num_bond[j]; k++) { - bond_type[j][k] = bond_type[i][k]; - bond_atom[j][k] = bond_atom[i][k]; - } - - for (k = 0; k < num_angle[j]; k++) { - angle_type[j][k] = angle_type[i][k]; - angle_atom1[j][k] = angle_atom1[i][k]; - angle_atom2[j][k] = angle_atom2[i][k]; - angle_atom3[j][k] = angle_atom3[i][k]; - } - - for (k = 0; k < num_dihedral[j]; k++) { - dihedral_type[j][k] = dihedral_type[i][k]; - dihedral_atom1[j][k] = dihedral_atom1[i][k]; - dihedral_atom2[j][k] = dihedral_atom2[i][k]; - dihedral_atom3[j][k] = dihedral_atom3[i][k]; - dihedral_atom4[j][k] = dihedral_atom4[i][k]; - } - - for (k = 0; k < num_improper[j]; k++) { - improper_type[j][k] = improper_type[i][k]; - improper_atom1[j][k] = improper_atom1[i][k]; - improper_atom2[j][k] = improper_atom2[i][k]; - improper_atom3[j][k] = improper_atom3[i][k]; - improper_atom4[j][k] = improper_atom4[i][k]; - } - - for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - modify->fix[extra_grow[iextra]]->copy_arrays(i,j); -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::pack_comm(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::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]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::pack_border(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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++] = molecule[j]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - buf[m++] = tag[j]; - buf[m++] = type[j]; - buf[m++] = mask[j]; - buf[m++] = q[j]; - buf[m++] = molecule[j]; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomFull::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 (buf[m++]); - type[i] = static_cast (buf[m++]); - mask[i] = static_cast (buf[m++]); - q[i] = buf[m++]; - molecule[i] = static_cast (buf[m++]); - } -} - -/* ---------------------------------------------------------------------- - pack all atom quantities for shipping to another proc - xyz must be 1st 3 values, so that comm::exchange can test on them -------------------------------------------------------------------------- */ - -int AtomFull::pack_exchange(int i, double *buf) -{ - int k; - - 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++] = molecule[i]; - - buf[m++] = num_bond[i]; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = bond_type[i][k]; - buf[m++] = bond_atom[i][k]; - } - - buf[m++] = num_angle[i]; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = angle_type[i][k]; - buf[m++] = angle_atom1[i][k]; - buf[m++] = angle_atom2[i][k]; - buf[m++] = angle_atom3[i][k]; - } - - buf[m++] = num_dihedral[i]; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = dihedral_type[i][k]; - buf[m++] = dihedral_atom1[i][k]; - buf[m++] = dihedral_atom2[i][k]; - buf[m++] = dihedral_atom3[i][k]; - buf[m++] = dihedral_atom4[i][k]; - } - - buf[m++] = num_improper[i]; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = improper_type[i][k]; - buf[m++] = improper_atom1[i][k]; - buf[m++] = improper_atom2[i][k]; - buf[m++] = improper_atom3[i][k]; - buf[m++] = improper_atom4[i][k]; - } - - buf[m++] = nspecial[i][0]; - buf[m++] = nspecial[i][1]; - buf[m++] = nspecial[i][2]; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->pack_exchange(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomFull::unpack_exchange(double *buf) -{ - int k; - if (nlocal == nmax) grow(0); - - int m = 1; - x[nlocal][0] = buf[m++]; - x[nlocal][1] = buf[m++]; - x[nlocal][2] = buf[m++]; - tag[nlocal] = static_cast (buf[m++]); - type[nlocal] = static_cast (buf[m++]); - mask[nlocal] = static_cast (buf[m++]); - image[nlocal] = static_cast (buf[m++]); - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - q[nlocal] = buf[m++]; - - molecule[nlocal] = static_cast (buf[m++]); - - num_bond[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = static_cast (buf[m++]); - bond_atom[nlocal][k] = static_cast (buf[m++]); - } - - num_angle[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = static_cast (buf[m++]); - angle_atom1[nlocal][k] = static_cast (buf[m++]); - angle_atom2[nlocal][k] = static_cast (buf[m++]); - angle_atom3[nlocal][k] = static_cast (buf[m++]); - } - - num_dihedral[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = static_cast (buf[m++]); - dihedral_atom1[nlocal][k] = static_cast (buf[m++]); - dihedral_atom2[nlocal][k] = static_cast (buf[m++]); - dihedral_atom3[nlocal][k] = static_cast (buf[m++]); - dihedral_atom4[nlocal][k] = static_cast (buf[m++]); - } - - num_improper[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = static_cast (buf[m++]); - improper_atom1[nlocal][k] = static_cast (buf[m++]); - improper_atom2[nlocal][k] = static_cast (buf[m++]); - improper_atom3[nlocal][k] = static_cast (buf[m++]); - improper_atom4[nlocal][k] = static_cast (buf[m++]); - } - - nspecial[nlocal][0] = static_cast (buf[m++]); - nspecial[nlocal][1] = static_cast (buf[m++]); - nspecial[nlocal][2] = static_cast (buf[m++]); - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = static_cast (buf[m++]); - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->unpack_exchange(nlocal,&buf[m]); - - nlocal++; - return m; -} diff --git a/src/atom_full.h b/src/atom_full.h deleted file mode 100644 index 71c5a806db..0000000000 --- a/src/atom_full.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_FULL_H -#define ATOM_FULL_H - -#include "atom.h" - -class AtomFull : public Atom { - public: - AtomFull(int, char **); - ~AtomFull() {} - void copy(int, int); - void pack_comm(int, int *, double *, int *); - void unpack_comm(int, int, double *); - void pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - void pack_border(int, int *, double *, int *); - void unpack_border(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); -}; - -#endif diff --git a/src/atom_molecular.cpp b/src/atom_molecular.cpp deleted file mode 100644 index 5c18061930..0000000000 --- a/src/atom_molecular.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "atom_molecular.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" - -/* ---------------------------------------------------------------------- */ - -AtomMolecular::AtomMolecular(int narg, char **arg) : Atom(narg, arg) {} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::copy(int i, int j) -{ - int k; - - 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]; - - molecule[j] = molecule[i]; - num_bond[j] = num_bond[i]; - num_angle[j] = num_angle[i]; - num_dihedral[j] = num_dihedral[i]; - num_improper[j] = num_improper[i]; - nspecial[j][0] = nspecial[i][0]; - nspecial[j][1] = nspecial[i][1]; - nspecial[j][2] = nspecial[i][2]; - - for (k = 0; k < num_bond[j]; k++) { - bond_type[j][k] = bond_type[i][k]; - bond_atom[j][k] = bond_atom[i][k]; - } - - for (k = 0; k < num_angle[j]; k++) { - angle_type[j][k] = angle_type[i][k]; - angle_atom1[j][k] = angle_atom1[i][k]; - angle_atom2[j][k] = angle_atom2[i][k]; - angle_atom3[j][k] = angle_atom3[i][k]; - } - - for (k = 0; k < num_dihedral[j]; k++) { - dihedral_type[j][k] = dihedral_type[i][k]; - dihedral_atom1[j][k] = dihedral_atom1[i][k]; - dihedral_atom2[j][k] = dihedral_atom2[i][k]; - dihedral_atom3[j][k] = dihedral_atom3[i][k]; - dihedral_atom4[j][k] = dihedral_atom4[i][k]; - } - - for (k = 0; k < num_improper[j]; k++) { - improper_type[j][k] = improper_type[i][k]; - improper_atom1[j][k] = improper_atom1[i][k]; - improper_atom2[j][k] = improper_atom2[i][k]; - improper_atom3[j][k] = improper_atom3[i][k]; - improper_atom4[j][k] = improper_atom4[i][k]; - } - - for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - modify->fix[extra_grow[iextra]]->copy_arrays(i,j); -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::pack_comm(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::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]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::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++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::pack_border(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - if (pbc_flags[0] == 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++] = molecule[j]; - } - } else { - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = x[j][0] + pbc_flags[1]*xprd; - buf[m++] = x[j][1] + pbc_flags[2]*yprd; - buf[m++] = x[j][2] + pbc_flags[3]*zprd; - buf[m++] = tag[j]; - buf[m++] = type[j]; - buf[m++] = mask[j]; - buf[m++] = molecule[j]; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomMolecular::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 (buf[m++]); - type[i] = static_cast (buf[m++]); - mask[i] = static_cast (buf[m++]); - molecule[i] = static_cast (buf[m++]); - } -} - -/* ---------------------------------------------------------------------- - pack all atom quantities for shipping to another proc - xyz must be 1st 3 values, so that comm::exchange can test on them -------------------------------------------------------------------------- */ - -int AtomMolecular::pack_exchange(int i, double *buf) -{ - int k; - - 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++] = molecule[i]; - - buf[m++] = num_bond[i]; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = bond_type[i][k]; - buf[m++] = bond_atom[i][k]; - } - - buf[m++] = num_angle[i]; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = angle_type[i][k]; - buf[m++] = angle_atom1[i][k]; - buf[m++] = angle_atom2[i][k]; - buf[m++] = angle_atom3[i][k]; - } - - buf[m++] = num_dihedral[i]; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = dihedral_type[i][k]; - buf[m++] = dihedral_atom1[i][k]; - buf[m++] = dihedral_atom2[i][k]; - buf[m++] = dihedral_atom3[i][k]; - buf[m++] = dihedral_atom4[i][k]; - } - - buf[m++] = num_improper[i]; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = improper_type[i][k]; - buf[m++] = improper_atom1[i][k]; - buf[m++] = improper_atom2[i][k]; - buf[m++] = improper_atom3[i][k]; - buf[m++] = improper_atom4[i][k]; - } - - buf[m++] = nspecial[i][0]; - buf[m++] = nspecial[i][1]; - buf[m++] = nspecial[i][2]; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->pack_exchange(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomMolecular::unpack_exchange(double *buf) -{ - int k; - if (nlocal == nmax) grow(0); - - int m = 1; - x[nlocal][0] = buf[m++]; - x[nlocal][1] = buf[m++]; - x[nlocal][2] = buf[m++]; - tag[nlocal] = static_cast (buf[m++]); - type[nlocal] = static_cast (buf[m++]); - mask[nlocal] = static_cast (buf[m++]); - image[nlocal] = static_cast (buf[m++]); - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = static_cast (buf[m++]); - - num_bond[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = static_cast (buf[m++]); - bond_atom[nlocal][k] = static_cast (buf[m++]); - } - - num_angle[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = static_cast (buf[m++]); - angle_atom1[nlocal][k] = static_cast (buf[m++]); - angle_atom2[nlocal][k] = static_cast (buf[m++]); - angle_atom3[nlocal][k] = static_cast (buf[m++]); - } - - num_dihedral[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = static_cast (buf[m++]); - dihedral_atom1[nlocal][k] = static_cast (buf[m++]); - dihedral_atom2[nlocal][k] = static_cast (buf[m++]); - dihedral_atom3[nlocal][k] = static_cast (buf[m++]); - dihedral_atom4[nlocal][k] = static_cast (buf[m++]); - } - - num_improper[nlocal] = static_cast (buf[m++]); - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = static_cast (buf[m++]); - improper_atom1[nlocal][k] = static_cast (buf[m++]); - improper_atom2[nlocal][k] = static_cast (buf[m++]); - improper_atom3[nlocal][k] = static_cast (buf[m++]); - improper_atom4[nlocal][k] = static_cast (buf[m++]); - } - - nspecial[nlocal][0] = static_cast (buf[m++]); - nspecial[nlocal][1] = static_cast (buf[m++]); - nspecial[nlocal][2] = static_cast (buf[m++]); - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = static_cast (buf[m++]); - - if (nextra_grow) - for (int iextra = 0; iextra < nextra_grow; iextra++) - m += modify->fix[extra_grow[iextra]]->unpack_exchange(nlocal,&buf[m]); - - nlocal++; - return m; -} diff --git a/src/atom_molecular.h b/src/atom_molecular.h deleted file mode 100644 index f31caf8926..0000000000 --- a/src/atom_molecular.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_MOLECULAR_H -#define ATOM_MOLECULAR_H - -#include "atom.h" - -class AtomMolecular : public Atom { - public: - AtomMolecular(int, char **); - ~AtomMolecular() {} - void copy(int, int); - void pack_comm(int, int *, double *, int *); - void unpack_comm(int, int, double *); - void pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - void pack_border(int, int *, double *, int *); - void unpack_border(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); -}; - -#endif diff --git a/src/bond.cpp b/src/bond.cpp deleted file mode 100644 index c126658063..0000000000 --- a/src/bond.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "string.h" -#include "bond.h" -#include "atom.h" -#include "error.h" - -/* ----------------------------------------------------------------------- - set bond contribution to Vdwl energy to 0.0 - a particular bond style can override this -------------------------------------------------------------------------- */ - -Bond::Bond() -{ - allocated = 0; - eng_vdwl = 0.0; -} - -/* ---------------------------------------------------------------------- - check if all coeffs are set -------------------------------------------------------------------------- */ - -void Bond::init() -{ - if (!allocated) error->all("Bond coeffs are not set"); - for (int i = 1; i <= atom->nbondtypes; i++) - if (setflag[i] == 0) error->all("All bond coeffs are not set"); - init_style(); -} diff --git a/src/bond_fene.cpp b/src/bond_fene.cpp deleted file mode 100644 index 0c516341a4..0000000000 --- a/src/bond_fene.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "bond_fene.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "update.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -BondFENE::BondFENE() -{ - TWO_1_3 = pow(2.0,(1.0/3.0)); -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondFENE::~BondFENE() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(r0); - memory->sfree(epsilon); - memory->sfree(sigma); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondFENE::compute(int eflag, int vflag) -{ - int i1,i2,n,type,factor; - double delx,dely,delz,rsq,r0sq,rlogarg,fforce,sr2,sr6,rfactor; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5*factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - // force from log term - - rsq = delx*delx + dely*dely + delz*delz; - r0sq = r0[type] * r0[type]; - rlogarg = 1.0 - rsq/r0sq; - - // if r -> r0, then rlogarg < 0.0 which is an error - // issue a warning and reset rlogarg = epsilon - // if r > 2*r0 something serious is wrong, abort - - if (rlogarg < 0.1) { - char str[128]; - sprintf(str,"FENE bond too long: %d %d %d %g", - update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq)); - error->warning(str); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); - rlogarg = 0.1; - } - - fforce = -k[type]/rlogarg; - - // force from LJ term - - if (rsq < TWO_1_3*sigma[type]*sigma[type]) { - sr2 = sigma[type]*sigma[type]/rsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq; - } - - // energy - - if (eflag) { - energy -= 0.5*rfactor * k[type]*r0sq*log(rlogarg); - if (rsq < TWO_1_3*sigma[type]*sigma[type]) - energy += rfactor * (4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]); - } - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor * delx*delx*fforce; - virial[1] += rfactor * dely*dely*fforce; - virial[2] += rfactor * delz*delz*fforce; - virial[3] += rfactor * delx*dely*fforce; - virial[4] += rfactor * delx*delz*fforce; - virial[5] += rfactor * dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondFENE::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k"); - r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0"); - epsilon = (double *) memory->smalloc((n+1)*sizeof(double),"bond:epsilon"); - sigma = (double *) memory->smalloc((n+1)*sizeof(double),"bond:sigma"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void BondFENE::coeff(int narg, char **arg) -{ - if (narg != 5) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double k_one = atof(arg[1]); - double r0_one = atof(arg[2]); - double epsilon_one = atof(arg[3]); - double sigma_one = atof(arg[4]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - r0[i] = r0_one; - epsilon[i] = epsilon_one; - sigma[i] = sigma_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double BondFENE::equilibrium_distance(int i) -{ - return 0.97*sigma[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void BondFENE::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&sigma[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void BondFENE::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nbondtypes,fp); - fread(&r0[1],sizeof(double),atom->nbondtypes,fp); - fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fread(&sigma[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&sigma[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -void BondFENE::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r0sq = r0[type] * r0[type]; - double rlogarg = 1.0 - rsq/r0sq; - - // if r -> r0, then rlogarg < 0.0 which is an error - // issue a warning and reset rlogarg = epsilon - // if r > 2*r0 something serious is wrong, abort - - if (rlogarg < 0.1) { - char str[128]; - sprintf(str,"FENE bond too long: %d %g",update->ntimestep,sqrt(rsq)); - error->warning(str); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); - rlogarg = 0.1; - } - - fforce = -k[type]/rlogarg; - - // force from LJ term - - double sr2,sr6; - if (rsq < TWO_1_3*sigma[type]*sigma[type]) { - sr2 = sigma[type]*sigma[type]/rsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq; - } - - // energy - - if (eflag) { - eng = -0.5*rfactor * k[type]*r0sq*log(rlogarg); - if (rsq < TWO_1_3*sigma[type]*sigma[type]) - eng += rfactor * (4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]); - } -} diff --git a/src/bond_fene.h b/src/bond_fene.h deleted file mode 100644 index 43c997f92d..0000000000 --- a/src/bond_fene.h +++ /dev/null @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 BOND_FENE_H -#define BOND_FENE_H - -#include "stdio.h" -#include "bond.h" - -class BondFENE : public Bond { - public: - BondFENE(); - ~BondFENE(); - void compute(int, int); - void coeff(int, char **); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double TWO_1_3; - double *k,*r0,*epsilon,*sigma; - - void allocate(); -}; - -#endif diff --git a/src/bond_fene_expand.cpp b/src/bond_fene_expand.cpp deleted file mode 100644 index 801ae110f8..0000000000 --- a/src/bond_fene_expand.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* ---------------------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -// FENE bond potential, with repulsive LJ, with shift - -#include "math.h" -#include "stdlib.h" -#include "bond_fene_expand.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "update.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- - set all global defaults -------------------------------------------------------------------------- */ - -BondFENEExpand::BondFENEExpand() -{ - TWO_1_3 = pow(2.0,(1.0/3.0)); -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondFENEExpand::~BondFENEExpand() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(r0); - memory->sfree(epsilon); - memory->sfree(sigma); - memory->sfree(shift); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondFENEExpand::compute(int eflag, int vflag) -{ - int i1,i2,n,type,factor; - double delx,dely,delz,rsq,r0sq,rlogarg,fforce,sr2,sr6,rfactor; - double r,rshift,rshiftsq; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5*factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - // force from log term - - rsq = delx*delx + dely*dely + delz*delz; - r = sqrt(rsq); - rshift = r - shift[type]; - rshiftsq = rshift*rshift; - r0sq = r0[type] * r0[type]; - rlogarg = 1.0 - rshiftsq/r0sq; - - // if r -> r0, then rlogarg < 0.0 which is an error - // issue a warning and reset rlogarg = epsilon - // if r > 2*r0 something serious is wrong, abort - - if (rlogarg < 0.1) { - char str[128]; - sprintf(str,"FENE bond too long: %d %d %d %g", - update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq)); - error->warning(str); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); - rlogarg = 0.1; - } - - fforce = -k[type]*rshift/rlogarg/r; - - // force from LJ term - - if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) { - sr2 = sigma[type]*sigma[type]/rshiftsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r; - } - - // energy - - if (eflag) { - energy -= 0.5*rfactor * k[type]*r0sq*log(rlogarg); - if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) - energy += 0.5*factor * - (4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]); - } - - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor * delx*delx*fforce; - virial[1] += rfactor * dely*dely*fforce; - virial[2] += rfactor * delz*delz*fforce; - virial[3] += rfactor * delx*dely*fforce; - virial[4] += rfactor * delx*delz*fforce; - virial[5] += rfactor * dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondFENEExpand::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k"); - r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0"); - epsilon = (double *) memory->smalloc((n+1)*sizeof(double),"bond:epsilon"); - sigma = (double *) memory->smalloc((n+1)*sizeof(double),"bond:sigma"); - shift = (double *) memory->smalloc((n+1)*sizeof(double),"bond:shift"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void BondFENEExpand::coeff(int narg, char **arg) -{ - if (narg != 6) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double k_one = atof(arg[1]); - double r0_one = atof(arg[2]); - double epsilon_one = atof(arg[3]); - double sigma_one = atof(arg[4]); - double shift_one = atof(arg[5]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - r0[i] = r0_one; - epsilon[i] = epsilon_one; - sigma[i] = sigma_one; - shift[i] = shift_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double BondFENEExpand::equilibrium_distance(int i) -{ - return 0.97*sigma[i] + shift[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void BondFENEExpand::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&sigma[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&shift[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void BondFENEExpand::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nbondtypes,fp); - fread(&r0[1],sizeof(double),atom->nbondtypes,fp); - fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fread(&sigma[1],sizeof(double),atom->nbondtypes,fp); - fread(&shift[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&sigma[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&shift[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -void BondFENEExpand::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r = sqrt(rsq); - double rshift = r - shift[type]; - double rshiftsq = rshift*rshift; - double r0sq = r0[type] * r0[type]; - double rlogarg = 1.0 - rshiftsq/r0sq; - - // if r -> r0, then rlogarg < 0.0 which is an error - // issue a warning and reset rlogarg = epsilon - // if r > 2*r0 something serious is wrong, abort - - if (rlogarg < 0.1) { - char str[128]; - sprintf(str,"FENE bond too long: %d %g",update->ntimestep,sqrt(rsq)); - error->warning(str); - if (rlogarg <= -3.0) error->one("Bad FENE bond"); - rlogarg = 0.1; - } - - fforce = -k[type]*rshift/rlogarg/r; - - // force from LJ term - - double sr2,sr6; - if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) { - sr2 = sigma[type]*sigma[type]/rshiftsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r; - } - - // energy - - if (eflag) { - eng = -0.5*rfactor * k[type]*r0sq*log(rlogarg); - if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) - eng += rfactor * (4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]); - } -} diff --git a/src/bond_fene_expand.h b/src/bond_fene_expand.h deleted file mode 100644 index 0e7167b1c6..0000000000 --- a/src/bond_fene_expand.h +++ /dev/null @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 BOND_FENE_EXPAND_H -#define BOND_FENE_EXPAND_H - -#include "stdio.h" -#include "bond.h" - -class BondFENEExpand : public Bond { - public: - BondFENEExpand(); - ~BondFENEExpand(); - void compute(int, int); - void coeff(int, char **); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double TWO_1_3; - double *k,*r0,*epsilon,*sigma,*shift; - - void allocate(); -}; - -#endif diff --git a/src/bond_harmonic.cpp b/src/bond_harmonic.cpp deleted file mode 100644 index 4520ec0dfb..0000000000 --- a/src/bond_harmonic.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "bond_harmonic.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondHarmonic::~BondHarmonic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(r0); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondHarmonic::compute(int eflag, int vflag) -{ - int i1,i2,n,type,factor; - double delx,dely,delz,rsq,r,dr,rk,fforce,rfactor; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5 * factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - rsq = delx*delx + dely*dely + delz*delz; - r = sqrt(rsq); - dr = r - r0[type]; - rk = k[type] * dr; - - // force & energy - - if (r > 0.0) fforce = -2.0*rk/r; - else fforce = 0.0; - - if (eflag) energy += rfactor * rk*dr; - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor*delx*delx*fforce; - virial[1] += rfactor*dely*dely*fforce; - virial[2] += rfactor*delz*delz*fforce; - virial[3] += rfactor*delx*dely*fforce; - virial[4] += rfactor*delx*delz*fforce; - virial[5] += rfactor*dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondHarmonic::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k"); - r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more types -------------------------------------------------------------------------- */ - -void BondHarmonic::coeff(int narg, char **arg) -{ - if (narg != 3) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double k_one = atof(arg[1]); - double r0_one = atof(arg[2]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - r0[i] = r0_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- - return an equilbrium bond length -------------------------------------------------------------------------- */ - -double BondHarmonic::equilibrium_distance(int i) -{ - return r0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void BondHarmonic::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void BondHarmonic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nbondtypes,fp); - fread(&r0[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -void BondHarmonic::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r = sqrt(rsq); - double dr = r - r0[type]; - double rk = k[type] * dr; - - // force & energy - - if (r > 0.0) fforce = -2.0*rk/r; - else fforce = 0.0; - if (eflag) eng = rfactor * rk*dr; -} diff --git a/src/bond_harmonic.h b/src/bond_harmonic.h deleted file mode 100644 index 438df27e0b..0000000000 --- a/src/bond_harmonic.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 BOND_HARMONIC_H -#define BOND_HARMONIC_H - -#include "stdio.h" -#include "bond.h" - -class BondHarmonic : public Bond { - public: - BondHarmonic() {} - ~BondHarmonic(); - void compute(int, int); - void coeff(int, char **); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double *k,*r0; - - void allocate(); -}; - -#endif diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp deleted file mode 100644 index ff9f7b4f3f..0000000000 --- a/src/bond_hybrid.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* ----------------------------------------------------------------------- - 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 "bond_hybrid.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define EXTRA 1000 - -/* ---------------------------------------------------------------------- - set all global defaults -------------------------------------------------------------------------- */ - -BondHybrid::BondHybrid() -{ - nstyles = 0; -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondHybrid::~BondHybrid() -{ - if (nstyles) { - for (int i = 0; i < nstyles; i++) delete styles[i]; - delete [] styles; - for (int i = 0; i < nstyles; i++) delete [] keywords[i]; - delete [] keywords; - } - - if (allocated) { - memory->sfree(setflag); - memory->sfree(map); - delete [] nbondlist; - delete [] maxbond; - for (int i = 0; i < nstyles; i++) - memory->destroy_2d_int_array(bondlist[i]); - delete [] bondlist; - } -} - -/* ---------------------------------------------------------------------- */ - -void BondHybrid::compute(int eflag, int vflag) -{ - int i,m,n; - - // save ptrs to original bondlist - - int nbondlist_orig = neighbor->nbondlist; - int **bondlist_orig = neighbor->bondlist; - - // if this is re-neighbor step, create sub-style bondlists - // nbondlist[] = length of each sub-style list - // realloc sub-style bondlist if necessary - // load sub-style bondlist with 3 values from original bondlist - - if (neighbor->ago == 0) { - for (m = 0; m < nstyles; m++) nbondlist[m] = 0; - for (i = 0; i < nbondlist_orig; i++) - nbondlist[map[bondlist_orig[i][2]]]++; - for (m = 0; m < nstyles; m++) { - if (nbondlist[m] > maxbond[m]) { - memory->destroy_2d_int_array(bondlist[m]); - maxbond[m] = nbondlist[m] + EXTRA; - bondlist[m] = (int **) - memory->create_2d_int_array(maxbond[m],3,"bond_hybrid:bondlist"); - } - nbondlist[m] = 0; - } - for (i = 0; i < nbondlist_orig; i++) { - m = map[bondlist_orig[i][2]]; - n = nbondlist[m]; - bondlist[m][n][0] = bondlist_orig[i][0]; - bondlist[m][n][1] = bondlist_orig[i][1]; - bondlist[m][n][2] = bondlist_orig[i][2]; - nbondlist[m]++; - } - } - - // call each sub-style's compute function - // must set neighbor->bondlist to sub-style bondlist before call - // accumulate sub-style energy,virial in hybrid's energy,virial - - energy = 0.0; - eng_vdwl = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - for (m = 0; m < nstyles; m++) { - if (styles[m] == NULL) continue; - neighbor->nbondlist = nbondlist[m]; - neighbor->bondlist = bondlist[m]; - styles[m]->compute(eflag,vflag); - if (eflag) { - energy += styles[m]->energy; - eng_vdwl += styles[m]->eng_vdwl; - } - if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; - } - - // restore ptrs to original bondlist - - neighbor->nbondlist = nbondlist_orig; - neighbor->bondlist = bondlist_orig; -} - -/* ---------------------------------------------------------------------- */ - -void BondHybrid::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - map = (int *) memory->smalloc((n+1)*sizeof(int),"bond:map"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; - - nbondlist = new int[nstyles]; - maxbond = new int[nstyles]; - bondlist = new int**[nstyles]; - for (int m = 0; m < nstyles; m++) maxbond[m] = 0; - for (int m = 0; m < nstyles; m++) bondlist[m] = NULL; -} - -/* ---------------------------------------------------------------------- - create one bond style for each arg in list -------------------------------------------------------------------------- */ - -void BondHybrid::settings(int narg, char **arg) -{ - nstyles = narg; - styles = new Bond*[nstyles]; - keywords = new char*[nstyles]; - - for (int m = 0; m < nstyles; m++) { - for (int i = 0; i < m; i++) - if (strcmp(arg[m],arg[i]) == 0) - error->all("Bond style hybrid cannot use same bond style twice"); - if (strcmp(arg[m],"hybrid") == 0) - error->all("Bond style hybrid cannot have hybrid as an argument"); - styles[m] = force->new_bond(arg[m]); - keywords[m] = new char[strlen(arg[m])+1]; - strcpy(keywords[m],arg[m]); - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one type ----------------------------------------------------------------------- */ - -void BondHybrid::coeff(int narg, char **arg) -{ - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - // 2nd arg = bond style name (harmonic, fene, etc) - - int m; - for (m = 0; m < nstyles; m++) - if (strcmp(arg[1],keywords[m]) == 0) break; - if (m == nstyles) error->all("Bond coeff for hybrid has invalid style"); - - // set low-level coefficients for each bondtype - // replace 2nd arg with i, call coeff() with no 1st arg - // if sub-style is NULL for "none", still set setflag - - for (int i = ilo; i <= ihi; i++) { - sprintf(arg[1],"%d",i); - map[i] = m; - if (styles[m]) styles[m]->coeff(narg-1,&arg[1]); - setflag[i] = 1; - } -} - -/* ---------------------------------------------------------------------- */ - -void BondHybrid::init_style() -{ - for (int m = 0; m < nstyles; m++) - if (styles[m]) styles[m]->init_style(); -} - -/* ---------------------------------------------------------------------- - return an equilbrium bond length -------------------------------------------------------------------------- */ - -double BondHybrid::equilibrium_distance(int i) -{ - return styles[map[i]]->equilibrium_distance(i); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void BondHybrid::write_restart(FILE *fp) -{ - fwrite(&nstyles,sizeof(int),1,fp); - - int n; - for (int m = 0; m < nstyles; m++) { - n = strlen(keywords[m]) + 1; - fwrite(&n,sizeof(int),1,fp); - fwrite(keywords[m],sizeof(char),n,fp); - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void BondHybrid::read_restart(FILE *fp) -{ - allocate(); - - int me = comm->me; - if (me == 0) fread(&nstyles,sizeof(int),1,fp); - MPI_Bcast(&nstyles,1,MPI_INT,0,world); - styles = new Bond*[nstyles]; - keywords = new char*[nstyles]; - - int n; - for (int m = 0; m < nstyles; m++) { - if (me == 0) fread(&n,sizeof(int),1,fp); - MPI_Bcast(&n,1,MPI_INT,0,world); - keywords[m] = new char[n]; - if (me == 0) fread(keywords[m],sizeof(char),n,fp); - MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_bond(keywords[m]); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondHybrid::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - if (styles[map[type]]) - styles[map[type]]->single(type,rsq,i,j,rfactor,eflag,fforce,eng); -} - -/* ---------------------------------------------------------------------- - memory usage -------------------------------------------------------------------------- */ - -int BondHybrid::memory_usage() -{ - int bytes = 0; - for (int m = 0; m < nstyles; m++) bytes += maxbond[m]*3 * sizeof(int); - for (int m = 0; m < nstyles; m++) - if (styles[m]) bytes += styles[m]->memory_usage(); - return bytes; -} diff --git a/src/bond_morse.cpp b/src/bond_morse.cpp deleted file mode 100644 index 5cd83b8a32..0000000000 --- a/src/bond_morse.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Jeff Greathouse (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "bond_morse.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondMorse::~BondMorse() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(d0); - memory->sfree(alpha); - memory->sfree(r0); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondMorse::compute(int eflag, int vflag) -{ - int i1,i2,n,type,factor; - double delx,dely,delz,rsq,r,dr,fforce,rfactor,ralpha; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5 * factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - rsq = delx*delx + dely*dely + delz*delz; - r = sqrt(rsq); - dr = r - r0[type]; - ralpha = exp(-alpha[type]*dr); - - // force & energy - - if (r > 0.0) fforce = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r; - else fforce = 0.0; - - if (eflag) energy += rfactor * d0[type]*(1-ralpha)*(1-ralpha); - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor*delx*delx*fforce; - virial[1] += rfactor*dely*dely*fforce; - virial[2] += rfactor*delz*delz*fforce; - virial[3] += rfactor*delx*dely*fforce; - virial[4] += rfactor*delx*delz*fforce; - virial[5] += rfactor*dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondMorse::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - d0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:d0"); - alpha = (double *) memory->smalloc((n+1)*sizeof(double),"bond:alpha"); - r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void BondMorse::coeff(int narg, char **arg) -{ - if (narg != 4) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double d0_one = atof(arg[1]); - double alpha_one = atof(arg[2]); - double r0_one = atof(arg[3]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - d0[i] = d0_one; - alpha[i] = alpha_one; - r0[i] = r0_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- - return an equilbrium bond length -------------------------------------------------------------------------- */ - -double BondMorse::equilibrium_distance(int i) -{ - return r0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void BondMorse::write_restart(FILE *fp) -{ - fwrite(&d0[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&alpha[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void BondMorse::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&d0[1],sizeof(double),atom->nbondtypes,fp); - fread(&alpha[1],sizeof(double),atom->nbondtypes,fp); - fread(&r0[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&d0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&alpha[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -void BondMorse::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r = sqrt(rsq); - double dr = r - r0[type]; - double ralpha = exp(-alpha[type]*dr); - - // force & energy - - if (r > 0.0) fforce = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r; - else fforce = 0.0; - if (eflag) eng = rfactor * d0[type]*(1-ralpha)*(1-ralpha); -} diff --git a/src/bond_morse.h b/src/bond_morse.h deleted file mode 100644 index 9ac1d4cbf3..0000000000 --- a/src/bond_morse.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 BOND_MORSE_H -#define BOND_MORSE_H - -#include "stdio.h" -#include "bond.h" - -class BondMorse : public Bond { - public: - BondMorse() {} - ~BondMorse(); - void compute(int, int); - void coeff(int, char **); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double *d0,*alpha,*r0; - - void allocate(); -}; - -#endif diff --git a/src/bond_nonlinear.cpp b/src/bond_nonlinear.cpp deleted file mode 100644 index f39e61f665..0000000000 --- a/src/bond_nonlinear.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "bond_nonlinear.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondNonlinear::~BondNonlinear() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(epsilon); - memory->sfree(r0); - memory->sfree(lamda); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondNonlinear::compute(int eflag, int vflag) -{ - int i1,i2,n,type,factor; - double delx,dely,delz,rsq,r,dr,drsq,lamdasq,denom,denomsq,fforce,rfactor; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5 * factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - rsq = delx*delx + dely*dely + delz*delz; - r = sqrt(rsq); - dr = r - r0[type]; - drsq = dr*dr; - lamdasq = lamda[type]*lamda[type]; - denom = lamdasq - drsq; - denomsq = denom*denom; - - // force & energy - - fforce = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq; - if (eflag) energy += rfactor * epsilon[type] * drsq / denom; - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor*delx*delx*fforce; - virial[1] += rfactor*dely*dely*fforce; - virial[2] += rfactor*delz*delz*fforce; - virial[3] += rfactor*delx*dely*fforce; - virial[4] += rfactor*delx*delz*fforce; - virial[5] += rfactor*dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondNonlinear::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - epsilon = (double *) memory->smalloc((n+1)*sizeof(double),"bond:epsilon"); - r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0"); - lamda = (double *) memory->smalloc((n+1)*sizeof(double),"bond:lamda"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void BondNonlinear::coeff(int narg, char **arg) -{ - if (narg != 4) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double epsilon_one = atof(arg[1]); - double r0_one = atof(arg[2]); - double lamda_one = atof(arg[3]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - epsilon[i] = epsilon_one; - r0[i] = r0_one; - lamda[i] = lamda_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -double BondNonlinear::equilibrium_distance(int i) -{ - return r0[i]; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void BondNonlinear::write_restart(FILE *fp) -{ - fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&lamda[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void BondNonlinear::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp); - fread(&r0[1],sizeof(double),atom->nbondtypes,fp); - fread(&lamda[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&lamda[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - -/* ---------------------------------------------------------------------- */ - -void BondNonlinear::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r = sqrt(rsq); - double dr = r - r0[type]; - double drsq = dr*dr; - double lamdasq = lamda[type]*lamda[type]; - double denom = lamdasq - drsq; - double denomsq = denom*denom; - - // force & energy - - fforce = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq; - if (eflag) eng = rfactor * epsilon[type] * drsq / denom; -} diff --git a/src/bond_nonlinear.h b/src/bond_nonlinear.h deleted file mode 100644 index 952ddf1661..0000000000 --- a/src/bond_nonlinear.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 BOND_NONLINEAR_H -#define BOND_NONLINEAR_H - -#include "stdio.h" -#include "bond.h" - -class BondNonlinear : public Bond { - public: - BondNonlinear() {} - ~BondNonlinear(); - void compute(int, int); - void coeff(int, char **); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double *epsilon,*r0,*lamda; - - void allocate(); -}; - -#endif diff --git a/src/bond_quartic.cpp b/src/bond_quartic.cpp deleted file mode 100755 index 6889837bdd..0000000000 --- a/src/bond_quartic.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Chris Lorenz and Mark Stevens (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "bond_quartic.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "update.h" -#include "force.h" -#include "pair.h" -#include "memory.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -BondQuartic::BondQuartic() -{ - TWO_1_3 = pow(2.0,(1.0/3.0)); -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -BondQuartic::~BondQuartic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(b1); - memory->sfree(b2); - memory->sfree(rc); - memory->sfree(u0); - } -} - -/* ---------------------------------------------------------------------- */ - -void BondQuartic::compute(int eflag, int vflag) -{ - int i1,i2,n,m,type,factor,itype,jtype; - double delx,dely,delz,r,rsq,dr,r2,ra,rb,fforce,sr2,sr6,rfactor; - Pair::One one; - - energy = 0.0; - eng_vdwl = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **cutsq = force->pair->cutsq; - double **x = atom->x; - double **f = atom->f; - int **bondlist = neighbor->bondlist; - int nbondlist = neighbor->nbondlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nbondlist; n++) { - - // skip bond if already broken - - if (bondlist[n][2] <= 0) continue; - - i1 = bondlist[n][0]; - i2 = bondlist[n][1]; - type = bondlist[n][2]; - - if (newton_bond) factor = 2; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - } - rfactor = 0.5*factor; - - delx = x[i1][0] - x[i2][0]; - dely = x[i1][1] - x[i2][1]; - delz = x[i1][2] - x[i2][2]; - domain->minimum_image(&delx,&dely,&delz); - - rsq = delx*delx + dely*dely + delz*delz; - - // if bond breaks, set type to 0 - // both in temporary bondlist and permanent bond_type - // if this proc owns both atoms, - // negate bond_type twice if other atom stores it - // if other proc owns 2nd atom, other proc will also break bond - - if (rsq > rc[type]*rc[type]) { - bondlist[n][2] = 0; - for (m = 0; m < atom->num_bond[i1]; m++) - if (atom->bond_atom[i1][m] == atom->tag[i2]) - atom->bond_type[i1][m] = 0; - if (i2 < atom->nlocal) - for (m = 0; m < atom->num_bond[i2]; m++) - if (atom->bond_atom[i2][m] == atom->tag[i1]) - atom->bond_type[i2][m] = 0; - continue; - } - - // subtract out pairwise contribution from 2 atoms via pair->single() - // required since special_bond = 1,1,1 - - itype = atom->type[i1]; - jtype = atom->type[i2]; - - if (rsq < cutsq[itype][jtype]) { - force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,eflag,one); - fforce = -one.fforce; - if (eflag) eng_vdwl -= one.eng_vdwl + one.eng_coul; - } else fforce = 0.0; - - // quartic bond - // 1st portion is from quartic term - // 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0 - - r = sqrt(rsq); - dr = r - rc[type]; - r2 = dr*dr; - ra = dr - b1[type]; - rb = dr - b2[type]; - fforce += -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb); - - if (rsq < TWO_1_3) { - sr2 = 1.0/rsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*sr6*(sr6-0.5)/rsq; - } - - if (eflag) { - energy += rfactor*(k[type]*r2*ra*rb + u0[type]); - if (rsq < TWO_1_3) energy += rfactor * (4.0*sr6*(sr6-1.0) + 1.0); - } - - // apply force to each of 2 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] -= delx*fforce; - f[i2][1] -= dely*fforce; - f[i2][2] -= delz*fforce; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor * delx*delx*fforce; - virial[1] += rfactor * dely*dely*fforce; - virial[2] += rfactor * delz*delz*fforce; - virial[3] += rfactor * delx*dely*fforce; - virial[4] += rfactor * delx*delz*fforce; - virial[5] += rfactor * dely*delz*fforce; - } - } -} - -/* ---------------------------------------------------------------------- */ - -void BondQuartic::allocate() -{ - allocated = 1; - int n = atom->nbondtypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k"); - b1 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:b1"); - b2 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:b2"); - rc = (double *) memory->smalloc((n+1)*sizeof(double),"bond:rc"); - u0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:u0"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more types -------------------------------------------------------------------------- */ - -void BondQuartic::coeff(int narg, char **arg) -{ - if (narg != 6) error->all("Incorrect args for bond coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nbondtypes,ilo,ihi); - - double k_one = atof(arg[1]); - double b1_one = atof(arg[2]); - double b2_one = atof(arg[3]); - double rc_one = atof(arg[4]); - double u0_one = atof(arg[5]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - b1[i] = b1_one; - b2[i] = b2_one; - rc[i] = rc_one; - u0[i] = u0_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for bond coefficients"); -} - -/* ---------------------------------------------------------------------- - check if pair defined and special_bond settings are valid -------------------------------------------------------------------------- */ - -void BondQuartic::init_style() -{ - if (force->pair == NULL || force->pair->single_enable == 0) - error->all("Pair style does not support bond_style quartic"); - if (force->angle) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); - if (force->dihedral) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); - if (force->improper) - error->all("Bond style quartic cannot be used with 3,4-body interactions"); - - // special bonds must be 1 1 1 - - if (force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 || - force->special_lj[3] != 1.0) - error->all("Must use special bonds = 1,1,1 with bond style quartic"); -} - -/* ---------------------------------------------------------------------- - return an equilbrium bond length -------------------------------------------------------------------------- */ - -double BondQuartic::equilibrium_distance(int i) -{ - return 0.97; -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void BondQuartic::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&b1[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&b2[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&rc[1],sizeof(double),atom->nbondtypes,fp); - fwrite(&u0[1],sizeof(double),atom->nbondtypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void BondQuartic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nbondtypes,fp); - fread(&b1[1],sizeof(double),atom->nbondtypes,fp); - fread(&b2[1],sizeof(double),atom->nbondtypes,fp); - fread(&rc[1],sizeof(double),atom->nbondtypes,fp); - fread(&u0[1],sizeof(double),atom->nbondtypes,fp); - } - MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&b1[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&b2[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&rc[1],atom->nbondtypes,MPI_DOUBLE,0,world); - MPI_Bcast(&u0[1],atom->nbondtypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1; -} - - -/* ---------------------------------------------------------------------- */ - -void BondQuartic::single(int type, double rsq, int i, int j, double rfactor, - int eflag, double &fforce, double &eng) -{ - double r,dr,r2,ra,rb,sr2,sr6; - - fforce = eng = 0.0; - if (type <= 0) return; - - // subtract out pairwise contribution from 2 atoms via pair->single() - // required since special_bond = 1,1,1 - - int itype = atom->type[i]; - int jtype = atom->type[j]; - - if (rsq < force->pair->cutsq[itype][jtype]) { - Pair::One one; - force->pair->single(i,j,itype,jtype,rsq,1.0,1.0,eflag,one); - fforce = -one.fforce; - if (eflag) eng = -one.eng_coul - one.eng_vdwl; - } - - // quartic bond - // 1st portion is from quartic term - // 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0 - - r = sqrt(rsq); - dr = r - rc[type]; - r2 = dr*dr; - ra = dr - b1[type]; - rb = dr - b2[type]; - fforce += -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb); - - if (rsq < TWO_1_3) { - sr2 = 1.0/rsq; - sr6 = sr2*sr2*sr2; - fforce += 48.0*sr6*(sr6-0.5)/rsq; - } - - if (eflag) { - eng += rfactor*(k[type]*r2*ra*rb + u0[type]); - if (rsq < TWO_1_3) eng += rfactor * (4.0*sr6*(sr6-1.0) + 1.0); - } -} diff --git a/src/bond_quartic.h b/src/bond_quartic.h deleted file mode 100644 index 7bc7f55f3a..0000000000 --- a/src/bond_quartic.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ----------------------------------------------------------------------- - 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 BOND_QUARTIC_H -#define BOND_QUARTIC_H - -#include "stdio.h" -#include "bond.h" - -class BondQuartic : public Bond { - public: - BondQuartic(); - ~BondQuartic(); - void compute(int, int); - void coeff(int, char **); - void init_style(); - double equilibrium_distance(int); - void write_restart(FILE *); - void read_restart(FILE *); - void single(int, double, int, int, double, int, double &, double &); - - private: - double TWO_1_3; - double *k,*b1,*b2,*rc,*u0; - - void allocate(); -}; - -#endif diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 6579e1e082..7088eb576e 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -257,7 +257,6 @@ void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) for (k = 0; k < numneigh; k++) { j = neighs[k]; - list[i] = 1; if (j >= nall) { if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue; j %= nall; diff --git a/src/dihedral.cpp b/src/dihedral.cpp deleted file mode 100644 index 49de307e36..0000000000 --- a/src/dihedral.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "dihedral.h" -#include "atom.h" -#include "error.h" - -/* ---------------------------------------------------------------------- - set dihedral contribution to Vdwl and Coulombic energy to 0.0 - DihedralCharmm will override this -------------------------------------------------------------------------- */ - -Dihedral::Dihedral() -{ - allocated = 0; - eng_vdwl = eng_coul = 0.0; - PI = 4.0*atan(1.0); -} - -/* ---------------------------------------------------------------------- - check if all coeffs are set -------------------------------------------------------------------------- */ - -void Dihedral::init() -{ - if (!allocated) error->all("Dihedral coeffs are not set"); - for (int i = 1; i <= atom->ndihedraltypes; i++) - if (setflag[i] == 0) error->all("All dihedral coeffs are not set"); - init_style(); -} - diff --git a/src/dihedral_charmm.cpp b/src/dihedral_charmm.cpp deleted file mode 100644 index 24198df7f1..0000000000 --- a/src/dihedral_charmm.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "mpi.h" -#include "math.h" -#include "stdlib.h" -#include "dihedral_charmm.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "force.h" -#include "pair_lj_charmm_coul_charmm.h" -#include "pair_lj_charmm_coul_charmm_implicit.h" -#include "pair_lj_charmm_coul_long.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define TOLERANCE 0.05 -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralCharmm::~DihedralCharmm() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(multiplicity); - memory->sfree(shift); - memory->sfree(cos_shift); - memory->sfree(sin_shift); - memory->sfree(weight); - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralCharmm::compute(int eflag, int vflag) -{ - int i,m,n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z; - double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; - double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; - double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; - double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; - int itype,jtype; - double delx,dely,delz,rsq,r2inv,r6inv; - double fforce,forcecoul,forcelj,phicoul,philj; - - energy = 0.0; - eng_coul = eng_vdwl = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - double *q = atom->q; - int *atomtype = atom->type; - int **dihedrallist = neighbor->dihedrallist; - int ndihedrallist = neighbor->ndihedrallist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - double qqrd2e = force->qqrd2e; - - for (n = 0; n < ndihedrallist; n++) { - - i1 = dihedrallist[n][0]; - i2 = dihedrallist[n][1]; - i3 = dihedrallist[n][2]; - i4 = dihedrallist[n][3]; - type = dihedrallist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - ax = vb1y*vb2zm - vb1z*vb2ym; - ay = vb1z*vb2xm - vb1x*vb2zm; - az = vb1x*vb2ym - vb1y*vb2xm; - bx = vb3y*vb2zm - vb3z*vb2ym; - by = vb3z*vb2xm - vb3x*vb2zm; - bz = vb3x*vb2ym - vb3y*vb2xm; - - rasq = ax*ax + ay*ay + az*az; - rbsq = bx*bx + by*by + bz*bz; - rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - rg = sqrt(rgsq); - - rginv = ra2inv = rb2inv = 0.0; - if (rg > 0) rginv = 1.0/rg; - if (rasq > 0) ra2inv = 1.0/rasq; - if (rbsq > 0) rb2inv = 1.0/rbsq; - rabinv = sqrt(ra2inv*rb2inv); - - c = (ax*bx + ay*by + az*bz)*rabinv; - s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - int me; - MPI_Comm_rank(world,&me); - if (screen) { - fprintf(screen,"Dihedral problem: %d %d %d %d %d %d\n", - me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - m = multiplicity[type]; - p = 1.0; - df1 = 0.0; - - for (i = 0; i < m; i++) { - ddf1 = p*c - df1*s; - df1 = p*s + df1*c; - p = ddf1; - } - - p = p*cos_shift[type] + df1*sin_shift[type]; - df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; - df1 *= -m; - p += 1.0; - - if (m == 0) { - p = 1.0 + cos_shift[type]; - df1 = 0.0; - } - - if (eflag) energy += rfactor * k[type] * p; - - fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; - hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; - fga = fg*ra2inv*rginv; - hgb = hg*rb2inv*rginv; - gaa = -ra2inv*rg; - gbb = rb2inv*rg; - - dtfx = gaa*ax; - dtfy = gaa*ay; - dtfz = gaa*az; - dtgx = fga*ax - hgb*bx; - dtgy = fga*ay - hgb*by; - dtgz = fga*az - hgb*bz; - dthx = gbb*bx; - dthy = gbb*by; - dthz = gbb*bz; - - df = k[type] * df1; - - sx1 = df*dtfx; - sy1 = df*dtfy; - sz1 = df*dtfz; - sx2 = -df*dtgx; - sy2 = -df*dtgy; - sz2 = -df*dtgz; - sx12 = df*dthx; - sy12 = df*dthy; - sz12 = df*dthz; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - - // 1-4 LJ and Coulomb interactions - // force, energy, and virial - - if (weight[type] > 0.0) { - - itype = atomtype[i1]; - jtype = atomtype[i4]; - - delx = x[i1][0] - x[i4][0]; - dely = x[i1][1] - x[i4][1]; - delz = x[i1][2] - x[i4][2]; - domain->minimum_image(&delx,&dely,&delz); - rsq = delx*delx + dely*dely + delz*delz; - r2inv = 1.0/rsq; - r6inv = r2inv*r2inv*r2inv; - - if (implicitflag) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; - else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); - forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]); - fforce = weight[type] * (forcelj+forcecoul)*r2inv; - - if (eflag) { - phicoul = weight[type] * rfactor * forcecoul; - philj = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]); - philj = weight[type] * rfactor * philj; - eng_coul += phicoul; - eng_vdwl += philj; - } - - if (newton_bond || i1 < nlocal) { - f[i1][0] += delx*fforce; - f[i1][1] += dely*fforce; - f[i1][2] += delz*fforce; - } - if (newton_bond || i4 < nlocal) { - f[i4][0] -= delx*fforce; - f[i4][1] -= dely*fforce; - f[i4][2] -= delz*fforce; - } - - if (vflag) { - virial[0] += rfactor * delx*delx*fforce; - virial[1] += rfactor * dely*dely*fforce; - virial[2] += rfactor * delz*delz*fforce; - virial[3] += rfactor * delx*dely*fforce; - virial[4] += rfactor * delx*delz*fforce; - virial[5] += rfactor * dely*delz*fforce; - } - } - - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralCharmm::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k"); - multiplicity = (int *) - memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity"); - shift = (int *) - memory->smalloc((n+1)*sizeof(double),"dihedral:shift"); - cos_shift = (double *) - memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift"); - sin_shift = (double *) - memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift"); - weight = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:weight"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void DihedralCharmm::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this dihedral style"); - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - // require integer values of shift for backwards compatibility - // arbitrary phase angle shift could be allowed, but would break - // backwards compatibility and is probably not needed - - double k_one = atof(arg[1]); - int multiplicity_one = atoi(arg[2]); - int shift_one = atoi(arg[3]); - double weight_one = atof(arg[4]); - - if (multiplicity_one < 0) - error->all("Incorrect multiplicity arg for dihedral coefficients"); - if (weight_one < 0.0 || weight_one > 1.0) - error->all("Incorrect weight arg for dihedral coefficients"); - - double PI = 4.0*atan(1.0); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - shift[i] = shift_one; - cos_shift[i] = cos(PI*shift_one/180.0); - sin_shift[i] = sin(PI*shift_one/180.0); - multiplicity[i] = multiplicity_one; - weight[i] = weight_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for dihedral coefficients"); -} - -/* ---------------------------------------------------------------------- - error check and initialize all values needed for force computation -------------------------------------------------------------------------- */ - -void DihedralCharmm::init_style() -{ - // set local ptrs to LJ 14 arrays setup by pair - - Pair *anypair; - if (anypair = force->pair_match("lj/charmm/coul/charmm")) { - PairLJCharmmCoulCharmm *pair = (PairLJCharmmCoulCharmm *) anypair; - lj14_1 = pair->lj14_1; - lj14_2 = pair->lj14_2; - lj14_3 = pair->lj14_3; - lj14_4 = pair->lj14_4; - implicitflag = 0; - } else if (anypair = force->pair_match("lj/charmm/coul/charmm/implicit")) { - PairLJCharmmCoulCharmmImplicit *pair = - (PairLJCharmmCoulCharmmImplicit *) anypair; - lj14_1 = pair->lj14_1; - lj14_2 = pair->lj14_2; - lj14_3 = pair->lj14_3; - lj14_4 = pair->lj14_4; - implicitflag = 1; - } else if (anypair = force->pair_match("lj/charmm/coul/long")) { - PairLJCharmmCoulLong *pair = (PairLJCharmmCoulLong *) anypair; - lj14_1 = pair->lj14_1; - lj14_2 = pair->lj14_2; - lj14_3 = pair->lj14_3; - lj14_4 = pair->lj14_4; - implicitflag = 0; - } else error->all("Pair style is incompatible with DihedralCharmm"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void DihedralCharmm::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); - fwrite(&shift[1],sizeof(int),atom->ndihedraltypes,fp); - fwrite(&weight[1],sizeof(double),atom->ndihedraltypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void DihedralCharmm::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); - fread(&shift[1],sizeof(int),atom->ndihedraltypes,fp); - fread(&weight[1],sizeof(double),atom->ndihedraltypes,fp); - } - MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world); - MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world); - MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - - double PI = 4.0*atan(1.0); - for (int i = 1; i <= atom->ndihedraltypes; i++) { - setflag[i] = 1; - cos_shift[i] = cos(PI*shift[i]/180.0); - sin_shift[i] = sin(PI*shift[i]/180.0); - } -} diff --git a/src/dihedral_charmm.h b/src/dihedral_charmm.h deleted file mode 100644 index 107818633d..0000000000 --- a/src/dihedral_charmm.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_CHARMM_H -#define DIHEDRAL_CHARMM_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralCharmm : public Dihedral { - public: - DihedralCharmm() {} - ~DihedralCharmm(); - void compute(int, int); - void coeff(int, int, char **); - void init_style(); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *k,*weight,*cos_shift,*sin_shift; - int *multiplicity,*shift; - double **lj14_1,**lj14_2,**lj14_3,**lj14_4; - int implicitflag; - - void allocate(); -}; - -#endif diff --git a/src/dihedral_harmonic.cpp b/src/dihedral_harmonic.cpp deleted file mode 100644 index 8762262bdf..0000000000 --- a/src/dihedral_harmonic.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "mpi.h" -#include "math.h" -#include "stdlib.h" -#include "dihedral_harmonic.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define TOLERANCE 0.05 -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralHarmonic::~DihedralHarmonic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(sign); - memory->sfree(multiplicity); - memory->sfree(cos_shift); - memory->sfree(sin_shift); - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHarmonic::compute(int eflag, int vflag) -{ - int i,m,n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z; - double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; - double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; - double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; - double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **dihedrallist = neighbor->dihedrallist; - int ndihedrallist = neighbor->ndihedrallist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < ndihedrallist; n++) { - - i1 = dihedrallist[n][0]; - i2 = dihedrallist[n][1]; - i3 = dihedrallist[n][2]; - i4 = dihedrallist[n][3]; - type = dihedrallist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - // c,s calculation - - ax = vb1y*vb2zm - vb1z*vb2ym; - ay = vb1z*vb2xm - vb1x*vb2zm; - az = vb1x*vb2ym - vb1y*vb2xm; - bx = vb3y*vb2zm - vb3z*vb2ym; - by = vb3z*vb2xm - vb3x*vb2zm; - bz = vb3x*vb2ym - vb3y*vb2xm; - - rasq = ax*ax + ay*ay + az*az; - rbsq = bx*bx + by*by + bz*bz; - rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - rg = sqrt(rgsq); - - rginv = ra2inv = rb2inv = 0.0; - if (rg > 0) rginv = 1.0/rg; - if (rasq > 0) ra2inv = 1.0/rasq; - if (rbsq > 0) rb2inv = 1.0/rbsq; - rabinv = sqrt(ra2inv*rb2inv); - - c = (ax*bx + ay*by + az*bz)*rabinv; - s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - int me; - MPI_Comm_rank(world,&me); - if (screen) { - fprintf(screen,"Dihedral problem: %d %d %d %d %d %d\n", - me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - m = multiplicity[type]; - p = 1.0; - df1 = 0.0; - - for (i = 0; i < m; i++) { - ddf1 = p*c - df1*s; - df1 = p*s + df1*c; - p = ddf1; - } - - p = p*cos_shift[type] + df1*sin_shift[type]; - df1 = df1*cos_shift[type] - ddf1*sin_shift[type]; - df1 *= -m; - p += 1.0; - - if (m == 0) { - p = 1.0 + cos_shift[type]; - df1 = 0.0; - } - - if (eflag) energy += rfactor * k[type] * p; - - fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; - hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; - fga = fg*ra2inv*rginv; - hgb = hg*rb2inv*rginv; - gaa = -ra2inv*rg; - gbb = rb2inv*rg; - - dtfx = gaa*ax; - dtfy = gaa*ay; - dtfz = gaa*az; - dtgx = fga*ax - hgb*bx; - dtgy = fga*ay - hgb*by; - dtgz = fga*az - hgb*bz; - dthx = gbb*bx; - dthy = gbb*by; - dthz = gbb*bz; - - df = k[type] * df1; - - sx1 = df*dtfx; - sy1 = df*dtfy; - sz1 = df*dtfz; - sx2 = -df*dtgx; - sy2 = -df*dtgy; - sz2 = -df*dtgz; - sx12 = df*dthx; - sy12 = df*dthy; - sz12 = df*dthz; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHarmonic::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k"); - sign = (int *) memory->smalloc((n+1)*sizeof(double),"dihedral:sign"); - multiplicity = (int *) - memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity"); - cos_shift = (double *) - memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift"); - sin_shift = (double *) - memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void DihedralHarmonic::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this dihedral style"); - if (narg != 4) error->all("Incorrect args for dihedral coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - double k_one = atof(arg[1]); - int sign_one = atoi(arg[2]); - int multiplicity_one = atoi(arg[3]); - - // require sign = +/- 1 for backwards compatibility - // arbitrary phase angle shift could be allowed, but would break - // backwards compatibility and is probably not needed - - if (sign_one != -1 && sign_one != 1) - error->all("Incorrect sign arg for dihedral coefficients"); - if (multiplicity_one < 0) - error->all("Incorrect multiplicity arg for dihedral coefficients"); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - sign[i] = sign_one; - if (sign[i] == 1) { - cos_shift[i] = 1; - sin_shift[i] = 0; - } else { - cos_shift[i] = -1; - sin_shift[i] = 0; - } - multiplicity[i] = multiplicity_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for dihedral coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void DihedralHarmonic::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&sign[1],sizeof(int),atom->ndihedraltypes,fp); - fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void DihedralHarmonic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&sign[1],sizeof(int),atom->ndihedraltypes,fp); - fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp); - } - MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&sign[1],atom->ndihedraltypes,MPI_INT,0,world); - MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world); - - for (int i = 1; i <= atom->ndihedraltypes; i++) { - setflag[i] = 1; - if (sign[i] == 1) { - cos_shift[i] = 1; - sin_shift[i] = 0; - } else { - cos_shift[i] = -1; - sin_shift[i] = 0; - } - } -} diff --git a/src/dihedral_harmonic.h b/src/dihedral_harmonic.h deleted file mode 100644 index e0ddac0882..0000000000 --- a/src/dihedral_harmonic.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_HARMONIC_H -#define DIHEDRAL_HARMONIC_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralHarmonic : public Dihedral { - public: - DihedralHarmonic() {} - ~DihedralHarmonic(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *k,*cos_shift,*sin_shift; - int *sign,*multiplicity; - - void allocate(); -}; - -#endif diff --git a/src/dihedral_helix.cpp b/src/dihedral_helix.cpp deleted file mode 100644 index ba6f7c7e33..0000000000 --- a/src/dihedral_helix.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Naveen Michaud-Agrawal (Johns Hopkins U) and - Mark Stevens (Sandia) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "mpi.h" -#include "dihedral_helix.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -#define TOLERANCE 0.05 -#define SMALL 0.001 -#define SMALLER 0.00001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralHelix::~DihedralHelix() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(aphi); - memory->sfree(bphi); - memory->sfree(cphi); - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHelix::compute(int eflag, int vflag) -{ - int n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; - double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; - double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; - double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; - double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; - double sz1,sz2,sz12,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **dihedrallist = neighbor->dihedrallist; - int ndihedrallist = neighbor->ndihedrallist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < ndihedrallist; n++) { - - i1 = dihedrallist[n][0]; - i2 = dihedrallist[n][1]; - i3 = dihedrallist[n][2]; - i4 = dihedrallist[n][3]; - type = dihedrallist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - // c0 calculation - - sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); - sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); - sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); - - rb1 = sqrt(sb1); - rb3 = sqrt(sb3); - - c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; - - // 1st and 2nd angle - - b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - b1mag = sqrt(b1mag2); - b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; - b2mag = sqrt(b2mag2); - b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - b3mag = sqrt(b3mag2); - - ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; - r12c1 = 1.0 / (b1mag*b2mag); - c1mag = ctmp * r12c1; - - ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; - r12c2 = 1.0 / (b2mag*b3mag); - c2mag = ctmp * r12c2; - - // cos and sin of 2 angles and final c - - sin2 = MAX(1.0 - c1mag*c1mag,0.0); - sc1 = sqrt(sin2); - if (sc1 < SMALL) sc1 = SMALL; - sc1 = 1.0/sc1; - - sin2 = MAX(1.0 - c2mag*c2mag,0.0); - sc2 = sqrt(sin2); - if (sc2 < SMALL) sc2 = SMALL; - sc2 = 1.0/sc2; - - s1 = sc1 * sc1; - s2 = sc2 * sc2; - s12 = sc1 * sc2; - c = (c0 + c1mag*c2mag) * s12; - - cx = vb1y*vb2z - vb1z*vb2y; - cy = vb1z*vb2x - vb1x*vb2z; - cz = vb1x*vb2y - vb1y*vb2x; - cmag = sqrt(cx*cx + cy*cy + cz*cz); - dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - int me; - MPI_Comm_rank(world,&me); - if (screen) { - fprintf(screen,"Dihedral problem: %d %d %d %d %d %d\n", - me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - phi = acos(c); - if (dx < 0.0) phi *= -1.0; - si = sin(phi); - if (fabs(si) < SMALLER) si = SMALLER; - siinv = 1.0/si; - - p = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + - cphi[type]*(1.0 + cos(phi + 0.25*PI)); - pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + - cphi[type]*sin(phi + 0.25*PI)*siinv; - - if (eflag) energy += rfactor * p; - - a = pd; - c = c * a; - s12 = s12 * a; - a11 = -c*sb1*s1; - a22 = sb2 * (2.0*c0*s12 - c*(s1+s2)); - a33 = -c*sb3*s2; - a12 = r12c1 * (c1mag*c*s1 + c2mag*s12); - a13 = rb1*rb3*s12; - a23 = r12c2 * (-c2mag*c*s2 - c1mag*s12); - - sx1 = a11*vb1x + a12*vb2x + a13*vb3x; - sx2 = a12*vb1x + a22*vb2x + a23*vb3x; - sx12 = a13*vb1x + a23*vb2x + a33*vb3x; - sy1 = a11*vb1y + a12*vb2y + a13*vb3y; - sy2 = a12*vb1y + a22*vb2y + a23*vb3y; - sy12 = a13*vb1y + a23*vb2y + a33*vb3y; - sz1 = a11*vb1z + a12*vb2z + a13*vb3z; - sz2 = a12*vb1z + a22*vb2z + a23*vb3z; - sz12 = a13*vb1z + a23*vb2z + a33*vb3z; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHelix::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - aphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:aphi"); - bphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:bphi"); - cphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:cphi"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs from one line in input script -------------------------------------------------------------------------- */ - -void DihedralHelix::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this dihedral style"); - if (narg != 4) error->all("Incorrect args for dihedral coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - double aphi_one = atof(arg[1]); - double bphi_one = atof(arg[2]); - double cphi_one = atof(arg[3]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - aphi[i] = aphi_one; - bphi[i] = bphi_one; - cphi[i] = cphi_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for dihedral coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void DihedralHelix::write_restart(FILE *fp) -{ - fwrite(&aphi[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&bphi[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&cphi[1],sizeof(double),atom->ndihedraltypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void DihedralHelix::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&aphi[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&bphi[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&cphi[1],sizeof(double),atom->ndihedraltypes,fp); - } - MPI_Bcast(&aphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&bphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&cphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1; -} diff --git a/src/dihedral_helix.h b/src/dihedral_helix.h deleted file mode 100644 index 85481b4318..0000000000 --- a/src/dihedral_helix.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_HELIX_H -#define DIHEDRAL_HELIX_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralHelix : public Dihedral { - public: - DihedralHelix() {} - ~DihedralHelix(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *aphi,*bphi,*cphi; - - void allocate(); -}; - -#endif diff --git a/src/dihedral_hybrid.cpp b/src/dihedral_hybrid.cpp deleted file mode 100644 index dea4ce72fc..0000000000 --- a/src/dihedral_hybrid.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* ----------------------------------------------------------------------- - 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 "dihedral_hybrid.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define EXTRA 1000 - -/* ---------------------------------------------------------------------- - set all global defaults -------------------------------------------------------------------------- */ - -DihedralHybrid::DihedralHybrid() -{ - nstyles = 0; -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralHybrid::~DihedralHybrid() -{ - if (nstyles) { - for (int i = 0; i < nstyles; i++) delete styles[i]; - delete [] styles; - for (int i = 0; i < nstyles; i++) delete [] keywords[i]; - delete [] keywords; - } - - if (allocated) { - memory->sfree(setflag); - memory->sfree(map); - delete [] ndihedrallist; - delete [] maxdihedral; - for (int i = 0; i < nstyles; i++) - memory->destroy_2d_int_array(dihedrallist[i]); - delete [] dihedrallist; - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHybrid::compute(int eflag, int vflag) -{ - int i,m,n; - - // save ptrs to original dihedrallist - - int ndihedrallist_orig = neighbor->ndihedrallist; - int **dihedrallist_orig = neighbor->dihedrallist; - - // if this is re-neighbor step, create sub-style dihedrallists - // ndihedrallist[] = length of each sub-style list - // realloc sub-style dihedrallist if necessary - // load sub-style dihedrallist with 5 values from original dihedrallist - - if (neighbor->ago == 0) { - for (m = 0; m < nstyles; m++) ndihedrallist[m] = 0; - for (i = 0; i < ndihedrallist_orig; i++) - ndihedrallist[map[dihedrallist_orig[i][4]]]++; - for (m = 0; m < nstyles; m++) { - if (ndihedrallist[m] > maxdihedral[m]) { - memory->destroy_2d_int_array(dihedrallist[m]); - maxdihedral[m] = ndihedrallist[m] + EXTRA; - dihedrallist[m] = (int **) - memory->create_2d_int_array(maxdihedral[m],5, - "dihedral_hybrid:dihedrallist"); - } - ndihedrallist[m] = 0; - } - for (i = 0; i < ndihedrallist_orig; i++) { - m = map[dihedrallist_orig[i][4]]; - n = ndihedrallist[m]; - dihedrallist[m][n][0] = dihedrallist_orig[i][0]; - dihedrallist[m][n][1] = dihedrallist_orig[i][1]; - dihedrallist[m][n][2] = dihedrallist_orig[i][2]; - dihedrallist[m][n][3] = dihedrallist_orig[i][3]; - dihedrallist[m][n][4] = dihedrallist_orig[i][4]; - ndihedrallist[m]++; - } - } - - // call each sub-style's compute function - // must set neighbor->dihedrallist to sub-style dihedrallist before call - // accumulate sub-style energy,virial in hybrid's energy,virial - - energy = 0.0; - eng_vdwl = eng_coul = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - for (m = 0; m < nstyles; m++) { - if (styles[m] == NULL) continue; - neighbor->ndihedrallist = ndihedrallist[m]; - neighbor->dihedrallist = dihedrallist[m]; - styles[m]->compute(eflag,vflag); - if (eflag) { - energy += styles[m]->energy; - eng_vdwl += styles[m]->eng_vdwl; - eng_coul += styles[m]->eng_coul; - } - if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; - } - - // restore ptrs to original dihedrallist - - neighbor->ndihedrallist = ndihedrallist_orig; - neighbor->dihedrallist = dihedrallist_orig; -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHybrid::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - map = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:map"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; - - ndihedrallist = new int[nstyles]; - maxdihedral = new int[nstyles]; - dihedrallist = new int**[nstyles]; - for (int m = 0; m < nstyles; m++) maxdihedral[m] = 0; - for (int m = 0; m < nstyles; m++) dihedrallist[m] = NULL; -} - -/* ---------------------------------------------------------------------- - create one dihedral style for each arg in list -------------------------------------------------------------------------- */ - -void DihedralHybrid::settings(int narg, char **arg) -{ - nstyles = narg; - styles = new Dihedral*[nstyles]; - keywords = new char*[nstyles]; - - for (int m = 0; m < nstyles; m++) { - for (int i = 0; i < m; i++) - if (strcmp(arg[m],arg[i]) == 0) - error->all("Dihedral style hybrid cannot use same dihedral style twice"); - if (strcmp(arg[m],"hybrid") == 0) - error->all("Dihedral style hybrid cannot have hybrid as an argument"); - styles[m] = force->new_dihedral(arg[m]); - keywords[m] = new char[strlen(arg[m])+1]; - strcpy(keywords[m],arg[m]); - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one type ----------------------------------------------------------------------- */ - -void DihedralHybrid::coeff(int which, int narg, char **arg) -{ - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - // 2nd arg = dihedral style name (harmonic, etc) - - int m; - for (m = 0; m < nstyles; m++) - if (strcmp(arg[1],keywords[m]) == 0) break; - if (m == nstyles) error->all("Dihedral coeff for hybrid has invalid style"); - - // set low-level coefficients for each dihedraltype - // replace 2nd arg with i, call coeff() with no 1st arg - // if sub-style is NULL for "none", still set setflag - - for (int i = ilo; i <= ihi; i++) { - sprintf(arg[1],"%d",i); - map[i] = m; - if (styles[m]) styles[m]->coeff(which,narg-1,&arg[1]); - setflag[i] = 1; - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralHybrid::init_style() -{ - for (int m = 0; m < nstyles; m++) - if (styles[m]) styles[m]->init_style(); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void DihedralHybrid::write_restart(FILE *fp) -{ - fwrite(&nstyles,sizeof(int),1,fp); - - int n; - for (int m = 0; m < nstyles; m++) { - n = strlen(keywords[m]) + 1; - fwrite(&n,sizeof(int),1,fp); - fwrite(keywords[m],sizeof(char),n,fp); - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void DihedralHybrid::read_restart(FILE *fp) -{ - allocate(); - - int me = comm->me; - if (me == 0) fread(&nstyles,sizeof(int),1,fp); - MPI_Bcast(&nstyles,1,MPI_INT,0,world); - styles = new Dihedral*[nstyles]; - keywords = new char*[nstyles]; - - int n; - for (int m = 0; m < nstyles; m++) { - if (me == 0) fread(&n,sizeof(int),1,fp); - MPI_Bcast(&n,1,MPI_INT,0,world); - keywords[m] = new char[n]; - if (me == 0) fread(keywords[m],sizeof(char),n,fp); - MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_dihedral(keywords[m]); - } -} - -/* ---------------------------------------------------------------------- - memory usage -------------------------------------------------------------------------- */ - -int DihedralHybrid::memory_usage() -{ - int bytes = 0; - for (int m = 0; m < nstyles; m++) bytes += maxdihedral[m]*5 * sizeof(int); - for (int m = 0; m < nstyles; m++) - if (styles[m]) bytes += styles[m]->memory_usage(); - return bytes; -} diff --git a/src/dihedral_hybrid.h b/src/dihedral_hybrid.h deleted file mode 100644 index e6cc471342..0000000000 --- a/src/dihedral_hybrid.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_HYBRID_H -#define DIHEDRAL_HYBRID_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralHybrid : public Dihedral { - public: - DihedralHybrid(); - ~DihedralHybrid(); - void compute(int, int); - void settings(int, char **); - void coeff(int, int, char **); - void init_style(); - void write_restart(FILE *); - void read_restart(FILE *); - int memory_usage(); - - private: - int nstyles; // # of different dihedral styles - Dihedral **styles; // class list for each Dihedral style - char **keywords; // keyword for each dihedral style - int *map; // which style each dihedral type points to - - int *ndihedrallist; // # of dihedrals in sub-style dihedrallists - int *maxdihedral; // max # of dihedrals sub-style lists can store - int ***dihedrallist; // dihedrallist for each sub-style - - void allocate(); -}; - -#endif diff --git a/src/dihedral_multi_harmonic.cpp b/src/dihedral_multi_harmonic.cpp deleted file mode 100644 index b3541f9521..0000000000 --- a/src/dihedral_multi_harmonic.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Mathias Puetz (SNL) and friends -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "dihedral_multi_harmonic.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -#define TOLERANCE 0.05 -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralMultiHarmonic::~DihedralMultiHarmonic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(a1); - memory->sfree(a2); - memory->sfree(a3); - memory->sfree(a4); - memory->sfree(a5); - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralMultiHarmonic::compute(int eflag, int vflag) -{ - int n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; - double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; - double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; - double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; - double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; - double sz1,sz2,sz12,s2,sin2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **dihedrallist = neighbor->dihedrallist; - int ndihedrallist = neighbor->ndihedrallist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < ndihedrallist; n++) { - - i1 = dihedrallist[n][0]; - i2 = dihedrallist[n][1]; - i3 = dihedrallist[n][2]; - i4 = dihedrallist[n][3]; - type = dihedrallist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - // c0 calculation - - sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); - sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); - sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); - - rb1 = sqrt(sb1); - rb3 = sqrt(sb3); - - c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; - - // 1st and 2nd angle - - b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - b1mag = sqrt(b1mag2); - b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; - b2mag = sqrt(b2mag2); - b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - b3mag = sqrt(b3mag2); - - ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; - r12c1 = 1.0 / (b1mag*b2mag); - c1mag = ctmp * r12c1; - - ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; - r12c2 = 1.0 / (b2mag*b3mag); - c2mag = ctmp * r12c2; - - // cos and sin of 2 angles and final c - - sin2 = MAX(1.0 - c1mag*c1mag,0.0); - sc1 = sqrt(sin2); - if (sc1 < SMALL) sc1 = SMALL; - sc1 = 1.0/sc1; - - sin2 = MAX(1.0 - c2mag*c2mag,0.0); - sc2 = sqrt(sin2); - if (sc2 < SMALL) sc2 = SMALL; - sc2 = 1.0/sc2; - - s1 = sc1 * sc1; - s2 = sc2 * sc2; - s12 = sc1 * sc2; - c = (c0 + c1mag*c2mag) * s12; - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - if (screen) { - fprintf(screen,"Dihedral problem: %d %d %d %d %d %d\n", - comm->me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - comm->me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - comm->me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - comm->me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - comm->me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - // force & energy - // p = sum (i=1,5) a_i * c**(i-1) - // pd = dp/dc - - p = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type]))); - pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type])); - - if (eflag) energy += rfactor * p; - - a = pd; - c = c * a; - s12 = s12 * a; - a11 = (-c*sb1*s1); - a22 = sb2*(2.0*c0*s12 - c*(s1+s2)); - a33 = (-c*sb3*s2); - a12 = r12c1*(c1mag*c*s1 + c2mag*s12); - a13 = rb1*rb3*s12; - a23 = r12c2*(-c2mag*c*s2 - c1mag*s12); - - sx1 = a11*vb1x + a12*vb2x + a13*vb3x; - sx2 = a12*vb1x + a22*vb2x + a23*vb3x; - sx12 = a13*vb1x + a23*vb2x + a33*vb3x; - sy1 = a11*vb1y + a12*vb2y + a13*vb3y; - sy2 = a12*vb1y + a22*vb2y + a23*vb3y; - sy12 = a13*vb1y + a23*vb2y + a33*vb3y; - sz1 = a11*vb1z + a12*vb2z + a13*vb3z; - sz2 = a12*vb1z + a22*vb2z + a23*vb3z; - sz12 = a13*vb1z + a23*vb2z + a33*vb3z; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralMultiHarmonic::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - a1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a1"); - a2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a2"); - a3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a3"); - a4 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a4"); - a5 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a5"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void DihedralMultiHarmonic::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this dihedral style"); - if (narg != 6) error->all("Incorrect args for dihedral coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - double a1_one = atof(arg[1]); - double a2_one = atof(arg[2]); - double a3_one = atof(arg[3]); - double a4_one = atof(arg[4]); - double a5_one = atof(arg[5]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - a1[i] = a1_one; - a2[i] = a2_one; - a3[i] = a3_one; - a4[i] = a4_one; - a5[i] = a5_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for dihedral coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void DihedralMultiHarmonic::write_restart(FILE *fp) -{ - fwrite(&a1[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&a2[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&a3[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&a4[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&a5[1],sizeof(double),atom->ndihedraltypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void DihedralMultiHarmonic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&a1[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&a2[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&a3[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&a4[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&a5[1],sizeof(double),atom->ndihedraltypes,fp); - } - MPI_Bcast(&a1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&a2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&a3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&a4[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&a5[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1; -} diff --git a/src/dihedral_multi_harmonic.h b/src/dihedral_multi_harmonic.h deleted file mode 100644 index 695cdfe1af..0000000000 --- a/src/dihedral_multi_harmonic.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_MULTI_HARMONIC_H -#define DIHEDRAL_MULTI_HARMONIC_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralMultiHarmonic : public Dihedral { - public: - DihedralMultiHarmonic() {} - ~DihedralMultiHarmonic(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *a1,*a2,*a3,*a4,*a5; - - void allocate(); -}; - -#endif diff --git a/src/dihedral_opls.cpp b/src/dihedral_opls.cpp deleted file mode 100644 index eff17571fc..0000000000 --- a/src/dihedral_opls.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Mark Stevens (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdlib.h" -#include "dihedral_opls.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -#define TOLERANCE 0.05 -#define SMALL 0.001 -#define SMALLER 0.00001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -DihedralOPLS::~DihedralOPLS() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k1); - memory->sfree(k2); - memory->sfree(k3); - memory->sfree(k4); - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralOPLS::compute(int eflag, int vflag) -{ - int i,m,n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; - double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; - double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; - double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; - double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; - double sz1,sz2,sz12,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **dihedrallist = neighbor->dihedrallist; - int ndihedrallist = neighbor->ndihedrallist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < ndihedrallist; n++) { - - i1 = dihedrallist[n][0]; - i2 = dihedrallist[n][1]; - i3 = dihedrallist[n][2]; - i4 = dihedrallist[n][3]; - type = dihedrallist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - // c0 calculation - - sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); - sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); - sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); - - rb1 = sqrt(sb1); - rb3 = sqrt(sb3); - - c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; - - // 1st and 2nd angle - - b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - b1mag = sqrt(b1mag2); - b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; - b2mag = sqrt(b2mag2); - b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - b3mag = sqrt(b3mag2); - - ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; - r12c1 = 1.0 / (b1mag*b2mag); - c1mag = ctmp * r12c1; - - ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; - r12c2 = 1.0 / (b2mag*b3mag); - c2mag = ctmp * r12c2; - - // cos and sin of 2 angles and final c - - sin2 = MAX(1.0 - c1mag*c1mag,0.0); - sc1 = sqrt(sin2); - if (sc1 < SMALL) sc1 = SMALL; - sc1 = 1.0/sc1; - - sin2 = MAX(1.0 - c2mag*c2mag,0.0); - sc2 = sqrt(sin2); - if (sc2 < SMALL) sc2 = SMALL; - sc2 = 1.0/sc2; - - s1 = sc1 * sc1; - s2 = sc2 * sc2; - s12 = sc1 * sc2; - c = (c0 + c1mag*c2mag) * s12; - - cx = vb1y*vb2z - vb1z*vb2y; - cy = vb1z*vb2x - vb1x*vb2z; - cz = vb1x*vb2y - vb1y*vb2x; - cmag = sqrt(cx*cx + cy*cy + cz*cz); - dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - if (screen) { - fprintf(screen,"Dihedral problem: %d %d %d %d %d %d\n", - comm->me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - comm->me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - comm->me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - comm->me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - comm->me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - // force & energy - // p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) ) - // pd = dp/dc - - phi = acos(c); - if (dx < 0.0) phi *= -1.0; - si = sin(phi); - if (fabs(si) < SMALLER) si = SMALLER; - siinv = 1.0/si; - - p = k1[type]*(1.0 + c) + k2[type]*(1.0 - cos(2.0*phi)) + - k3[type]*(1.0 + cos(3.0*phi)) + k4[type]*(1.0 - cos(4.0*phi)) ; - pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv + - 3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv; - - if (eflag) energy += rfactor * p; - - a = pd; - c = c * a; - s12 = s12 * a; - a11 = -c*sb1*s1; - a22 = sb2 * (2.0*c0*s12 - c*(s1+s2)); - a33 = -c*sb3*s2; - a12 = r12c1 * (c1mag*c*s1 + c2mag*s12); - a13 = rb1*rb3*s12; - a23 = r12c2 * (-c2mag*c*s2 - c1mag*s12); - - sx1 = a11*vb1x + a12*vb2x + a13*vb3x; - sx2 = a12*vb1x + a22*vb2x + a23*vb3x; - sx12 = a13*vb1x + a23*vb2x + a33*vb3x; - sy1 = a11*vb1y + a12*vb2y + a13*vb3y; - sy2 = a12*vb1y + a22*vb2y + a23*vb3y; - sy12 = a13*vb1y + a23*vb2y + a33*vb3y; - sz1 = a11*vb1z + a12*vb2z + a13*vb3z; - sz2 = a12*vb1z + a22*vb2z + a23*vb3z; - sz12 = a13*vb1z + a23*vb2z + a33*vb3z; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void DihedralOPLS::allocate() -{ - allocated = 1; - int n = atom->ndihedraltypes; - - k1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k1"); - k2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k2"); - k3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k3"); - k4 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k4"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void DihedralOPLS::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this dihedral style"); - if (narg != 5) error->all("Incorrect args for dihedral coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi); - - double k1_one = atof(arg[1]); - double k2_one = atof(arg[2]); - double k3_one = atof(arg[3]); - double k4_one = atof(arg[4]); - - // store 1/2 factor with prefactor - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k1[i] = 0.5*k1_one; - k2[i] = 0.5*k2_one; - k3[i] = 0.5*k3_one; - k4[i] = 0.5*k4_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for dihedral coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void DihedralOPLS::write_restart(FILE *fp) -{ - fwrite(&k1[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&k2[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&k3[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&k4[1],sizeof(double),atom->ndihedraltypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void DihedralOPLS::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k1[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&k2[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&k3[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&k4[1],sizeof(double),atom->ndihedraltypes,fp); - } - MPI_Bcast(&k1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k4[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1; -} diff --git a/src/dihedral_opls.h b/src/dihedral_opls.h deleted file mode 100644 index d65363286c..0000000000 --- a/src/dihedral_opls.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DIHEDRAL_OPLS_H -#define DIHEDRAL_OPLS_H - -#include "stdio.h" -#include "dihedral.h" - -class DihedralOPLS : public Dihedral { - public: - DihedralOPLS() {} - ~DihedralOPLS(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *k1,*k2,*k3,*k4; - - void allocate(); -}; - -#endif diff --git a/src/dump_bond.cpp b/src/dump_bond.cpp deleted file mode 100644 index eb88e24780..0000000000 --- a/src/dump_bond.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "string.h" -#include "dump_bond.h" -#include "atom.h" -#include "domain.h" -#include "update.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -DumpBond::DumpBond(int narg, char **arg) : Dump(narg, arg) -{ - if (narg != 5) error->all("Illegal dump bond command"); - if (atom->molecular == 0) - error->all("Cannot use dump bond with non-molecular system"); - - size_one = 3; - - char *str = "%d %d %d %d"; - int n = strlen(str) + 1; - format_default = new char[n]; - strcpy(format_default,str); - - // one-time file open - - if (multifile == 0) openfile(); -} - -/* ---------------------------------------------------------------------- */ - -void DumpBond::init() -{ - delete [] format; - char *str; - if (format_user) str = format_user; - else str = format_default; - - int n = strlen(str) + 2; - format = new char[n]; - strcpy(format,str); - strcat(format,"\n"); -} - -/* ---------------------------------------------------------------------- */ - -void DumpBond::write_header(int ndump) -{ - fprintf(fp,"ITEM: TIMESTEP\n"); - fprintf(fp,"%d\n",update->ntimestep); - fprintf(fp,"ITEM: NUMBER OF BONDS\n"); - fprintf(fp,"%d\n",ndump); - fprintf(fp,"ITEM: BONDS\n"); -} - -/* ---------------------------------------------------------------------- */ - -int DumpBond::count() -{ - index = 0; - - int *num_bond = atom->num_bond; - int **bond_type = atom->bond_type; - int **bond_atom = atom->bond_atom; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - int i,j,k; - - int m = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - for (j = 0; j < num_bond[i]; j++) { - k = atom->map(bond_atom[i][j]); - if (k >= 0 && !(mask[k] & groupbit)) continue; - if (bond_type[i][j] == 0) continue; - m++; - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int DumpBond::pack() -{ - int *num_bond = atom->num_bond; - int **bond_type = atom->bond_type; - int **bond_atom = atom->bond_atom; - int *tag = atom->tag; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - int i,j,k,type,iatom; - - int m = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - for (j = 0; j < num_bond[i]; j++) { - iatom = bond_atom[i][j]; - k = atom->map(iatom); - if (k >= 0 && !(mask[k] & groupbit)) continue; - type = bond_type[i][j]; - if (type == 0) continue; - buf[m++] = type; - buf[m++] = tag[i]; - buf[m++] = iatom; - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void DumpBond::write_data(int n, double *buf) -{ - int m = 0; - for (int i = 0; i < n; i++) { - index++; - fprintf(fp,format, - index, static_cast (buf[m]), - static_cast (buf[m+1]), static_cast (buf[m+2])); - m += size_one; - } -} diff --git a/src/dump_bond.h b/src/dump_bond.h deleted file mode 100644 index 6af31b8a9a..0000000000 --- a/src/dump_bond.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 DUMP_BOND_H -#define DUMP_BOND_H - -#include "dump.h" - -class DumpBond : public Dump { - public: - DumpBond(int, char **); - ~DumpBond() {} - void init(); - - private: - int index; // counter for bond output - - void write_header(int); - int count(); - int pack(); - void write_data(int, double *); -}; - -#endif diff --git a/src/ewald.cpp b/src/ewald.cpp deleted file mode 100644 index 202a677999..0000000000 --- a/src/ewald.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Roy Pollock (LLNL), Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "mpi.h" -#include "stdlib.h" -#include "stdio.h" -#include "math.h" -#include "ewald.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "pair_buck_coul_long.h" -#include "pair_lj_cut_coul_long.h" -#include "pair_lj_charmm_coul_long.h" -#include "pair_lj_class2_coul_long.h" -#include "pair_table.h" -#include "domain.h" -#include "memory.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* ---------------------------------------------------------------------- */ - -Ewald::Ewald(int narg, char **arg) : KSpace(narg, arg) -{ - if (narg != 1) error->all("Illegal kspace_style ewald command"); - - precision = atof(arg[0]); - PI = 4.0*atan(1.0); - - kmax = 0; - kxvecs = kyvecs = kzvecs = NULL; - ug = NULL; - eg = vg = NULL; - sfacrl = sfacim = sfacrl_all = sfacim_all = NULL; - - nmax = 0; - ek = NULL; - cs = sn = NULL; - - kcount = 0; -} - -/* ---------------------------------------------------------------------- - free all memory -------------------------------------------------------------------------- */ - -Ewald::~Ewald() -{ - deallocate(); - memory->destroy_2d_double_array(ek); - memory->destroy_3d_double_array(cs,-kmax_created); - memory->destroy_3d_double_array(sn,-kmax_created); -} - -/* ---------------------------------------------------------------------- */ - -void Ewald::init() -{ - if (comm->me == 0) { - if (screen) fprintf(screen,"Ewald initialization ...\n"); - if (logfile) fprintf(logfile,"Ewald initialization ...\n"); - } - - // error check - - if (force->dimension == 2) error->all("Cannot use Ewald with 2d simulation"); - - if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with Ewald"); - if (slabflag == 1) { - if (domain->xperiodic != 1 || domain->yperiodic != 1 || - domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab Ewald"); - } - - // insure use of pair_style with long-range Coulombics - // set cutoff to short-range Coulombic cutoff - - qqrd2e = force->qqrd2e; - - double cutoff; - - Pair *anypair; - if (force->pair == NULL) - error->all("KSpace style is incompatible with Pair style"); - else if (anypair = force->pair_match("buck/coul/long")) - cutoff = ((PairBuckCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/cut/coul/long")) - cutoff = ((PairLJCutCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/charmm/coul/long")) - cutoff = ((PairLJCharmmCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/class2/coul/long")) - cutoff = ((PairLJClass2CoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("table")) - cutoff = ((PairTable *) anypair)->cut_coul(); - else error->all("KSpace style is incompatible with Pair style"); - - // compute qsum & qsqsum - - double tmp; - - qsum = 0.0; - for (int i = 0; i < atom->nlocal; i++) qsum += atom->q[i]; - MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world); - qsum = tmp; - - qsqsum = 0.0; - for (int i = 0; i < atom->nlocal; i++) qsqsum += atom->q[i]*atom->q[i]; - MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world); - qsqsum = tmp; - - // setup K-space resolution - - g_ewald = (1.35 - 0.15*log(precision))/cutoff; - gsqmx = -4.0*g_ewald*g_ewald*log(precision); - - if (comm->me == 0) { - if (screen) fprintf(screen," G vector = %g\n",g_ewald); - if (logfile) fprintf(logfile," G vector = %g\n",g_ewald); - } -} - -/* ---------------------------------------------------------------------- - adjust Ewald coeffs, called initially and whenever volume has changed -------------------------------------------------------------------------- */ - -void Ewald::setup() -{ - // volume-dependent factors - - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - - // adjustment of z dimension for 2d slab Ewald - // 3d Ewald just uses zprd since slab_volfactor = 1.0 - - double zprd_slab = zprd*slab_volfactor; - volume = xprd * yprd * zprd_slab; - - unitk[0] = 2.0*PI/xprd; - unitk[1] = 2.0*PI/yprd; - unitk[2] = 2.0*PI/zprd_slab; - - // determine kmax - // function of current box size, precision, G_ewald (short-range cutoff) - - int nkxmx = static_cast ((g_ewald*xprd/PI) * sqrt(-log(precision))); - int nkymx = static_cast ((g_ewald*yprd/PI) * sqrt(-log(precision))); - int nkzmx = static_cast ((g_ewald*zprd_slab/PI) * sqrt(-log(precision))); - - int kmax_old = kmax; - kmax = MAX(nkxmx,nkymx); - kmax = MAX(kmax,nkzmx); - kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; - - // if size has grown, reallocate k-dependent and nlocal-dependent arrays - - if (kmax > kmax_old) { - deallocate(); - allocate(); - - memory->destroy_2d_double_array(ek); - memory->destroy_3d_double_array(cs,-kmax_created); - memory->destroy_3d_double_array(sn,-kmax_created); - nmax = atom->nmax; - ek = memory->create_2d_double_array(nmax,3,"ewald:ek"); - cs = memory->create_3d_double_array(-kmax,kmax,3,nmax,"ewald:cs"); - sn = memory->create_3d_double_array(-kmax,kmax,3,nmax,"ewald:sn"); - kmax_created = kmax; - } - - // pre-compute Ewald coefficients - - int kcount_old = kcount; - coeffs(); - - // if array sizes changed, print out new sizes - - if (kmax != kmax_old || kcount != kcount_old) { - if (comm->me == 0) { - if (screen) fprintf(screen," vectors: actual 1d max = %d %d %d\n", - kcount,kmax,kmax3d); - if (logfile) fprintf(logfile," vectors: actual 1d max = %d %d %d\n", - kcount,kmax,kmax3d); - } - } -} - -/* ---------------------------------------------------------------------- - compute the Ewald long-range force, energy, virial -------------------------------------------------------------------------- */ - -void Ewald::compute(int eflag, int vflag) -{ - int i,k,n; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - // extend size of nlocal-dependent arrays if necessary - - int nlocal = atom->nlocal; - if (nlocal > nmax) { - memory->destroy_2d_double_array(ek); - memory->destroy_3d_double_array(cs,-kmax_created); - memory->destroy_3d_double_array(sn,-kmax_created); - nmax = atom->nmax; - ek = memory->create_2d_double_array(nmax,3,"ewald:ek"); - cs = memory->create_3d_double_array(-kmax,kmax,3,nmax,"ewald:cs"); - sn = memory->create_3d_double_array(-kmax,kmax,3,nmax,"ewald:sn"); - kmax_created = kmax; - } - - // partial structure factors on each processor - // total structure factor by summing over procs - - eik_dot_r(); - MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world); - - // K-space portion of electric field - // double loop over K-vectors and local atoms - - double **f = atom->f; - double *q = atom->q; - - int kx,ky,kz; - double cypz,sypz,exprl,expim,partial; - - for (i = 0; i < nlocal; i++) { - ek[i][0] = 0.0; - ek[i][1] = 0.0; - ek[i][2] = 0.0; - } - - for (k = 0; k < kcount; k++) { - kx = kxvecs[k]; - ky = kyvecs[k]; - kz = kzvecs[k]; - - for (i = 0; i < nlocal; i++) { - cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i]; - sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i]; - exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; - expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; - partial = expim*sfacrl_all[k] - exprl*sfacim_all[k]; - ek[i][0] += partial*eg[k][0]; - ek[i][1] += partial*eg[k][1]; - ek[i][2] += partial*eg[k][2]; - } - } - - // convert E-field to force - - for (i = 0; i < nlocal; i++) { - f[i][0] += qqrd2e*q[i]*ek[i][0]; - f[i][1] += qqrd2e*q[i]*ek[i][1]; - f[i][2] += qqrd2e*q[i]*ek[i][2]; - } - - // energy if requested - - if (eflag) { - for (k = 0; k < kcount; k++) - energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + - sfacim_all[k]*sfacim_all[k]); - PI = 4.0*atan(1.0); - energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); - energy *= qqrd2e; - } - - // virial if requested - - if (vflag) { - double uk; - for (k = 0; k < kcount; k++) { - uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - for (n = 0; n < 6; n++) virial[n] += uk*vg[k][n]; - } - for (n = 0; n < 6; n++) virial[n] *= qqrd2e; - } - - if (slabflag) slabcorr(eflag); - -} - -/* ---------------------------------------------------------------------- */ - -void Ewald::eik_dot_r() -{ - int i,k,l,m,n,ic; - double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; - double sqk,clpm,slpm; - - double **x = atom->x; - double *q = atom->q; - int nlocal = atom->nlocal; - - n = 0; - - // (k,0,0), (0,l,0), (0,0,m) - - for (ic = 0; ic < 3; ic++) { - sqk = unitk[ic]*unitk[ic]; - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - for (i = 0; i < nlocal; i++) { - cs[0][ic][i] = 1.0; - sn[0][ic][i] = 0.0; - cs[1][ic][i] = cos(unitk[ic]*x[i][ic]); - sn[1][ic][i] = sin(unitk[ic]*x[i][ic]); - cs[-1][ic][i] = cs[1][ic][i]; - sn[-1][ic][i] = -sn[1][ic][i]; - cstr1 += q[i]*cs[1][ic][i]; - sstr1 += q[i]*sn[1][ic][i]; - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - } - } - - for (m = 2; m <= kmax; m++) { - for (ic = 0; ic < 3; ic++) { - sqk = m*unitk[ic] * m*unitk[ic]; - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - for (i = 0; i < nlocal; i++) { - cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] - - sn[m-1][ic][i]*sn[1][ic][i]; - sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] + - cs[m-1][ic][i]*sn[1][ic][i]; - cs[-m][ic][i] = cs[m][ic][i]; - sn[-m][ic][i] = -sn[m][ic][i]; - cstr1 += q[i]*cs[m][ic][i]; - sstr1 += q[i]*sn[m][ic][i]; - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - } - } - } - - // 1 = (k,l,0), 2 = (k,-l,0) - - for (k = 1; k <= kmax; k++) { - for (l = 1; l <= kmax; l++) { - sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]); - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - cstr2 = 0.0; - sstr2 = 0.0; - for (i = 0; i < nlocal; i++) { - cstr1 += q[i]*(cs[k][0][i]*cs[l][1][i] - sn[k][0][i]*sn[l][1][i]); - sstr1 += q[i]*(sn[k][0][i]*cs[l][1][i] + cs[k][0][i]*sn[l][1][i]); - cstr2 += q[i]*(cs[k][0][i]*cs[l][1][i] + sn[k][0][i]*sn[l][1][i]); - sstr2 += q[i]*(sn[k][0][i]*cs[l][1][i] - cs[k][0][i]*sn[l][1][i]); - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - sfacrl[n] = cstr2; - sfacim[n++] = sstr2; - } - } - } - - // 1 = (0,l,m), 2 = (0,l,-m) - - for (l = 1; l <= kmax; l++) { - for (m = 1; m <= kmax; m++) { - sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]); - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - cstr2 = 0.0; - sstr2 = 0.0; - for (i = 0; i < nlocal; i++) { - cstr1 += q[i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); - sstr1 += q[i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); - cstr2 += q[i]*(cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]); - sstr2 += q[i]*(sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]); - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - sfacrl[n] = cstr2; - sfacim[n++] = sstr2; - } - } - } - - // 1 = (k,0,m), 2 = (k,0,-m) - - for (k = 1; k <= kmax; k++) { - for (m = 1; m <= kmax; m++) { - sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]); - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - cstr2 = 0.0; - sstr2 = 0.0; - for (i = 0; i < nlocal; i++) { - cstr1 += q[i]*(cs[k][0][i]*cs[m][2][i] - sn[k][0][i]*sn[m][2][i]); - sstr1 += q[i]*(sn[k][0][i]*cs[m][2][i] + cs[k][0][i]*sn[m][2][i]); - cstr2 += q[i]*(cs[k][0][i]*cs[m][2][i] + sn[k][0][i]*sn[m][2][i]); - sstr2 += q[i]*(sn[k][0][i]*cs[m][2][i] - cs[k][0][i]*sn[m][2][i]); - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - sfacrl[n] = cstr2; - sfacim[n++] = sstr2; - } - } - } - - // 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m) - - for (k = 1; k <= kmax; k++) { - for (l = 1; l <= kmax; l++) { - for (m = 1; m <= kmax; m++) { - sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) + - (m*unitk[2] * m*unitk[2]); - if (sqk <= gsqmx) { - cstr1 = 0.0; - sstr1 = 0.0; - cstr2 = 0.0; - sstr2 = 0.0; - cstr3 = 0.0; - sstr3 = 0.0; - cstr4 = 0.0; - sstr4 = 0.0; - for (i = 0; i < nlocal; i++) { - clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; - slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr1 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr1 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - - clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; - slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr2 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr2 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - - clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; - slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr3 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr3 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - - clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; - slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr4 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr4 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - } - sfacrl[n] = cstr1; - sfacim[n++] = sstr1; - sfacrl[n] = cstr2; - sfacim[n++] = sstr2; - sfacrl[n] = cstr3; - sfacim[n++] = sstr3; - sfacrl[n] = cstr4; - sfacim[n++] = sstr4; - } - } - } - } -} - -/* ---------------------------------------------------------------------- - pre-compute coefficients for each Ewald K-vector -------------------------------------------------------------------------- */ - -void Ewald::coeffs() -{ - int k,l,m; - double sqk,vterm; - - double unitkx = unitk[0]; - double unitky = unitk[1]; - double unitkz = unitk[2]; - double g_ewald_sq_inv = 1.0 / (g_ewald*g_ewald); - double preu = 4.0*PI/volume; - - kcount = 0; - - // (k,0,0), (0,l,0), (0,0,m) - - for (m = 1; m <= kmax; m++) { - sqk = (m*unitkx) * (m*unitkx); - if (sqk <= gsqmx) { - kxvecs[kcount] = m; - kyvecs[kcount] = 0; - kzvecs[kcount] = 0; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*m*ug[kcount]; - eg[kcount][1] = 0.0; - eg[kcount][2] = 0.0; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0 + vterm*(unitkx*m)*(unitkx*m); - vg[kcount][1] = 1.0; - vg[kcount][2] = 1.0; - vg[kcount][3] = 0.0; - vg[kcount][4] = 0.0; - vg[kcount][5] = 0.0; - kcount++; - } - sqk = (m*unitky) * (m*unitky); - if (sqk <= gsqmx) { - kxvecs[kcount] = 0; - kyvecs[kcount] = m; - kzvecs[kcount] = 0; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 0.0; - eg[kcount][1] = 2.0*unitky*m*ug[kcount]; - eg[kcount][2] = 0.0; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0; - vg[kcount][1] = 1.0 + vterm*(unitky*m)*(unitky*m); - vg[kcount][2] = 1.0; - vg[kcount][3] = 0.0; - vg[kcount][4] = 0.0; - vg[kcount][5] = 0.0; - kcount++; - } - sqk = (m*unitkz) * (m*unitkz); - if (sqk <= gsqmx) { - kxvecs[kcount] = 0; - kyvecs[kcount] = 0; - kzvecs[kcount] = m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 0.0; - eg[kcount][1] = 0.0; - eg[kcount][2] = 2.0*unitkz*m*ug[kcount]; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0; - vg[kcount][1] = 1.0; - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = 0.0; - vg[kcount][4] = 0.0; - vg[kcount][5] = 0.0; - kcount++; - } - } - - // 1 = (k,l,0), 2 = (k,-l,0) - - for (k = 1; k <= kmax; k++) { - for (l = 1; l <= kmax; l++) { - sqk = (unitkx*k) * (unitkx*k) + (unitky*l) * (unitky*l); - if (sqk <= gsqmx) { - kxvecs[kcount] = k; - kyvecs[kcount] = l; - kzvecs[kcount] = 0; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = 2.0*unitky*l*ug[kcount]; - eg[kcount][2] = 0.0; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0; - vg[kcount][3] = vterm*unitkx*k*unitky*l; - vg[kcount][4] = 0.0; - vg[kcount][5] = 0.0; - kcount++; - - kxvecs[kcount] = k; - kyvecs[kcount] = -l; - kzvecs[kcount] = 0; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = -2.0*unitky*l*ug[kcount]; - eg[kcount][2] = 0.0; - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0; - vg[kcount][3] = -vterm*unitkx*k*unitky*l; - vg[kcount][4] = 0.0; - vg[kcount][5] = 0.0; - kcount++;; - } - } - } - - // 1 = (0,l,m), 2 = (0,l,-m) - - for (l = 1; l <= kmax; l++) { - for (m = 1; m <= kmax; m++) { - sqk = (unitky*l) * (unitky*l) + (unitkz*m) * (unitkz*m); - if (sqk <= gsqmx) { - kxvecs[kcount] = 0; - kyvecs[kcount] = l; - kzvecs[kcount] = m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 0.0; - eg[kcount][1] = 2.0*unitky*l*ug[kcount]; - eg[kcount][2] = 2.0*unitkz*m*ug[kcount]; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0; - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = 0.0; - vg[kcount][4] = 0.0; - vg[kcount][5] = vterm*unitky*l*unitkz*m; - kcount++; - - kxvecs[kcount] = 0; - kyvecs[kcount] = l; - kzvecs[kcount] = -m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 0.0; - eg[kcount][1] = 2.0*unitky*l*ug[kcount]; - eg[kcount][2] = -2.0*unitkz*m*ug[kcount]; - vg[kcount][0] = 1.0; - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = 0.0; - vg[kcount][4] = 0.0; - vg[kcount][5] = -vterm*unitky*l*unitkz*m; - kcount++; - } - } - } - - // 1 = (k,0,m), 2 = (k,0,-m) - - for (k = 1; k <= kmax; k++) { - for (m = 1; m <= kmax; m++) { - sqk = (unitkx*k) * (unitkx*k) + (unitkz*m) * (unitkz*m); - if (sqk <= gsqmx) { - kxvecs[kcount] = k; - kyvecs[kcount] = 0; - kzvecs[kcount] = m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = 0.0; - eg[kcount][2] = 2.0*unitkz*m*ug[kcount]; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0; - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = 0.0; - vg[kcount][4] = vterm*unitkx*k*unitkz*m; - vg[kcount][5] = 0.0; - kcount++; - - kxvecs[kcount] = k; - kyvecs[kcount] = 0; - kzvecs[kcount] = -m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = 0.0; - eg[kcount][2] = -2.0*unitkz*m*ug[kcount]; - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0; - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = 0.0; - vg[kcount][4] = -vterm*unitkx*k*unitkz*m; - vg[kcount][5] = 0.0; - kcount++; - } - } - } - - // 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m) - - for (k = 1; k <= kmax; k++) { - for (l = 1; l <= kmax; l++) { - for (m = 1; m <= kmax; m++) { - sqk = (unitkx*k) * (unitkx*k) + (unitky*l) * (unitky*l) + - (unitkz*m) * (unitkz*m); - if (sqk <= gsqmx) { - kxvecs[kcount] = k; - kyvecs[kcount] = l; - kzvecs[kcount] = m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = 2.0*unitky*l*ug[kcount]; - eg[kcount][2] = 2.0*unitkz*m*ug[kcount]; - vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv); - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = vterm*unitkx*k*unitky*l; - vg[kcount][4] = vterm*unitkx*k*unitkz*m; - vg[kcount][5] = vterm*unitky*l*unitkz*m; - kcount++; - - kxvecs[kcount] = k; - kyvecs[kcount] = -l; - kzvecs[kcount] = m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = -2.0*unitky*l*ug[kcount]; - eg[kcount][2] = 2.0*unitkz*m*ug[kcount]; - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = -vterm*unitkx*k*unitky*l; - vg[kcount][4] = vterm*unitkx*k*unitkz*m; - vg[kcount][5] = -vterm*unitky*l*unitkz*m; - kcount++; - - kxvecs[kcount] = k; - kyvecs[kcount] = l; - kzvecs[kcount] = -m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = 2.0*unitky*l*ug[kcount]; - eg[kcount][2] = -2.0*unitkz*m*ug[kcount]; - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = vterm*unitkx*k*unitky*l; - vg[kcount][4] = -vterm*unitkx*k*unitkz*m; - vg[kcount][5] = -vterm*unitky*l*unitkz*m; - kcount++; - - kxvecs[kcount] = k; - kyvecs[kcount] = -l; - kzvecs[kcount] = -m; - ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk; - eg[kcount][0] = 2.0*unitkx*k*ug[kcount]; - eg[kcount][1] = -2.0*unitky*l*ug[kcount]; - eg[kcount][2] = -2.0*unitkz*m*ug[kcount]; - vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k); - vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l); - vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m); - vg[kcount][3] = -vterm*unitkx*k*unitky*l; - vg[kcount][4] = -vterm*unitkx*k*unitkz*m; - vg[kcount][5] = vterm*unitky*l*unitkz*m; - kcount++;; - } - } - } - } -} - -/* ---------------------------------------------------------------------- - allocate memory that depends on # of K-vectors -------------------------------------------------------------------------- */ - -void Ewald::allocate() -{ - kxvecs = new int[kmax3d]; - kyvecs = new int[kmax3d]; - kzvecs = new int[kmax3d]; - - ug = new double[kmax3d]; - eg = memory->create_2d_double_array(kmax3d,3,"ewald:eg"); - vg = memory->create_2d_double_array(kmax3d,6,"ewald:vg"); - - sfacrl = new double[kmax3d]; - sfacim = new double[kmax3d]; - sfacrl_all = new double[kmax3d]; - sfacim_all = new double[kmax3d]; -} - -/* ---------------------------------------------------------------------- - deallocate memory that depends on # of K-vectors -------------------------------------------------------------------------- */ - -void Ewald::deallocate() -{ - delete [] kxvecs; - delete [] kyvecs; - delete [] kzvecs; - - delete [] ug; - memory->destroy_2d_double_array(eg); - memory->destroy_2d_double_array(vg); - - delete [] sfacrl; - delete [] sfacim; - delete [] sfacrl_all; - delete [] sfacim_all; -} - -/* ---------------------------------------------------------------------- - Slab-geometry correction term to dampen inter-slab interactions between - periodically repeating slabs. Yields good approximation to 2-D Ewald if - adequate empty space is left between repeating slabs (J. Chem. Phys. - 111, 3155). Slabs defined here to be parallel to the xy plane. -------------------------------------------------------------------------- */ - -void Ewald::slabcorr(int eflag) -{ - // compute local contribution to global dipole moment - - double *q = atom->q; - double **x = atom->x; - int nlocal = atom->nlocal; - - double dipole = 0.0; - for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2]; - - // sum local contributions to get global dipole moment - - double dipole_all; - MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); - - // compute corrections - - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; - - if (eflag) energy += qqrd2e*e_slabcorr; - - // add on force corrections - - double ffact = -4.0*PI*dipole_all/volume; - double **f = atom->f; - - for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*q[i]*ffact; -} - -/* ---------------------------------------------------------------------- - memory usage of local arrays -------------------------------------------------------------------------- */ - -int Ewald::memory_usage() -{ - int bytes = 3 * kmax3d * sizeof(int); - bytes += (1 + 3 + 6) * kmax3d * sizeof(double); - bytes += 4 * kmax3d * sizeof(double); - bytes += nmax*3 * sizeof(double); - bytes += 2 * (2*kmax+1)*3*nmax * sizeof(double); - return bytes; -} diff --git a/src/ewald.h b/src/ewald.h deleted file mode 100644 index cbd28c5693..0000000000 --- a/src/ewald.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 EWALD_H -#define EWALD_H - -#include "kspace.h" - -class Ewald : public KSpace { - public: - Ewald(int, char **); - ~Ewald(); - void init(); - void setup(); - void compute(int, int); - int memory_usage(); - - private: - double PI; - double precision; - int kcount,kmax,kmax3d,kmax_created; - double qqrd2e; - double gsqmx,qsum,qsqsum,volume; - int nmax; - - double unitk[3]; - int *kxvecs,*kyvecs,*kzvecs; - double *ug; - double **eg,**vg; - double **ek; - double *sfacrl,*sfacim,*sfacrl_all,*sfacim_all; - double ***cs,***sn; - - void eik_dot_r(); - void coeffs(); - void allocate(); - void deallocate(); - void slabcorr(int); -}; - -#endif - diff --git a/src/fft3d.cpp b/src/fft3d.cpp deleted file mode 100644 index 3af1923d15..0000000000 --- a/src/fft3d.cpp +++ /dev/null @@ -1,999 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Jim Shepherd (GA Tech) added SGI SCSL support -------------------------------------------------------------------------- */ - -#include "mpi.h" -#include "stdio.h" -#include "stdlib.h" -#include "math.h" -#include "fft3d.h" -#include "remap.h" - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -/* ---------------------------------------------------------------------- - Data layout for 3d FFTs: - - data set of Nfast x Nmid x Nslow elements is owned by P procs - on input, each proc owns a subsection of the elements - on output, each proc will own a (possibly different) subsection - my subsection must not overlap with any other proc's subsection, - i.e. the union of all proc's input (or output) subsections must - exactly tile the global Nfast x Nmid x Nslow data set - when called from C, all subsection indices are - C-style from 0 to N-1 where N = Nfast or Nmid or Nslow - when called from F77, all subsection indices are - F77-style from 1 to N where N = Nfast or Nmid or Nslow - a proc can own 0 elements on input or output - by specifying hi index < lo index - on both input and output, data is stored contiguously on a processor - with a fast-varying, mid-varying, and slow-varying index -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Perform 3d FFT - - Arguments: - in starting address of input data on this proc - out starting address of where output data for this proc - will be placed (can be same as in) - flag 1 for forward FFT, -1 for inverse FFT - plan plan returned by previous call to fft_3d_create_plan -------------------------------------------------------------------------- */ - -void fft_3d(FFT_DATA *in, FFT_DATA *out, int flag, struct fft_plan_3d *plan) -{ - int i,total,length,offset,num; - double norm; - FFT_DATA *data,*copy; - - // system specific constants - -#ifdef FFT_SCSL - int isys = 0; - FFT_PREC scalef = 1.0; -#endif -#ifdef FFT_DEC - char c = 'C'; - char f = 'F'; - char b = 'B'; - int one = 1; -#endif -#ifdef FFT_T3E - int isys = 0; - double scalef = 1.0; -#endif - - // pre-remap to prepare for 1st FFTs if needed - // copy = loc for remap result - - if (plan->pre_plan) { - if (plan->pre_target == 0) copy = out; - else copy = plan->copy; - remap_3d((double *) in, (double *) copy, (double *) plan->scratch, - plan->pre_plan); - data = copy; - } - else - data = in; - - // 1d FFTs along fast axis - - total = plan->total1; - length = plan->length1; - -#ifdef FFT_SGI - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,&data[offset],1,plan->coeff1); -#endif -#ifdef FFT_SCSL - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff1, - plan->work1,&isys); -#endif -#ifdef FFT_INTEL - for (offset = 0; offset < total; offset += length) - FFT_1D(&data[offset],&length,&flag,plan->coeff1); -#endif -#ifdef FFT_DEC - if (flag == -1) - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one); - else - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one); -#endif -#ifdef FFT_T3E - for (offset = 0; offset < total; offset += length) - FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff1, - plan->work1,&isys); -#endif -#ifdef FFT_FFTW - if (flag == -1) - fftw(plan->plan_fast_forward,total/length,data,1,length,NULL,0,0); - else - fftw(plan->plan_fast_backward,total/length,data,1,length,NULL,0,0); -#endif - - // 1st mid-remap to prepare for 2nd FFTs - // copy = loc for remap result - - if (plan->mid1_target == 0) copy = out; - else copy = plan->copy; - remap_3d((double *) data, (double *) copy, (double *) plan->scratch, - plan->mid1_plan); - data = copy; - - // 1d FFTs along mid axis - - total = plan->total2; - length = plan->length2; - -#ifdef FFT_SGI - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,&data[offset],1,plan->coeff2); -#endif -#ifdef FFT_SCSL - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff2, - plan->work2,&isys); -#endif -#ifdef FFT_INTEL - for (offset = 0; offset < total; offset += length) - FFT_1D(&data[offset],&length,&flag,plan->coeff2); -#endif -#ifdef FFT_DEC - if (flag == -1) - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one); - else - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one); -#endif -#ifdef FFT_T3E - for (offset = 0; offset < total; offset += length) - FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff2, - plan->work2,&isys); -#endif -#ifdef FFT_FFTW - if (flag == -1) - fftw(plan->plan_mid_forward,total/length,data,1,length,NULL,0,0); - else - fftw(plan->plan_mid_backward,total/length,data,1,length,NULL,0,0); -#endif - - // 2nd mid-remap to prepare for 3rd FFTs - // copy = loc for remap result - - if (plan->mid2_target == 0) copy = out; - else copy = plan->copy; - remap_3d((double *) data, (double *) copy, (double *) plan->scratch, - plan->mid2_plan); - data = copy; - - // 1d FFTs along slow axis - - total = plan->total3; - length = plan->length3; - -#ifdef FFT_SGI - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,&data[offset],1,plan->coeff3); -#endif -#ifdef FFT_SCSL - for (offset = 0; offset < total; offset += length) - FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff3, - plan->work3,&isys); -#endif -#ifdef FFT_INTEL - for (offset = 0; offset < total; offset += length) - FFT_1D(&data[offset],&length,&flag,plan->coeff3); -#endif -#ifdef FFT_DEC - if (flag == -1) - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one); - else - for (offset = 0; offset < total; offset += length) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one); -#endif -#ifdef FFT_T3E - for (offset = 0; offset < total; offset += length) - FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff3, - plan->work3,&isys); -#endif -#ifdef FFT_FFTW - if (flag == -1) - fftw(plan->plan_slow_forward,total/length,data,1,length,NULL,0,0); - else - fftw(plan->plan_slow_backward,total/length,data,1,length,NULL,0,0); -#endif - - // post-remap to put data in output format if needed - // destination is always out - - if (plan->post_plan) - remap_3d((double *) data, (double *) out, (double *) plan->scratch, - plan->post_plan); - - // scaling if required - -#ifndef FFT_T3E - if (flag == 1 && plan->scaled) { - norm = plan->norm; - num = plan->normnum; - for (i = 0; i < num; i++) { - out[i].re *= norm; - out[i].im *= norm; - } - } -#endif - -#ifdef FFT_T3E - if (flag == 1 && plan->scaled) { - norm = plan->norm; - num = plan->normnum; - for (i = 0; i < num; i++) out[i] *= (norm,norm); - } -#endif -} - -/* ---------------------------------------------------------------------- - Create plan for performing a 3d FFT - - Arguments: - comm MPI communicator for the P procs which own the data - nfast,nmid,nslow size of global 3d matrix - in_ilo,in_ihi input bounds of data I own in fast index - in_jlo,in_jhi input bounds of data I own in mid index - in_klo,in_khi input bounds of data I own in slow index - out_ilo,out_ihi output bounds of data I own in fast index - out_jlo,out_jhi output bounds of data I own in mid index - out_klo,out_khi output bounds of data I own in slow index - scaled 0 = no scaling of result, 1 = scaling - permute permutation in storage order of indices on output - 0 = no permutation - 1 = permute once = mid->fast, slow->mid, fast->slow - 2 = permute twice = slow->fast, fast->mid, mid->slow - nbuf returns size of internal storage buffers used by FFT -------------------------------------------------------------------------- */ - -struct fft_plan_3d *fft_3d_create_plan( - MPI_Comm comm, int nfast, int nmid, int nslow, - int in_ilo, int in_ihi, int in_jlo, int in_jhi, - int in_klo, int in_khi, - int out_ilo, int out_ihi, int out_jlo, int out_jhi, - int out_klo, int out_khi, - int scaled, int permute, int *nbuf) -{ - struct fft_plan_3d *plan; - int me,nprocs; - int i,num,flag,remapflag,fftflag; - int first_ilo,first_ihi,first_jlo,first_jhi,first_klo,first_khi; - int second_ilo,second_ihi,second_jlo,second_jhi,second_klo,second_khi; - int third_ilo,third_ihi,third_jlo,third_jhi,third_klo,third_khi; - int out_size,first_size,second_size,third_size,copy_size,scratch_size; - int np1,np2,ip1,ip2; - int list[50]; - - // system specific variables - -#ifdef FFT_SCSL - FFT_DATA dummy_d[5]; - FFT_PREC dummy_p[5]; - int isign,isys; - FFT_PREC scalef; -#endif -#ifdef FFT_INTEL - FFT_DATA dummy; -#endif -#ifdef FFT_T3E - FFT_DATA dummy[5]; - int isign,isys; - double scalef; -#endif - - // query MPI info - - MPI_Comm_rank(comm,&me); - MPI_Comm_size(comm,&nprocs); - -#ifdef FFT_NONE - if (me == 0) { - printf("ERROR: Cannot use FFTs with FFT_NONE set\n"); - return NULL; - } -#endif - - // compute division of procs in 2 dimensions not on-processor - - bifactor(nprocs,&np1,&np2); - ip1 = me % np1; - ip2 = me/np1; - - // allocate memory for plan data struct - - plan = (struct fft_plan_3d *) malloc(sizeof(struct fft_plan_3d)); - if (plan == NULL) return NULL; - - // remap from initial distribution to layout needed for 1st set of 1d FFTs - // not needed if all procs own entire fast axis initially - // first indices = distribution after 1st set of FFTs - - if (in_ilo == 0 && in_ihi == nfast-1) - flag = 0; - else - flag = 1; - - MPI_Allreduce(&flag,&remapflag,1,MPI_INT,MPI_MAX,comm); - - if (remapflag == 0) { - first_ilo = in_ilo; - first_ihi = in_ihi; - first_jlo = in_jlo; - first_jhi = in_jhi; - first_klo = in_klo; - first_khi = in_khi; - plan->pre_plan = NULL; - } - else { - first_ilo = 0; - first_ihi = nfast - 1; - first_jlo = ip1*nmid/np1; - first_jhi = (ip1+1)*nmid/np1 - 1; - first_klo = ip2*nslow/np2; - first_khi = (ip2+1)*nslow/np2 - 1; - plan->pre_plan = - remap_3d_create_plan(comm,in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, - first_ilo,first_ihi,first_jlo,first_jhi, - first_klo,first_khi, - FFT_PRECISION,0,0,2); - if (plan->pre_plan == NULL) return NULL; - } - - // 1d FFTs along fast axis - - plan->length1 = nfast; - plan->total1 = nfast * (first_jhi-first_jlo+1) * (first_khi-first_klo+1); - - // remap from 1st to 2nd FFT - // choose which axis is split over np1 vs np2 to minimize communication - // second indices = distribution after 2nd set of FFTs - - second_ilo = ip1*nfast/np1; - second_ihi = (ip1+1)*nfast/np1 - 1; - second_jlo = 0; - second_jhi = nmid - 1; - second_klo = ip2*nslow/np2; - second_khi = (ip2+1)*nslow/np2 - 1; - plan->mid1_plan = - remap_3d_create_plan(comm, - first_ilo,first_ihi,first_jlo,first_jhi, - first_klo,first_khi, - second_ilo,second_ihi,second_jlo,second_jhi, - second_klo,second_khi, - FFT_PRECISION,1,0,2); - if (plan->mid1_plan == NULL) return NULL; - - // 1d FFTs along mid axis - - plan->length2 = nmid; - plan->total2 = (second_ihi-second_ilo+1) * nmid * (second_khi-second_klo+1); - - // remap from 2nd to 3rd FFT - // if final distribution is permute=2 with all procs owning entire slow axis - // then this remapping goes directly to final distribution - // third indices = distribution after 3rd set of FFTs - - if (permute == 2 && out_klo == 0 && out_khi == nslow-1) - flag = 0; - else - flag = 1; - - MPI_Allreduce(&flag,&remapflag,1,MPI_INT,MPI_MAX,comm); - - if (remapflag == 0) { - third_ilo = out_ilo; - third_ihi = out_ihi; - third_jlo = out_jlo; - third_jhi = out_jhi; - third_klo = out_klo; - third_khi = out_khi; - } - else { - third_ilo = ip1*nfast/np1; - third_ihi = (ip1+1)*nfast/np1 - 1; - third_jlo = ip2*nmid/np2; - third_jhi = (ip2+1)*nmid/np2 - 1; - third_klo = 0; - third_khi = nslow - 1; - } - - plan->mid2_plan = - remap_3d_create_plan(comm, - second_jlo,second_jhi,second_klo,second_khi, - second_ilo,second_ihi, - third_jlo,third_jhi,third_klo,third_khi, - third_ilo,third_ihi, - FFT_PRECISION,1,0,2); - if (plan->mid2_plan == NULL) return NULL; - - // 1d FFTs along slow axis - - plan->length3 = nslow; - plan->total3 = (third_ihi-third_ilo+1) * (third_jhi-third_jlo+1) * nslow; - - // remap from 3rd FFT to final distribution - // not needed if permute = 2 and third indices = out indices on all procs - - if (permute == 2 && - out_ilo == third_ilo && out_ihi == third_ihi && - out_jlo == third_jlo && out_jhi == third_jhi && - out_klo == third_klo && out_khi == third_khi) - flag = 0; - else - flag = 1; - - MPI_Allreduce(&flag,&remapflag,1,MPI_INT,MPI_MAX,comm); - - if (remapflag == 0) - plan->post_plan = NULL; - else { - plan->post_plan = - remap_3d_create_plan(comm, - third_klo,third_khi,third_ilo,third_ihi, - third_jlo,third_jhi, - out_klo,out_khi,out_ilo,out_ihi, - out_jlo,out_jhi, - FFT_PRECISION,(permute+1)%3,0,2); - if (plan->post_plan == NULL) return NULL; - } - - // configure plan memory pointers and allocate work space - // out_size = amount of memory given to FFT by user - // first/second/third_size = amount of memory needed after pre,mid1,mid2 remaps - // copy_size = amount needed internally for extra copy of data - // scratch_size = amount needed internally for remap scratch space - // for each remap: - // out space used for result if big enough, else require copy buffer - // accumulate largest required remap scratch space - - out_size = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * (out_khi-out_klo+1); - first_size = (first_ihi-first_ilo+1) * (first_jhi-first_jlo+1) * - (first_khi-first_klo+1); - second_size = (second_ihi-second_ilo+1) * (second_jhi-second_jlo+1) * - (second_khi-second_klo+1); - third_size = (third_ihi-third_ilo+1) * (third_jhi-third_jlo+1) * - (third_khi-third_klo+1); - - copy_size = 0; - scratch_size = 0; - - if (plan->pre_plan) { - if (first_size <= out_size) - plan->pre_target = 0; - else { - plan->pre_target = 1; - copy_size = MAX(copy_size,first_size); - } - scratch_size = MAX(scratch_size,first_size); - } - - if (plan->mid1_plan) { - if (second_size <= out_size) - plan->mid1_target = 0; - else { - plan->mid1_target = 1; - copy_size = MAX(copy_size,second_size); - } - scratch_size = MAX(scratch_size,second_size); - } - - if (plan->mid2_plan) { - if (third_size <= out_size) - plan->mid2_target = 0; - else { - plan->mid2_target = 1; - copy_size = MAX(copy_size,third_size); - } - scratch_size = MAX(scratch_size,third_size); - } - - if (plan->post_plan) - scratch_size = MAX(scratch_size,out_size); - - *nbuf = copy_size + scratch_size; - - if (copy_size) { - plan->copy = (FFT_DATA *) malloc(copy_size*sizeof(FFT_DATA)); - if (plan->copy == NULL) return NULL; - } - else plan->copy = NULL; - - if (scratch_size) { - plan->scratch = (FFT_DATA *) malloc(scratch_size*sizeof(FFT_DATA)); - if (plan->scratch == NULL) return NULL; - } - else plan->scratch = NULL; - - // system specific pre-computation of 1d FFT coeffs - // and scaling normalization - -#ifdef FFT_SGI - - plan->coeff1 = (FFT_DATA *) malloc((nfast+15)*sizeof(FFT_DATA)); - plan->coeff2 = (FFT_DATA *) malloc((nmid+15)*sizeof(FFT_DATA)); - plan->coeff3 = (FFT_DATA *) malloc((nslow+15)*sizeof(FFT_DATA)); - - if (plan->coeff1 == NULL || plan->coeff2 == NULL || - plan->coeff3 == NULL) return NULL; - - FFT_1D_INIT(nfast,plan->coeff1); - FFT_1D_INIT(nmid,plan->coeff2); - FFT_1D_INIT(nslow,plan->coeff3); - - if (scaled == 0) - plan->scaled = 0; - else { - plan->scaled = 1; - plan->norm = 1.0/(nfast*nmid*nslow); - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - -#endif - -#ifdef FFT_SCSL - - plan->coeff1 = (FFT_PREC *) malloc((2*nfast+30)*sizeof(FFT_PREC)); - plan->coeff2 = (FFT_PREC *) malloc((2*nmid+30)*sizeof(FFT_PREC)); - plan->coeff3 = (FFT_PREC *) malloc((2*nslow+30)*sizeof(FFT_PREC)); - - if (plan->coeff1 == NULL || plan->coeff2 == NULL || - plan->coeff3 == NULL) return NULL; - - plan->work1 = (FFT_PREC *) malloc((2*nfast)*sizeof(FFT_PREC)); - plan->work2 = (FFT_PREC *) malloc((2*nmid)*sizeof(FFT_PREC)); - plan->work3 = (FFT_PREC *) malloc((2*nslow)*sizeof(FFT_PREC)); - - if (plan->work1 == NULL || plan->work2 == NULL || - plan->work3 == NULL) return NULL; - - isign = 0; - scalef = 1.0; - isys = 0; - - FFT_1D_INIT(isign,nfast,scalef,dummy_d,dummy_d,plan->coeff1,dummy_p,&isys); - FFT_1D_INIT(isign,nmid,scalef,dummy_d,dummy_d,plan->coeff2,dummy_p,&isys); - FFT_1D_INIT(isign,nslow,scalef,dummy_d,dummy_d,plan->coeff3,dummy_p,&isys); - - if (scaled == 0) - plan->scaled = 0; - else { - plan->scaled = 1; - plan->norm = 1.0/(nfast*nmid*nslow); - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - -#endif - -#ifdef FFT_INTEL - - flag = 0; - - num = 0; - factor(nfast,&num,list); - for (i = 0; i < num; i++) - if (list[i] != 2 && list[i] != 3 && list[i] != 5) flag = 1; - num = 0; - factor(nmid,&num,list); - for (i = 0; i < num; i++) - if (list[i] != 2 && list[i] != 3 && list[i] != 5) flag = 1; - num = 0; - factor(nslow,&num,list); - for (i = 0; i < num; i++) - if (list[i] != 2 && list[i] != 3 && list[i] != 5) flag = 1; - - MPI_Allreduce(&flag,&fftflag,1,MPI_INT,MPI_MAX,comm); - if (fftflag) { - if (me == 0) printf("ERROR: FFTs are not power of 2,3,5\n"); - return NULL; - } - - plan->coeff1 = (FFT_DATA *) malloc((3*nfast/2+1)*sizeof(FFT_DATA)); - plan->coeff2 = (FFT_DATA *) malloc((3*nmid/2+1)*sizeof(FFT_DATA)); - plan->coeff3 = (FFT_DATA *) malloc((3*nslow/2+1)*sizeof(FFT_DATA)); - - if (plan->coeff1 == NULL || plan->coeff2 == NULL || - plan->coeff3 == NULL) return NULL; - - flag = 0; - FFT_1D_INIT(&dummy,&nfast,&flag,plan->coeff1); - FFT_1D_INIT(&dummy,&nmid,&flag,plan->coeff2); - FFT_1D_INIT(&dummy,&nslow,&flag,plan->coeff3); - - if (scaled == 0) { - plan->scaled = 1; - plan->norm = nfast*nmid*nslow; - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - else - plan->scaled = 0; - -#endif - -#ifdef FFT_DEC - - if (scaled == 0) { - plan->scaled = 1; - plan->norm = nfast*nmid*nslow; - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - else - plan->scaled = 0; - -#endif - -#ifdef FFT_T3E - - plan->coeff1 = (double *) malloc((12*nfast)*sizeof(double)); - plan->coeff2 = (double *) malloc((12*nmid)*sizeof(double)); - plan->coeff3 = (double *) malloc((12*nslow)*sizeof(double)); - - if (plan->coeff1 == NULL || plan->coeff2 == NULL || - plan->coeff3 == NULL) return NULL; - - plan->work1 = (double *) malloc((8*nfast)*sizeof(double)); - plan->work2 = (double *) malloc((8*nmid)*sizeof(double)); - plan->work3 = (double *) malloc((8*nslow)*sizeof(double)); - - if (plan->work1 == NULL || plan->work2 == NULL || - plan->work3 == NULL) return NULL; - - isign = 0; - scalef = 1.0; - isys = 0; - - FFT_1D_INIT(&isign,&nfast,&scalef,dummy,dummy,plan->coeff1,dummy,&isys); - FFT_1D_INIT(&isign,&nmid,&scalef,dummy,dummy,plan->coeff2,dummy,&isys); - FFT_1D_INIT(&isign,&nslow,&scalef,dummy,dummy,plan->coeff3,dummy,&isys); - - if (scaled == 0) - plan->scaled = 0; - else { - plan->scaled = 1; - plan->norm = 1.0/(nfast*nmid*nslow); - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - -#endif - -#ifdef FFT_FFTW - - plan->plan_fast_forward = - fftw_create_plan(nfast,FFTW_FORWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - plan->plan_fast_backward = - fftw_create_plan(nfast,FFTW_BACKWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - - if (nmid == nfast) { - plan->plan_mid_forward = plan->plan_fast_forward; - plan->plan_mid_backward = plan->plan_fast_backward; - } - else { - plan->plan_mid_forward = - fftw_create_plan(nmid,FFTW_FORWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - plan->plan_mid_backward = - fftw_create_plan(nmid,FFTW_BACKWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - } - - if (nslow == nfast) { - plan->plan_slow_forward = plan->plan_fast_forward; - plan->plan_slow_backward = plan->plan_fast_backward; - } - else if (nslow == nmid) { - plan->plan_slow_forward = plan->plan_mid_forward; - plan->plan_slow_backward = plan->plan_mid_backward; - } - else { - plan->plan_slow_forward = - fftw_create_plan(nslow,FFTW_FORWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - plan->plan_slow_backward = - fftw_create_plan(nslow,FFTW_BACKWARD,FFTW_ESTIMATE | FFTW_IN_PLACE); - } - - if (scaled == 0) - plan->scaled = 0; - else { - plan->scaled = 1; - plan->norm = 1.0/(nfast*nmid*nslow); - plan->normnum = (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1); - } - -#endif - - return plan; -} - -/* ---------------------------------------------------------------------- - Destroy a 3d fft plan -------------------------------------------------------------------------- */ - -void fft_3d_destroy_plan(struct fft_plan_3d *plan) -{ - if (plan->pre_plan) remap_3d_destroy_plan(plan->pre_plan); - if (plan->mid1_plan) remap_3d_destroy_plan(plan->mid1_plan); - if (plan->mid2_plan) remap_3d_destroy_plan(plan->mid2_plan); - if (plan->post_plan) remap_3d_destroy_plan(plan->post_plan); - - if (plan->copy) free(plan->copy); - if (plan->scratch) free(plan->scratch); - -#ifdef FFT_SGI - free(plan->coeff1); - free(plan->coeff2); - free(plan->coeff3); -#endif -#ifdef FFT_SCSL - free(plan->coeff1); - free(plan->coeff2); - free(plan->coeff3); - free(plan->work1); - free(plan->work2); - free(plan->work3); -#endif -#ifdef FFT_INTEL - free(plan->coeff1); - free(plan->coeff2); - free(plan->coeff3); -#endif -#ifdef FFT_T3E - free(plan->coeff1); - free(plan->coeff2); - free(plan->coeff3); - free(plan->work1); - free(plan->work2); - free(plan->work3); -#endif -#ifdef FFT_FFTW - if (plan->plan_slow_forward != plan->plan_mid_forward && - plan->plan_slow_forward != plan->plan_fast_forward) { - fftw_destroy_plan(plan->plan_slow_forward); - fftw_destroy_plan(plan->plan_slow_backward); - } - if (plan->plan_mid_forward != plan->plan_fast_forward) { - fftw_destroy_plan(plan->plan_mid_forward); - fftw_destroy_plan(plan->plan_mid_backward); - } - fftw_destroy_plan(plan->plan_fast_forward); - fftw_destroy_plan(plan->plan_fast_backward); -#endif - - free(plan); -} - -/* ---------------------------------------------------------------------- - recursively divide n into small factors, return them in list -------------------------------------------------------------------------- */ - -void factor(int n, int *num, int *list) -{ - if (n == 1) { - return; - } - else if (n % 2 == 0) { - *list = 2; - (*num)++; - factor(n/2,num,list+1); - } - else if (n % 3 == 0) { - *list = 3; - (*num)++; - factor(n/3,num,list+1); - } - else if (n % 5 == 0) { - *list = 5; - (*num)++; - factor(n/5,num,list+1); - } - else if (n % 7 == 0) { - *list = 7; - (*num)++; - factor(n/7,num,list+1); - } - else if (n % 11 == 0) { - *list = 11; - (*num)++; - factor(n/11,num,list+1); - } - else if (n % 13 == 0) { - *list = 13; - (*num)++; - factor(n/13,num,list+1); - } - else { - *list = n; - (*num)++; - return; - } -} - -/* ---------------------------------------------------------------------- - divide n into 2 factors of as equal size as possible -------------------------------------------------------------------------- */ - -void bifactor(int n, int *factor1, int *factor2) -{ - int n1,n2,facmax; - - facmax = static_cast (sqrt((double) n)); - - for (n1 = facmax; n1 > 0; n1--) { - n2 = n/n1; - if (n1*n2 == n) { - *factor1 = n1; - *factor2 = n2; - return; - } - } -} - -/* ---------------------------------------------------------------------- - perform just the 1d FFTs needed by a 3d FFT, no data movement - used for timing purposes - - Arguments: - in starting address of input data on this proc, all set to 0.0 - nsize size of in - flag 1 for forward FFT, -1 for inverse FFT - plan plan returned by previous call to fft_3d_create_plan -------------------------------------------------------------------------- */ - -void fft_1d_only(FFT_DATA *data, int nsize, int flag, struct fft_plan_3d *plan) -{ - int i,total,length,offset,num; - double norm; - - // system specific constants - -#ifdef FFT_SCSL - int isys = 0; - FFT_PREC scalef = 1.0; -#endif -#ifdef FFT_DEC - char c = 'C'; - char f = 'F'; - char b = 'B'; - int one = 1; -#endif -#ifdef FFT_T3E - int isys = 0; - double scalef = 1.0; -#endif - - // total = size of data needed in each dim - // length = length of 1d FFT in each dim - // total/length = # of 1d FFTs in each dim - // if total > nsize, limit # of 1d FFTs to available size of data - - int total1 = plan->total1; - int length1 = plan->length1; - int total2 = plan->total2; - int length2 = plan->length2; - int total3 = plan->total3; - int length3 = plan->length3; - - if (total1 > nsize) total1 = (nsize/length1) * length1; - if (total2 > nsize) total2 = (nsize/length2) * length2; - if (total3 > nsize) total3 = (nsize/length3) * length3; - - // perform 1d FFTs in each of 3 dimensions - // data is just an array of 0.0 - -#ifdef FFT_SGI - for (offset = 0; offset < total1; offset += length1) - FFT_1D(flag,length1,&data[offset],1,plan->coeff1); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(flag,length2,&data[offset],1,plan->coeff2); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(flag,length3,&data[offset],1,plan->coeff3); -#endif -#ifdef FFT_SCSL - for (offset = 0; offset < total1; offset += length1) - FFT_1D(flag,length1,scalef,&data[offset],&data[offset],plan->coeff1, - plan->work1,&isys); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(flag,length2,scalef,&data[offset],&data[offset],plan->coeff2, - plan->work2,&isys); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(flag,length3,scalef,&data[offset],&data[offset],plan->coeff3, - plan->work3,&isys); -#endif -#ifdef FFT_INTEL - for (offset = 0; offset < total1; offset += length1) - FFT_1D(&data[offset],&length1,&flag,plan->coeff1); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(&data[offset],&length2,&flag,plan->coeff2); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(&data[offset],&length3,&flag,plan->coeff3); -#endif -#ifdef FFT_DEC - if (flag == -1) { - for (offset = 0; offset < total1; offset += length1) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length1,&one); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length2,&one); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length3,&one); - } else { - for (offset = 0; offset < total1; offset += length1) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length1,&one); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length2,&one); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length3,&one); - } -#endif -#ifdef FFT_T3E - for (offset = 0; offset < total1; offset += length1) - FFT_1D(&flag,&length1,&scalef,&data[offset],&data[offset],plan->coeff1, - plan->work1,&isys); - for (offset = 0; offset < total2; offset += length2) - FFT_1D(&flag,&length2,&scalef,&data[offset],&data[offset],plan->coeff2, - plan->work2,&isys); - for (offset = 0; offset < total3; offset += length3) - FFT_1D(&flag,&length3,&scalef,&data[offset],&data[offset],plan->coeff3, - plan->work3,&isys); -#endif -#ifdef FFT_FFTW - if (flag == -1) { - fftw(plan->plan_fast_forward,total1/length1,data,1,0,NULL,0,0); - fftw(plan->plan_mid_forward,total2/length2,data,1,0,NULL,0,0); - fftw(plan->plan_slow_forward,total3/length3,data,1,0,NULL,0,0); - } else { - fftw(plan->plan_fast_backward,total1/length1,data,1,0,NULL,0,0); - fftw(plan->plan_mid_backward,total2/length2,data,1,0,NULL,0,0); - fftw(plan->plan_slow_backward,total3/length3,data,1,0,NULL,0,0); - } -#endif - - // scaling if required - // limit num to size of data - -#ifndef FFT_T3E - if (flag == 1 && plan->scaled) { - norm = plan->norm; - num = MIN(plan->normnum,nsize); - for (i = 0; i < num; i++) { - data[i].re *= norm; - data[i].im *= norm; - } - } -#endif - -#ifdef FFT_T3E - if (flag == 1 && plan->scaled) { - norm = plan->norm; - num = MIN(plan->normnum,nsize); - for (i = 0; i < num; i++) data[i] *= (norm,norm); - } -#endif -} diff --git a/src/fft3d.h b/src/fft3d.h deleted file mode 100644 index eb4a179db3..0000000000 --- a/src/fft3d.h +++ /dev/null @@ -1,242 +0,0 @@ -/* ---------------------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -// User-settable FFT precision - -// FFT_PRECISION = 1 is single-precision complex (4-byte real, 4-byte imag) -// FFT_PRECISION = 2 is double-precision complex (8-byte real, 8-byte imag) - -#define FFT_PRECISION 2 - -// ------------------------------------------------------------------------- - -// Data types for single-precision complex - -#if FFT_PRECISION == 1 - -#ifdef FFT_SGI -#include "fft.h" -typedef complex FFT_DATA; -#define FFT_1D cfft1d -#define FFT_1D_INIT cfft1di -extern "C" { - int cfft1d(int, int, FFT_DATA *, int, FFT_DATA *); - FFT_DATA *cfft1di(int, FFT_DATA *); -} - -#endif - -#ifdef FFT_SCSL -#include -typedef scsl_complex FFT_DATA; -typedef float FFT_PREC; -#define FFT_1D ccfft -#define FFT_1D_INIT ccfft -extern "C" { - int ccfft(int, int, FFT_PREC, FFT_DATA *, FFT_DATA *, - FFT_PREC *, FFT_PREC *, int *); -} - -#endif - -#ifdef FFT_INTEL -typedef struct { - float re; - float im; -} FFT_DATA; -#define FFT_1D cfft1d_ -#define FFT_1D_INIT cfft1d_ -extern "C" { - void cfft1d_(FFT_DATA *, int *, int *, FFT_DATA *); -} -#endif - -#ifdef FFT_DEC -typedef struct { - float re; - float im; -} FFT_DATA; -#define FFT_1D cfft_ -extern "C" { - void cfft_(char *, char *, char *, FFT_DATA *, FFT_DATA *, int *, int *); -} -#endif - -#ifdef FFT_T3E -#include -typedef complex single FFT_DATA; -#define FFT_1D GGFFT -#define FFT_1D_INIT GGFFT -extern "C" { - void GGFFT(int *, int *, double *, FFT_DATA *, FFT_DATA *, - double *, double *, int *); -} -#endif - -#ifdef FFT_FFTW -#include "fftw.h" -typedef FFTW_COMPLEX FFT_DATA; -#endif - -#ifdef FFT_NONE -typedef struct { - float re; - float im; -} FFT_DATA; -#endif - -#endif - -// ------------------------------------------------------------------------- - -// Data types for double-precision complex - -#if FFT_PRECISION == 2 - -#ifdef FFT_SGI -#include "fft.h" -typedef zomplex FFT_DATA; -#define FFT_1D zfft1d -#define FFT_1D_INIT zfft1di -extern "C" { - int zfft1d(int, int, FFT_DATA *, int, FFT_DATA *); - FFT_DATA *zfft1di(int, FFT_DATA *); -} -#endif - -#ifdef FFT_SCSL -#include -typedef scsl_zomplex FFT_DATA; -typedef double FFT_PREC; -#define FFT_1D zzfft -#define FFT_1D_INIT zzfft -extern "C" { - int zzfft(int, int, FFT_PREC, FFT_DATA *, FFT_DATA *, - FFT_PREC *, FFT_PREC *, int *); -} -#endif - -#ifdef FFT_INTEL -typedef struct { - double re; - double im; -} FFT_DATA; -#define FFT_1D zfft1d_ -#define FFT_1D_INIT zfft1d_ -extern "C" { - void zfft1d_(FFT_DATA *, int *, int *, FFT_DATA *); -} -#endif - -#ifdef FFT_DEC -typedef struct { - double re; - double im; -} FFT_DATA; -#define FFT_1D zfft_ -extern "C" { - void zfft_(char *, char *, char *, FFT_DATA *, FFT_DATA *, int *, int *); -} -#endif - -#ifdef FFT_T3E -#include -typedef complex double FFT_DATA; -#define FFT_1D CCFFT -#define FFT_1D_INIT CCFFT -extern "C" { - void CCFFT(int *, int *, double *, FFT_DATA *, FFT_DATA *, - double *, double *, int *); -} -#endif - -#ifdef FFT_FFTW -#include "fftw.h" -typedef FFTW_COMPLEX FFT_DATA; -#endif - -#ifdef FFT_NONE -typedef struct { - double re; - double im; -} FFT_DATA; -#endif - -#endif - -// ------------------------------------------------------------------------- - -// details of how to do a 3d FFT - -struct fft_plan_3d { - struct remap_plan_3d *pre_plan; // remap from input -> 1st FFTs - struct remap_plan_3d *mid1_plan; // remap from 1st -> 2nd FFTs - struct remap_plan_3d *mid2_plan; // remap from 2nd -> 3rd FFTs - struct remap_plan_3d *post_plan; // remap from 3rd FFTs -> output - FFT_DATA *copy; // memory for remap results (if needed) - FFT_DATA *scratch; // scratch space for remaps - int total1,total2,total3; // # of 1st,2nd,3rd FFTs (times length) - int length1,length2,length3; // length of 1st,2nd,3rd FFTs - int pre_target; // where to put remap results - int mid1_target,mid2_target; - int scaled; // whether to scale FFT results - int normnum; // # of values to rescale - double norm; // normalization factor for rescaling - - // system specific 1d FFT info -#ifdef FFT_SGI - FFT_DATA *coeff1; - FFT_DATA *coeff2; - FFT_DATA *coeff3; -#endif -#ifdef FFT_SCSL - FFT_PREC *coeff1; - FFT_PREC *coeff2; - FFT_PREC *coeff3; - FFT_PREC *work1; - FFT_PREC *work2; - FFT_PREC *work3; -#endif -#ifdef FFT_INTEL - FFT_DATA *coeff1; - FFT_DATA *coeff2; - FFT_DATA *coeff3; -#endif -#ifdef FFT_T3E - double *coeff1; - double *coeff2; - double *coeff3; - double *work1; - double *work2; - double *work3; -#endif -#ifdef FFT_FFTW - fftw_plan plan_fast_forward; - fftw_plan plan_fast_backward; - fftw_plan plan_mid_forward; - fftw_plan plan_mid_backward; - fftw_plan plan_slow_forward; - fftw_plan plan_slow_backward; -#endif -}; - -// function prototypes - -void fft_3d(FFT_DATA *, FFT_DATA *, int, struct fft_plan_3d *); -struct fft_plan_3d *fft_3d_create_plan(MPI_Comm, int, int, int, - int, int, int, int, int, int, int, int, int, int, int, int, - int, int, int *); -void fft_3d_destroy_plan(struct fft_plan_3d *); -void factor(int, int *, int *); -void bifactor(int, int *, int *); -void fft_1d_only(FFT_DATA *, int, int, struct fft_plan_3d *); diff --git a/src/fft3d_wrap.cpp b/src/fft3d_wrap.cpp deleted file mode 100644 index af72fdf4a2..0000000000 --- a/src/fft3d_wrap.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "fft3d_wrap.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -FFT3d::FFT3d(MPI_Comm comm, int nfast, int nmid, int nslow, - int in_ilo, int in_ihi, int in_jlo, int in_jhi, - int in_klo, int in_khi, - int out_ilo, int out_ihi, int out_jlo, int out_jhi, - int out_klo, int out_khi, - int scaled, int permute, int *nbuf) -{ - plan = fft_3d_create_plan(comm,nfast,nmid,nslow, - in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, - out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, - scaled,permute,nbuf); - if (plan == NULL) error->one("Could not create 3d FFT plan"); -} - -/* ---------------------------------------------------------------------- */ - -FFT3d::~FFT3d() -{ - fft_3d_destroy_plan(plan); -} - -/* ---------------------------------------------------------------------- */ - -void FFT3d::compute(double *in, double *out, int flag) -{ - fft_3d((FFT_DATA *) in,(FFT_DATA *) out,flag,plan); -} - -/* ---------------------------------------------------------------------- */ - -void FFT3d::timing1d(double *in, int nsize, int flag) -{ - fft_1d_only((FFT_DATA *) in,nsize,flag,plan); -} diff --git a/src/fft3d_wrap.h b/src/fft3d_wrap.h deleted file mode 100644 index 2d32e34626..0000000000 --- a/src/fft3d_wrap.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 FFT3D_WRAP_H -#define FFT3D_WRAP_H - -#include "lammps.h" -#include "fft3d.h" - -class FFT3d : public LAMMPS { - public: - FFT3d(MPI_Comm,int,int,int,int,int,int,int,int,int, - int,int,int,int,int,int,int,int,int *); - ~FFT3d(); - void compute(double *, double *, int); - void timing1d(double *, int, int); - - private: - struct fft_plan_3d *plan; -}; - -#endif diff --git a/src/improper.cpp b/src/improper.cpp deleted file mode 100644 index bf428a62c6..0000000000 --- a/src/improper.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "improper.h" -#include "atom.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -Improper::Improper() -{ - allocated = 0; - PI = 4.0*atan(1.0); -} - -/* ---------------------------------------------------------------------- - check if all coeffs are set -------------------------------------------------------------------------- */ - -void Improper::init() -{ - if (!allocated) error->all("Improper coeffs are not set"); - for (int i = 1; i <= atom->nimpropertypes; i++) - if (setflag[i] == 0) error->all("All improper coeffs are not set"); -} diff --git a/src/improper_cvff.cpp b/src/improper_cvff.cpp deleted file mode 100644 index 2b7a0d111f..0000000000 --- a/src/improper_cvff.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "math.h" -#include "stdlib.h" -#include "improper_cvff.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define TOLERANCE 0.05 -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -ImproperCvff::~ImproperCvff() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(sign); - memory->sfree(multiplicity); - } -} - -/* ---------------------------------------------------------------------- */ - -void ImproperCvff::compute(int eflag, int vflag) -{ - int m,n,i1,i2,i3,i4,type,factor; - double rfactor; - double vb1x,vb1y,vb1z,vb2x,vb2y; - double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; - double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2; - double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; - double c2mag,sc1,sc2,s1,s12,c,p,pd,rc2,a,a11,a22; - double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; - double sz1,sz2,sz12,s2; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **improperlist = neighbor->improperlist; - int nimproperlist = neighbor->nimproperlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nimproperlist; n++) { - - i1 = improperlist[n][0]; - i2 = improperlist[n][1]; - i3 = improperlist[n][2]; - i4 = improperlist[n][3]; - type = improperlist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // 1st bond - - vb1x = x[i1][0] - x[i2][0]; - vb1y = x[i1][1] - x[i2][1]; - vb1z = x[i1][2] - x[i2][2]; - domain->minimum_image(&vb1x,&vb1y,&vb1z); - - // 2nd bond - - vb2x = x[i3][0] - x[i2][0]; - vb2y = x[i3][1] - x[i2][1]; - vb2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&vb2x,&vb2y,&vb2z); - - vb2xm = -vb2x; - vb2ym = -vb2y; - vb2zm = -vb2z; - domain->minimum_image(&vb2xm,&vb2ym,&vb2zm); - - // 3rd bond - - vb3x = x[i4][0] - x[i3][0]; - vb3y = x[i4][1] - x[i3][1]; - vb3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&vb3x,&vb3y,&vb3z); - - // c0 calculation - - sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); - sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); - sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); - - rb1 = sqrt(sb1); - rb3 = sqrt(sb3); - - c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; - - // 1st and 2nd angle - - b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - b1mag = sqrt(b1mag2); - b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; - b2mag = sqrt(b2mag2); - b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - b3mag = sqrt(b3mag2); - - ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; - r12c1 = 1.0 / (b1mag*b2mag); - c1mag = ctmp * r12c1; - - ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; - r12c2 = 1.0 / (b2mag*b3mag); - c2mag = ctmp * r12c2; - - // cos and sin of 2 angles and final c - - sc1 = sqrt(1.0 - c1mag*c1mag); - if (sc1 < SMALL) sc1 = SMALL; - sc1 = 1.0/sc1; - - sc2 = sqrt(1.0 - c2mag*c2mag); - if (sc2 < SMALL) sc2 = SMALL; - sc2 = 1.0/sc2; - - s1 = sc1 * sc1; - s2 = sc2 * sc2; - s12 = sc1 * sc2; - c = (c0 + c1mag*c2mag) * s12; - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - int me; - MPI_Comm_rank(world,&me); - if (screen) { - fprintf(screen,"Improper problem: %d %d %d %d %d %d\n", - me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - // force & energy - // p = 1 + cos(n*phi) for d = 1 - // p = 1 - cos(n*phi) for d = -1 - // pd = dp/dc / 2 - - m = multiplicity[type]; - - if (m == 2) { - p = 2.0*c*c; - pd = 2.0*c; - } else if (m == 3) { - rc2 = c*c; - p = (4.0*rc2-3.0)*c + 1.0; - pd = 6.0*rc2 - 1.5; - } else if (m == 4) { - rc2 = c*c; - p = 8.0*(rc2-1)*rc2 + 2.0; - pd = (16.0*rc2-8.0)*c; - } else if (m == 6) { - rc2 = c*c; - p = ((32.0*rc2-48.0)*rc2 + 18.0)*rc2; - pd = (96.0*(rc2-1.0)*rc2 + 18.0)*c; - } else if (m == 1) { - p = c + 1.0; - pd = 0.5; - } else if (m == 5) { - rc2 = c*c; - p = ((16.0*rc2-20.0)*rc2 + 5.0)*c + 1.0; - pd = (40.0*rc2-30.0)*rc2 + 2.5; - } else if (m == 0) { - p = 2.0; - pd = 0.0; - } - - if (sign[type] == -1) { - p = 2.0 - p; - pd = -pd; - } - - if (eflag) energy += rfactor * k[type] * p; - - a = 2.0 * k[type] * pd; - c = c * a; - s12 = s12 * a; - a11 = (-c*sb1*s1); - a22 = sb2*(2.0*c0*s12 - c*(s1+s2)); - a33 = (-c*sb3*s2); - a12 = r12c1*(c1mag*c*s1 + c2mag*s12); - a13 = rb1*rb3*s12; - a23 = r12c2*(-c2mag*c*s2 - c1mag*s12); - - sx1 = a11*vb1x + a12*vb2x + a13*vb3x; - sx2 = a12*vb1x + a22*vb2x + a23*vb3x; - sx12 = a13*vb1x + a23*vb2x + a33*vb3x; - sy1 = a11*vb1y + a12*vb2y + a13*vb3y; - sy2 = a12*vb1y + a22*vb2y + a23*vb3y; - sy12 = a13*vb1y + a23*vb2y + a33*vb3y; - sz1 = a11*vb1z + a12*vb2z + a13*vb3z; - sz2 = a12*vb1z + a22*vb2z + a23*vb3z; - sz12 = a13*vb1z + a23*vb2z + a33*vb3z; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12); - virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12); - virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12); - virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12); - virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12); - virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void ImproperCvff::allocate() -{ - allocated = 1; - int n = atom->nimpropertypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"improper:k"); - sign = (int *) memory->smalloc((n+1)*sizeof(int),"improper:sign"); - multiplicity = (int *) - memory->smalloc((n+1)*sizeof(int),"improper:multiplicity"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void ImproperCvff::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this improper style"); - if (narg != 4) error->all("Incorrect args for improper coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nimpropertypes,ilo,ihi); - - double k_one = atof(arg[1]); - int sign_one = atoi(arg[2]); - int multiplicity_one = atoi(arg[3]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - sign[i] = sign_one; - multiplicity[i] = multiplicity_one; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for improper coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void ImproperCvff::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nimpropertypes,fp); - fwrite(&sign[1],sizeof(int),atom->nimpropertypes,fp); - fwrite(&multiplicity[1],sizeof(int),atom->nimpropertypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void ImproperCvff::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nimpropertypes,fp); - fread(&sign[1],sizeof(int),atom->nimpropertypes,fp); - fread(&multiplicity[1],sizeof(int),atom->nimpropertypes,fp); - } - MPI_Bcast(&k[1],atom->nimpropertypes,MPI_DOUBLE,0,world); - MPI_Bcast(&sign[1],atom->nimpropertypes,MPI_INT,0,world); - MPI_Bcast(&multiplicity[1],atom->nimpropertypes,MPI_INT,0,world); - - for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1; -} diff --git a/src/improper_cvff.h b/src/improper_cvff.h deleted file mode 100644 index 37225ee501..0000000000 --- a/src/improper_cvff.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 IMPROPER_CVFF_H -#define IMPROPER_CVFF_H - -#include "stdio.h" -#include "improper.h" - -class ImproperCvff : public Improper { - public: - ImproperCvff() {} - ~ImproperCvff(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *k; - int *sign,*multiplicity; - - void allocate(); -}; - -#endif diff --git a/src/improper_harmonic.cpp b/src/improper_harmonic.cpp deleted file mode 100644 index 58b0c58531..0000000000 --- a/src/improper_harmonic.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "math.h" -#include "stdlib.h" -#include "improper_harmonic.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "error.h" - -#define TOLERANCE 0.05 -#define SMALL 0.001 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -ImproperHarmonic::~ImproperHarmonic() -{ - if (allocated) { - memory->sfree(setflag); - memory->sfree(k); - memory->sfree(chi); - } -} - -/* ---------------------------------------------------------------------- */ - -void ImproperHarmonic::compute(int eflag, int vflag) -{ - int n,i1,i2,i3,i4,type,factor; - double rfactor; - double v1x,v1y,v1z,v2x,v2y,v2z,v3x; - double v3y,v3z,ss1,ss2,ss3,r1,r2,r3,c0,c1,c2,s1,s2; - double s12,c,s,domega,a,a11,a22,a33,a12,a13,a23,sx1; - double sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - double **x = atom->x; - double **f = atom->f; - int **improperlist = neighbor->improperlist; - int nimproperlist = neighbor->nimproperlist; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - for (n = 0; n < nimproperlist; n++) { - - i1 = improperlist[n][0]; - i2 = improperlist[n][1]; - i3 = improperlist[n][2]; - i4 = improperlist[n][3]; - type = improperlist[n][4]; - - if (newton_bond) factor = 4; - else { - factor = 0; - if (i1 < nlocal) factor++; - if (i2 < nlocal) factor++; - if (i3 < nlocal) factor++; - if (i4 < nlocal) factor++; - } - rfactor = 0.25 * factor; - - // geometry of 4-body - - v1x = x[i2][0] - x[i1][0]; - v1y = x[i2][1] - x[i1][1]; - v1z = x[i2][2] - x[i1][2]; - domain->minimum_image(&v1x,&v1y,&v1z); - - v2x = x[i3][0] - x[i2][0]; - v2y = x[i3][1] - x[i2][1]; - v2z = x[i3][2] - x[i2][2]; - domain->minimum_image(&v2x,&v2y,&v2z); - - v3x = x[i4][0] - x[i3][0]; - v3y = x[i4][1] - x[i3][1]; - v3z = x[i4][2] - x[i3][2]; - domain->minimum_image(&v3x,&v3y,&v3z); - - ss1 = 1.0 / (v1x*v1x + v1y*v1y + v1z*v1z); - ss2 = 1.0 / (v2x*v2x + v2y*v2y + v2z*v2z); - ss3 = 1.0 / (v3x*v3x + v3y*v3y + v3z*v3z); - - r1 = sqrt(ss1); - r2 = sqrt(ss2); - r3 = sqrt(ss3); - - // sin and cos of angle - - c0 = -(v1x * v3x + v1y * v3y + v1z * v3z) * r1 * r3; - c1 = -(v1x * v2x + v1y * v2y + v1z * v2z) * r1 * r2; - c2 = -(v3x * v2x + v3y * v2y + v3z * v2z) * r3 * r2; - - s1 = 1.0 - c1*c1; - if (s1 < SMALL) s1 = SMALL; - s1 = 1.0 / s1; - - s2 = 1.0 - c2*c2; - if (s2 < SMALL) s2 = SMALL; - s2 = 1.0 / s2; - - s12 = sqrt(s1*s2); - c = (c1*c2 + c0) * s12; - - // error check - - if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { - int me; - MPI_Comm_rank(world,&me); - if (screen) { - fprintf(screen,"Improper problem: %d %d %d %d %d %d\n", - me,update->ntimestep, - atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]); - fprintf(screen," 1st atom: %d %g %g %g\n", - me,x[i1][0],x[i1][1],x[i1][2]); - fprintf(screen," 2nd atom: %d %g %g %g\n", - me,x[i2][0],x[i2][1],x[i2][2]); - fprintf(screen," 3rd atom: %d %g %g %g\n", - me,x[i3][0],x[i3][1],x[i3][2]); - fprintf(screen," 4th atom: %d %g %g %g\n", - me,x[i4][0],x[i4][1],x[i4][2]); - } - } - - if (c > 1.0) c = 1.0; - if (c < -1.0) c = -1.0; - - s = sqrt(1.0 - c*c); - if (s < SMALL) s = SMALL; - - // force & energy - - domega = acos(c) - chi[type]; - a = k[type] * domega; - - if (eflag) energy += rfactor * a * domega; - - a = -a * 2.0/s; - c = c * a; - - s12 = s12 * a; - a11 = (-c * ss1 * s1); - a22 = ss2 * (2.0 * c0 * s12 - c * (s1 + s2)); - a33 = (-c * ss3 * s2); - a12 = r1 * r2 * (c1 * c * s1 + c2 * s12); - a13 = r1 * r3 * s12; - a23 = r2 * r3 * (-c2 * c * s2 - c1 * s12); - - sx1 = a12*v2x + a13*v3x - a11*v1x; - sx2 = a22*v2x + a23*v3x - a12*v1x; - sx12 = a23*v2x + a33*v3x - a13*v1x; - sy1 = a12*v2y + a13*v3y - a11*v1y; - sy2 = a22*v2y + a23*v3y - a12*v1y; - sy12 = a23*v2y + a33*v3y - a13*v1y; - sz1 = a12*v2z + a13*v3z - a11*v1z; - sz2 = a22*v2z + a23*v3z - a12*v1z; - sz12 = a23*v2z + a33*v3z - a13*v1z; - - // apply force to each of 4 atoms - - if (newton_bond || i1 < nlocal) { - f[i1][0] -= sx1; - f[i1][1] -= sy1; - f[i1][2] -= sz1; - } - - if (newton_bond || i2 < nlocal) { - f[i2][0] += sx2 + sx1; - f[i2][1] += sy2 + sy1; - f[i2][2] += sz2 + sz1; - } - - if (newton_bond || i3 < nlocal) { - f[i3][0] += sx12 - sx2; - f[i3][1] += sy12 - sy2; - f[i3][2] += sz12 - sz2; - } - - if (newton_bond || i4 < nlocal) { - f[i4][0] -= sx12; - f[i4][1] -= sy12; - f[i4][2] -= sz12; - } - - // virial contribution - - if (vflag) { - virial[0] += rfactor * (v1x*sx1 - v2x*sx2 - v3x*sx12); - virial[1] += rfactor * (v1y*sy1 - v2y*sy2 - v3y*sy12); - virial[2] += rfactor * (v1z*sz1 - v2z*sz2 - v3z*sz12); - virial[3] += rfactor * (v1x*sy1 - v2x*sy2 - v3x*sy12); - virial[4] += rfactor * (v1x*sz1 - v2x*sz2 - v3x*sz12); - virial[5] += rfactor * (v1y*sz1 - v2y*sz2 - v3y*sz12); - } - } -} - -/* ---------------------------------------------------------------------- */ - -void ImproperHarmonic::allocate() -{ - allocated = 1; - int n = atom->nimpropertypes; - - k = (double *) memory->smalloc((n+1)*sizeof(double),"improper:k"); - chi = (double *) memory->smalloc((n+1)*sizeof(double),"improper:chi"); - - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one type -------------------------------------------------------------------------- */ - -void ImproperHarmonic::coeff(int which, int narg, char **arg) -{ - if (which != 0) error->all("Invalid coeffs for this improper style"); - if (narg != 3) error->all("Incorrect args for improper coefficients"); - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nimpropertypes,ilo,ihi); - - double k_one = atof(arg[1]); - double chi_one = atof(arg[2]); - - // convert chi from degrees to radians - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - k[i] = k_one; - chi[i] = chi_one/180.0 * PI; - setflag[i] = 1; - count++; - } - - if (count == 0) error->all("Incorrect args for improper coefficients"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes out coeffs to restart file -------------------------------------------------------------------------- */ - -void ImproperHarmonic::write_restart(FILE *fp) -{ - fwrite(&k[1],sizeof(double),atom->nimpropertypes,fp); - fwrite(&chi[1],sizeof(double),atom->nimpropertypes,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads coeffs from restart file, bcasts them -------------------------------------------------------------------------- */ - -void ImproperHarmonic::read_restart(FILE *fp) -{ - allocate(); - - if (comm->me == 0) { - fread(&k[1],sizeof(double),atom->nimpropertypes,fp); - fread(&chi[1],sizeof(double),atom->nimpropertypes,fp); - } - MPI_Bcast(&k[1],atom->nimpropertypes,MPI_DOUBLE,0,world); - MPI_Bcast(&chi[1],atom->nimpropertypes,MPI_DOUBLE,0,world); - - for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1; -} diff --git a/src/improper_harmonic.h b/src/improper_harmonic.h deleted file mode 100644 index e21ac2e6b7..0000000000 --- a/src/improper_harmonic.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 IMPROPER_HARMONIC_H -#define IMPROPER_HARMONIC_H - -#include "stdio.h" -#include "improper.h" - -class ImproperHarmonic : public Improper { - public: - ImproperHarmonic() {} - ~ImproperHarmonic(); - void compute(int, int); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - - private: - double *k,*chi; - - void allocate(); -}; - -#endif diff --git a/src/improper_hybrid.cpp b/src/improper_hybrid.cpp deleted file mode 100644 index c911f58950..0000000000 --- a/src/improper_hybrid.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* ----------------------------------------------------------------------- - 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 "improper_hybrid.h" -#include "atom.h" -#include "neighbor.h" -#include "domain.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" - -#define EXTRA 1000 - -/* ---------------------------------------------------------------------- - set all global defaults -------------------------------------------------------------------------- */ - -ImproperHybrid::ImproperHybrid() -{ - nstyles = 0; -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -ImproperHybrid::~ImproperHybrid() -{ - if (nstyles) { - for (int i = 0; i < nstyles; i++) delete styles[i]; - delete [] styles; - for (int i = 0; i < nstyles; i++) delete [] keywords[i]; - delete [] keywords; - } - - if (allocated) { - memory->sfree(setflag); - memory->sfree(map); - delete [] nimproperlist; - delete [] maximproper; - for (int i = 0; i < nstyles; i++) - memory->destroy_2d_int_array(improperlist[i]); - delete [] improperlist; - } -} - -/* ---------------------------------------------------------------------- */ - -void ImproperHybrid::compute(int eflag, int vflag) -{ - int i,m,n; - - // save ptrs to original improperlist - - int nimproperlist_orig = neighbor->nimproperlist; - int **improperlist_orig = neighbor->improperlist; - - // if this is re-neighbor step, create sub-style improperlists - // nimproperlist[] = length of each sub-style list - // realloc sub-style improperlist if necessary - // load sub-style improperlist with 5 values from original improperlist - - if (neighbor->ago == 0) { - for (m = 0; m < nstyles; m++) nimproperlist[m] = 0; - for (i = 0; i < nimproperlist_orig; i++) - nimproperlist[map[improperlist_orig[i][4]]]++; - for (m = 0; m < nstyles; m++) { - if (nimproperlist[m] > maximproper[m]) { - memory->destroy_2d_int_array(improperlist[m]); - maximproper[m] = nimproperlist[m] + EXTRA; - improperlist[m] = (int **) - memory->create_2d_int_array(maximproper[m],5, - "improper_hybrid:improperlist"); - } - nimproperlist[m] = 0; - } - for (i = 0; i < nimproperlist_orig; i++) { - m = map[improperlist_orig[i][4]]; - n = nimproperlist[m]; - improperlist[m][n][0] = improperlist_orig[i][0]; - improperlist[m][n][1] = improperlist_orig[i][1]; - improperlist[m][n][2] = improperlist_orig[i][2]; - improperlist[m][n][3] = improperlist_orig[i][3]; - improperlist[m][n][4] = improperlist_orig[i][4]; - nimproperlist[m]++; - } - } - - // call each sub-style's compute function - // must set neighbor->improperlist to sub-style improperlist before call - // accumulate sub-style energy,virial in hybrid's energy,virial - - energy = 0.0; - if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - - for (m = 0; m < nstyles; m++) { - if (styles[m] == NULL) continue; - neighbor->nimproperlist = nimproperlist[m]; - neighbor->improperlist = improperlist[m]; - styles[m]->compute(eflag,vflag); - if (eflag) energy += styles[m]->energy; - if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; - } - - // restore ptrs to original improperlist - - neighbor->nimproperlist = nimproperlist_orig; - neighbor->improperlist = improperlist_orig; -} - -/* ---------------------------------------------------------------------- */ - -void ImproperHybrid::allocate() -{ - allocated = 1; - int n = atom->nimpropertypes; - - map = (int *) memory->smalloc((n+1)*sizeof(int),"improper:map"); - setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag"); - for (int i = 1; i <= n; i++) setflag[i] = 0; - - nimproperlist = new int[nstyles]; - maximproper = new int[nstyles]; - improperlist = new int**[nstyles]; - for (int m = 0; m < nstyles; m++) maximproper[m] = 0; - for (int m = 0; m < nstyles; m++) improperlist[m] = NULL; -} - -/* ---------------------------------------------------------------------- - create one improper style for each arg in list -------------------------------------------------------------------------- */ - -void ImproperHybrid::settings(int narg, char **arg) -{ - nstyles = narg; - styles = new Improper*[nstyles]; - keywords = new char*[nstyles]; - - for (int m = 0; m < nstyles; m++) { - for (int i = 0; i < m; i++) - if (strcmp(arg[m],arg[i]) == 0) - error->all("Improper style hybrid cannot use same improper style twice"); - if (strcmp(arg[m],"hybrid") == 0) - error->all("Improper style hybrid cannot have hybrid as an argument"); - styles[m] = force->new_improper(arg[m]); - keywords[m] = new char[strlen(arg[m])+1]; - strcpy(keywords[m],arg[m]); - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one type ----------------------------------------------------------------------- */ - -void ImproperHybrid::coeff(int which, int narg, char **arg) -{ - if (!allocated) allocate(); - - int ilo,ihi; - force->bounds(arg[0],atom->nimpropertypes,ilo,ihi); - - // 2nd arg = improper style name (harmonic, etc) - - int m; - for (m = 0; m < nstyles; m++) - if (strcmp(arg[1],keywords[m]) == 0) break; - if (m == nstyles) error->all("Improper coeff for hybrid has invalid style"); - - // set low-level coefficients for each impropertype - // replace 2nd arg with i, call coeff() with no 1st arg - // if sub-style is NULL for "none", still set setflag - - for (int i = ilo; i <= ihi; i++) { - sprintf(arg[1],"%d",i); - map[i] = m; - if (styles[m]) styles[m]->coeff(which,narg-1,&arg[1]); - setflag[i] = 1; - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void ImproperHybrid::write_restart(FILE *fp) -{ - fwrite(&nstyles,sizeof(int),1,fp); - - int n; - for (int m = 0; m < nstyles; m++) { - n = strlen(keywords[m]) + 1; - fwrite(&n,sizeof(int),1,fp); - fwrite(keywords[m],sizeof(char),n,fp); - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void ImproperHybrid::read_restart(FILE *fp) -{ - allocate(); - - int me = comm->me; - if (me == 0) fread(&nstyles,sizeof(int),1,fp); - MPI_Bcast(&nstyles,1,MPI_INT,0,world); - styles = new Improper*[nstyles]; - keywords = new char*[nstyles]; - - int n; - for (int m = 0; m < nstyles; m++) { - if (me == 0) fread(&n,sizeof(int),1,fp); - MPI_Bcast(&n,1,MPI_INT,0,world); - keywords[m] = new char[n]; - if (me == 0) fread(keywords[m],sizeof(char),n,fp); - MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); - styles[m] = force->new_improper(keywords[m]); - } -} - -/* ---------------------------------------------------------------------- - memory usage -------------------------------------------------------------------------- */ - -int ImproperHybrid::memory_usage() -{ - int bytes = 0; - for (int m = 0; m < nstyles; m++) bytes += maximproper[m]*5 * sizeof(int); - for (int m = 0; m < nstyles; m++) - if (styles[m]) bytes += styles[m]->memory_usage(); - return bytes; -} diff --git a/src/improper_hybrid.h b/src/improper_hybrid.h deleted file mode 100644 index 1aca2401e5..0000000000 --- a/src/improper_hybrid.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 IMPROPER_HYBRID_H -#define IMPROPER_HYBRID_H - -#include "stdio.h" -#include "improper.h" - -class ImproperHybrid : public Improper { - public: - ImproperHybrid(); - ~ImproperHybrid(); - void compute(int, int); - void settings(int, char **); - void coeff(int, int, char **); - void write_restart(FILE *); - void read_restart(FILE *); - int memory_usage(); - - private: - int nstyles; // # of different improper styles - Improper **styles; // class list for each Improper style - char **keywords; // keyword for each improper style - int *map; // which style each improper type points to - - int *nimproperlist; // # of impropers in sub-style improperlists - int *maximproper; // max # of impropers sub-style lists can store - int ***improperlist; // improperlist for each sub-style - - void allocate(); -}; - -#endif diff --git a/src/input.cpp b/src/input.cpp index b0d1494fdb..e573b08f25 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -156,6 +156,14 @@ void Input::file() MPI_Bcast(line,n,MPI_CHAR,0,world); + // if n = MAXLINE, line is too long + + if (n == MAXLINE) { + char str[MAXLINE+32]; + sprintf(str,"Input line too long: %s",line); + error->all(str); + } + // echo the command unless scanning for label if (me == 0 && label_active == 0) { diff --git a/src/pair_buck_coul_long.cpp b/src/pair_buck_coul_long.cpp deleted file mode 100644 index 450fcb5efa..0000000000 --- a/src/pair_buck_coul_long.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_buck_coul_long.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "kspace.h" -#include "update.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define A1 0.254829592 -#define A2 -0.284496736 -#define A3 1.421413741 -#define A4 -1.453152027 -#define A5 1.061405429 - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -PairBuckCoulLong::~PairBuckCoulLong() -{ - 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(a); - memory->destroy_2d_double_array(rho); - memory->destroy_2d_double_array(c); - memory->destroy_2d_double_array(rhoinv); - memory->destroy_2d_double_array(buck1); - memory->destroy_2d_double_array(buck2); - memory->destroy_2d_double_array(offset); - } -} - -/* ---------------------------------------------------------------------- */ - -void PairBuckCoulLong::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcebuck,fforce,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double factor,phicoul,phibuck,r,rexp; - 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; - int *type = atom->type; - 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 %= 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; - - if (rsq < cut_coulsq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else forcecoul = 0.0; - - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - r = sqrt(rsq); - rexp = exp(-r*rhoinv[itype][jtype]); - forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; - } else forcebuck = 0.0; - - fforce = (forcecoul + factor_lj*forcebuck) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - phicoul = prefactor*erfc; - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - eng_coul += factor*phicoul; - } - if (rsq < cut_ljsq[itype][jtype]) { - phibuck = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - - offset[itype][jtype]; - eng_vdwl += factor*factor_lj*phibuck; - } - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::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"); - a = memory->create_2d_double_array(n+1,n+1,"pair:a"); - rho = memory->create_2d_double_array(n+1,n+1,"pair:rho"); - c = memory->create_2d_double_array(n+1,n+1,"pair:c"); - rhoinv = memory->create_2d_double_array(n+1,n+1,"pair:rhoinv"); - buck1 = memory->create_2d_double_array(n+1,n+1,"pair:buck1"); - buck2 = memory->create_2d_double_array(n+1,n+1,"pair:buck2"); - offset = memory->create_2d_double_array(n+1,n+1,"pair:offset"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::settings(int narg, char **arg) -{ - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); - - cut_lj_global = atof(arg[0]); - if (narg == 1) cut_coul = cut_lj_global; - else cut_coul = 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; - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::coeff(int narg, char **arg) -{ - if (narg < 5 || 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 a_one = atof(arg[2]); - double rho_one = atof(arg[3]); - double c_one = atof(arg[4]); - - double cut_lj_one = cut_lj_global; - if (narg == 6) cut_lj_one = atof(arg[5]); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - a[i][j] = a_one; - rho[i][j] = rho_one; - c[i][j] = c_one; - cut_lj[i][j] = cut_lj_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 PairBuckCoulLong::init_one(int i, int j) -{ - if (setflag[i][j] == 0) error->all("All pair coeffs are not set"); - - double cut = MAX(cut_lj[i][j],cut_coul); - cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j]; - - rhoinv[i][j] = 1.0/rho[i][j]; - buck1[i][j] = a[i][j]/rho[i][j]; - buck2[i][j] = 6.0*c[i][j]; - - if (offset_flag) { - double rexp = exp(-cut_lj[i][j]/rho[i][j]); - offset[i][j] = a[i][j]*rexp - c[i][j]/pow(cut_lj[i][j],6.0); - } else offset[i][j] = 0.0; - - cut_ljsq[j][i] = cut_ljsq[i][j]; - a[j][i] = a[i][j]; - c[j][i] = c[i][j]; - rhoinv[j][i] = rhoinv[i][j]; - buck1[j][i] = buck1[i][j]; - buck2[j][i] = buck2[i][j]; - offset[j][i] = offset[i][j]; - - return cut; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::init_style() -{ - // require an atom style with charge defined - - if (atom->charge_allow == 0) - error->all("Must use charged atom style with this pair style"); - - cut_coulsq = cut_coul * cut_coul; - - // insure use of KSpace long-range solver, set g_ewald - - if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); - else if (strcmp(force->kspace_style,"ewald") == 0) - g_ewald = force->kspace->g_ewald; - else if (strcmp(force->kspace_style,"pppm") == 0) - g_ewald = force->kspace->g_ewald; - else error->all("Pair style is incompatible with KSpace style"); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::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(&a[i][j],sizeof(double),1,fp); - fwrite(&rho[i][j],sizeof(double),1,fp); - fwrite(&c[i][j],sizeof(double),1,fp); - fwrite(&cut_lj[i][j],sizeof(double),1,fp); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::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(&a[i][j],sizeof(double),1,fp); - fread(&rho[i][j],sizeof(double),1,fp); - fread(&c[i][j],sizeof(double),1,fp); - fread(&cut_lj[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&a[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&rho[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&c[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_lj[i][j],1,MPI_DOUBLE,0,world); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairBuckCoulLong::write_restart_settings(FILE *fp) -{ - fwrite(&cut_lj_global,sizeof(double),1,fp); - fwrite(&cut_coul,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 PairBuckCoulLong::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_lj_global,sizeof(double),1,fp); - fread(&cut_coul,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,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); -} - -/* ---------------------------------------------------------------------- */ - -void PairBuckCoulLong::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, - int eflag, One &one) -{ - double r2inv,r6inv,r,rexp,grij,expm2,t,erfc,prefactor; - double forcecoul,forcebuck,phicoul,phibuck; - - r2inv = 1.0/rsq; - if (rsq < cut_coulsq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else forcecoul = 0.0; - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - r = sqrt(rsq); - rexp = exp(-r*rhoinv[itype][jtype]); - forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; - } else forcebuck = 0.0; - one.fforce = (forcecoul + factor_lj*forcebuck) * r2inv; - - if (eflag) { - if (rsq < cut_coulsq) { - phicoul = prefactor*erfc; - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - one.eng_coul = phicoul; - } else one.eng_coul = 0.0; - if (rsq < cut_ljsq[itype][jtype]) { - phibuck = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - - offset[itype][jtype]; - one.eng_vdwl = factor_lj*phibuck; - } else one.eng_vdwl = 0.0; - } -} diff --git a/src/pair_buck_coul_long.h b/src/pair_buck_coul_long.h deleted file mode 100644 index 0f87844fa8..0000000000 --- a/src/pair_buck_coul_long.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_BUCK_COUL_LONG_H -#define PAIR_BUCK_COUL_LONG_H - -#include "pair.h" - -class PairBuckCoulLong : public Pair { - public: - double cut_coul; - - PairBuckCoulLong() {} - ~PairBuckCoulLong(); - 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; - double **cut_lj,**cut_ljsq; - double cut_coulsq; - double **a,**rho,**c; - double **rhoinv,**buck1,**buck2,**offset; - double g_ewald; - - void allocate(); -}; - -#endif diff --git a/src/pair_eam.cpp b/src/pair_eam.cpp deleted file mode 100644 index 651d32dde8..0000000000 --- a/src/pair_eam.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Stephen Foiles (SNL), Murray Daw (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_eam.h" -#include "atom.h" -#include "force.h" -#include "update.h" -#include "comm.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define MAXLINE 1024 - -/* ---------------------------------------------------------------------- */ - -PairEAM::PairEAM() -{ - nmax = 0; - rho = NULL; - fp = NULL; - - ntables = 0; - tables = NULL; - frho = NULL; - frho_0 = NULL; - - // set rhor to NULL so memory deallocation will work - // even from derived classes that don't use rhor - - rhor = NULL; -} - -/* ---------------------------------------------------------------------- - free all arrays - check if allocated, since class can be destructed when incomplete -------------------------------------------------------------------------- */ - -PairEAM::~PairEAM() -{ - memory->sfree(rho); - memory->sfree(fp); - - if (allocated) { - memory->destroy_2d_int_array(setflag); - memory->destroy_2d_double_array(cutsq); - memory->destroy_2d_int_array(tabindex); - } - - for (int m = 0; m < ntables; m++) { - delete [] tables[m].filename; - delete [] tables[m].frho; - delete [] tables[m].rhor; - delete [] tables[m].zr; - delete [] tables[m].z2r; - } - memory->sfree(tables); - - if (frho) { - memory->destroy_2d_double_array(frho); - memory->destroy_2d_double_array(rhor); - memory->destroy_2d_double_array(zrtmp); - memory->destroy_3d_double_array(z2r); - } - - if (frho_0) interpolate_deallocate(); -} - -/* ---------------------------------------------------------------------- */ - -void PairEAM::compute(int eflag, int vflag) -{ - int i,j,k,m,numneigh,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r,p,fforce,rhoip,rhojp,z2,z2p,recip,phi,phip,psip; - int *neighs; - double **f; - - // grow energy array if necessary - - if (atom->nmax > nmax) { - memory->sfree(rho); - memory->sfree(fp); - nmax = atom->nmax; - rho = (double *) memory->smalloc(nmax*sizeof(double),"eam:rho"); - fp = (double *) memory->smalloc(nmax*sizeof(double),"eam:fp"); - } - - eng_vdwl = 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; - int *type = atom->type; - int nlocal = atom->nlocal; - int newton_pair = force->newton_pair; - - // zero out density - - if (newton_pair) { - m = nlocal + atom->nghost; - for (i = 0; i < m; i++) rho[i] = 0.0; - } else for (i = 0; i < nlocal; i++) rho[i] = 0.0; - - // rho = density at each atom - // loop over neighbors of my atoms - - for (i = 0; i < nlocal; 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]; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cutforcesq) { - jtype = type[j]; - p = sqrt(rsq)*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - rho[i] += ((rhor_3[jtype][m]*p + rhor_2[jtype][m])*p + - rhor_1[jtype][m])*p + rhor_0[jtype][m]; - if (newton_pair || j < nlocal) - rho[j] += ((rhor_3[itype][m]*p + rhor_2[itype][m])*p + - rhor_1[itype][m])*p + rhor_0[itype][m]; - } - } - } - - // communicate and sum densities - - if (newton_pair) comm->reverse_comm_pair(this); - - // fp = derivative of embedding energy at each atom - // phi = embedding energy at each atom - - for (i = 0; i < nlocal; i++) { - itype = type[i]; - p = rho[i]*rdrho + 1.0; - m = static_cast (p); - m = MAX(1,MIN(m,nrho-1)); - p -= m; - p = MIN(p,1.0); - fp[i] = (frho_6[itype][m]*p + frho_5[itype][m])*p + frho_4[itype][m]; - if (eflag) { - phi = ((frho_3[itype][m]*p + frho_2[itype][m])*p + - frho_1[itype][m])*p + frho_0[itype][m]; - eng_vdwl += phi; - } - } - - // communicate derivative of embedding function - - comm->comm_pair(this); - - // compute forces on each atom - // loop over neighbors of my atoms - - for (i = 0; i < nlocal; 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]; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cutforcesq) { - jtype = type[j]; - r = sqrt(rsq); - p = r*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - - // rhoip = derivative of (density at atom j due to atom i) - // rhojp = derivative of (density at atom i due to atom j) - // phi = pair potential energy - // phip = phi' - // z2 = phi * r - // z2p = (phi * r)' = (phi' r) + phi - // psip needs both fp[i] and fp[j] terms since r_ij appears in two - // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) - // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip - - rhoip = (rhor_6[itype][m]*p + rhor_5[itype][m])*p + - rhor_4[itype][m]; - rhojp = (rhor_6[jtype][m]*p + rhor_5[jtype][m])*p + - rhor_4[jtype][m]; - z2 = ((z2r_3[itype][jtype][m]*p + z2r_2[itype][jtype][m])*p + - z2r_1[itype][jtype][m])*p + z2r_0[itype][jtype][m]; - z2p = (z2r_6[itype][jtype][m]*p + z2r_5[itype][jtype][m])*p + - z2r_4[itype][jtype][m]; - - recip = 1.0/r; - phi = z2*recip; - phip = z2p*recip - phi*recip; - psip = fp[i]*rhojp + fp[j]*rhoip + phip; - fforce = psip*recip; - f[i][0] -= delx*fforce; - f[i][1] -= dely*fforce; - f[i][2] -= delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] += delx*fforce; - f[j][1] += dely*fforce; - f[j][2] += delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) eng_vdwl += phi; - else eng_vdwl += 0.5*phi; - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] -= delx*delx*fforce; - virial[1] -= dely*dely*fforce; - virial[2] -= delz*delz*fforce; - virial[3] -= delx*dely*fforce; - virial[4] -= delx*delz*fforce; - virial[5] -= dely*delz*fforce; - } else { - virial[0] -= 0.5*delx*delx*fforce; - virial[1] -= 0.5*dely*dely*fforce; - virial[2] -= 0.5*delz*delz*fforce; - virial[3] -= 0.5*delx*dely*fforce; - virial[4] -= 0.5*delx*delz*fforce; - virial[5] -= 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairEAM::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"); - tabindex = memory->create_2d_int_array(n+1,n+1,"pair:tabindex"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairEAM::settings(int narg, char **arg) -{ - if (narg > 0) error->all("Illegal pair_style command"); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs - reading multiple funcfl files defines a funcfl alloy simulation -------------------------------------------------------------------------- */ - -void PairEAM::coeff(int narg, char **arg) -{ - if (!allocated) allocate(); - - if (narg != 3) error->all("Incorrect args for pair coefficients"); - - // parse pair of atom types - - int ilo,ihi,jlo,jhi; - force->bounds(arg[0],atom->ntypes,ilo,ihi); - force->bounds(arg[1],atom->ntypes,jlo,jhi); - - // read funcfl file only for i,i pairs - // only setflag i,i will be set - // set mass of each atom type - - int itable; - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - if (i == j) { - itable = read_funcfl(arg[2]); - atom->set_mass(i,tables[itable].mass); - tabindex[i][i] = itable; - setflag[i][i] = 1; - count++; - } - } - } - - if (count == 0) error->all("Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairEAM::init_one(int i, int j) -{ - // only setflag I,I was set by coeff - // mixing will occur in init_style if both I,I and J,J were set - - if (setflag[i][i] == 0 || setflag[j][j] == 0) - error->all("All EAM pair coeffs are not set"); - - // EAM has only one cutoff = max of all pairwise cutoffs - // determine max by checking table assigned to all type pairs - // only setflag[i][j] = 1 is relevant (if hybrid, some may not be set) - - cutmax = 0.0; - for (int ii = 1; ii <= atom->ntypes; ii++) { - for (int jj = ii; jj <= atom->ntypes; jj++) { - if (setflag[ii][jj] == 0) continue; - cutmax = MAX(cutmax,tables[tabindex[ii][jj]].cut); - } - } - - return cutmax; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairEAM::init_style() -{ - // set communication sizes in comm class - - comm->maxforward_pair = MAX(comm->maxforward_pair,1); - comm->maxreverse_pair = MAX(comm->maxreverse_pair,1); - - // convert read-in funcfl tables to multi-type setfl format and mix I,J - // interpolate final spline coeffs - - convert_funcfl(); - interpolate(); - - cutforcesq = cutmax*cutmax; -} - -/* ---------------------------------------------------------------------- - read potential values from a single element EAM file - read values into table and bcast values -------------------------------------------------------------------------- */ - -int PairEAM::read_funcfl(char *file) -{ - // check if same file has already been read - // if yes, return index of table entry - // if no, extend table list - - for (int i = 0; i < ntables; i++) - if (strcmp(file,tables->filename) == 0) return i; - - tables = (Table *) - memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); - - Table *tb = &tables[ntables]; - int n = strlen(file) + 1; - tb->filename = new char[n]; - strcpy(tb->filename,file); - tb->ith = tb->jth = 0; - - // open potential file - - int me = comm->me; - FILE *fp; - char line[MAXLINE]; - - if (me == 0) { - fp = fopen(file,"r"); - if (fp == NULL) { - char str[128]; - sprintf(str,"Cannot open EAM potential file %s",file); - error->one(str); - } - } - - // read and broadcast header - - int tmp; - if (me == 0) { - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg",&tmp,&tb->mass); - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg %d %lg %lg", - &tb->nrho,&tb->drho,&tb->nr,&tb->dr,&tb->cut); - } - - MPI_Bcast(&tb->mass,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->nrho,1,MPI_INT,0,world); - MPI_Bcast(&tb->drho,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->nr,1,MPI_INT,0,world); - MPI_Bcast(&tb->dr,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->cut,1,MPI_DOUBLE,0,world); - - // allocate potential arrays and read/bcast them - // set z2r to NULL (setfl array) so it can be deallocated - - tb->frho = new double[tb->nrho+1]; - tb->zr = new double[tb->nr+1]; - tb->rhor = new double[tb->nr+1]; - tb->z2r = NULL; - - if (me == 0) grab(fp,tb->nrho,&tb->frho[1]); - MPI_Bcast(&tb->frho[1],tb->nrho,MPI_DOUBLE,0,world); - - if (me == 0) grab(fp,tb->nr,&tb->zr[1]); - MPI_Bcast(&tb->zr[1],tb->nr,MPI_DOUBLE,0,world); - - if (me == 0) grab(fp,tb->nr,&tb->rhor[1]); - MPI_Bcast(&tb->rhor[1],tb->nr,MPI_DOUBLE,0,world); - - // close the potential file - - if (me == 0) fclose(fp); - - ntables++; - return ntables-1; -} - -/* ---------------------------------------------------------------------- - convert read-in funcfl potentials to multi-type setfl format -------------------------------------------------------------------------- */ - -void PairEAM::convert_funcfl() -{ - int i,j,k,m; - - int ntypes = atom->ntypes; - - // determine max values for all i,i type pairs - // skip if setflag = 0 (if hybrid, some may not be set) - - double rmax,rhomax; - dr = drho = rmax = rhomax = 0.0; - - for (int i = 1; i <= ntypes; i++) { - if (setflag[i][i] == 0) continue; - Table *tb = &tables[tabindex[i][i]]; - dr = MAX(dr,tb->dr); - drho = MAX(drho,tb->drho); - rmax = MAX(rmax,(tb->nr-1) * tb->dr); - rhomax = MAX(rhomax,(tb->nrho-1) * tb->drho); - } - - // set nr,nrho from cutoff and spacings - // 0.5 is for round-off in divide - - nr = static_cast (rmax/dr + 0.5); - nrho = static_cast (rhomax/drho + 0.5); - - // allocate multi-type setfl arrays - - if (frho) { - memory->destroy_2d_double_array(frho); - memory->destroy_2d_double_array(rhor); - memory->destroy_2d_double_array(zrtmp); - memory->destroy_3d_double_array(z2r); - } - - frho = (double **) - memory->create_2d_double_array(ntypes+1,nrho+1,"eam:frho"); - rhor = (double **) - memory->create_2d_double_array(ntypes+1,nr+1,"eam:rhor"); - zrtmp = (double **) - memory->create_2d_double_array(ntypes+1,nr+1,"eam:zrtmp"); - z2r = (double ***) - memory->create_3d_double_array(ntypes+1,ntypes+1,nr+1,"eam:frho"); - - // interpolate all potentials to a single grid and cutoff for all atom types - // frho,rhor are 1:ntypes, z2r is 1:ntypes,1:ntypes - // skip if setflag i,i or j,j = 0 (if hybrid, some may not be set) - - double r,p,cof1,cof2,cof3,cof4; - - for (i = 1; i <= ntypes; i++) { - if (setflag[i][i] == 0) continue; - Table *tb = &tables[tabindex[i][i]]; - for (m = 1; m <= nrho; m++) { - r = (m-1)*drho; - p = r/tb->drho + 1.0; - k = static_cast (p); - k = MIN(k,tb->nrho-2); - k = MAX(k,2); - p -= k; - p = MIN(p,2.0); - cof1 = -0.166666667*p*(p-1.0)*(p-2.0); - cof2 = 0.5*(p*p-1.0)*(p-2.0); - cof3 = -0.5*p*(p+1.0)*(p-2.0); - cof4 = 0.166666667*p*(p*p-1.0); - frho[i][m] = cof1*tb->frho[k-1] + cof2*tb->frho[k] + - cof3*tb->frho[k+1] + cof4*tb->frho[k+2]; - } - } - - for (i = 1; i <= ntypes; i++) { - if (setflag[i][i] == 0) continue; - Table *tb = &tables[tabindex[i][i]]; - for (m = 1; m <= nr; m++) { - r = (m-1)*dr; - p = r/tb->dr + 1.0; - k = static_cast (p); - k = MIN(k,tb->nr-2); - k = MAX(k,2); - p -= k; - p = MIN(p,2.0); - cof1 = -0.166666667*p*(p-1.0)*(p-2.0); - cof2 = 0.5*(p*p-1.0)*(p-2.0); - cof3 = -0.5*p*(p+1.0)*(p-2.0); - cof4 = 0.166666667*p*(p*p-1.0); - rhor[i][m] = cof1*tb->rhor[k-1] + cof2*tb->rhor[k] + - cof3*tb->rhor[k+1] + cof4*tb->rhor[k+2]; - zrtmp[i][m] = cof1*tb->zr[k-1] + cof2*tb->zr[k] + - cof3*tb->zr[k+1] + cof4*tb->zr[k+2]; - } - } - - for (i = 1; i <= ntypes; i++) - for (j = i; j <= ntypes; j++) { - if (setflag[i][i] == 0 || setflag[j][j] == 0) continue; - for (m = 1; m <= nr; m++) - z2r[i][j][m] = 27.2*0.529 * zrtmp[i][m]*zrtmp[j][m]; - } -} - -/* ---------------------------------------------------------------------- - interpolate EAM potentials -------------------------------------------------------------------------- */ - -void PairEAM::interpolate() -{ - // free memory from previous interpolation - - if (frho_0) interpolate_deallocate(); - - // interpolation spacings - - rdr = 1.0/dr; - rdrho = 1.0/drho; - - // allocate coeff arrays - - int n = atom->ntypes; - - frho_0 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_0"); - frho_1 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_1"); - frho_2 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_2"); - frho_3 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_3"); - frho_4 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_4"); - frho_5 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_5"); - frho_6 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_6"); - - rhor_0 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_0"); - rhor_1 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_1"); - rhor_2 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_2"); - rhor_3 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_3"); - rhor_4 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_4"); - rhor_5 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_5"); - rhor_6 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_6"); - - z2r_0 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_0"); - z2r_1 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_1"); - z2r_2 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_2"); - z2r_3 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_3"); - z2r_4 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_4"); - z2r_5 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_5"); - z2r_6 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_6"); - - // frho interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - // if skip, set frho arrays to 0.0, since they will still be accessed - // for non-EAM atoms when compute() calculates embedding function - - int i,j,m; - - for (i = 1; i <= atom->ntypes; i++) { - if (setflag[i][i] == 0) { - for (j = 1; j <= n; j++) - for (m = 1; m <= nrho; m++) - frho_0[j][m] = frho_1[j][m] = frho_2[j][m] = frho_3[j][m] = - frho_4[j][m] = frho_5[j][m] = frho_6[j][m] = 0.0; - continue; - } - - for (m = 1; m <= nrho; m++) frho_0[i][m] = frho[i][m]; - - frho_1[i][1] = frho_0[i][2]-frho_0[i][1]; - frho_1[i][2] = 0.5*(frho_0[i][3]-frho_0[i][1]); - frho_1[i][nrho-1] = 0.5*(frho_0[i][nrho]-frho_0[i][nrho-2]); - frho_1[i][nrho] = frho_0[i][nrho]-frho_0[i][nrho-1]; - - for (m = 3; m <= nrho-2; m++) - frho_1[i][m] = ((frho_0[i][m-2]-frho_0[i][m+2]) + - 8.0*(frho_0[i][m+1]-frho_0[i][m-1]))/12.0; - - for (m = 1; m <= nrho-1; m++) { - frho_2[i][m] = 3.*(frho_0[i][m+1]-frho_0[i][m]) - - 2.0*frho_1[i][m] - frho_1[i][m+1]; - frho_3[i][m] = frho_1[i][m] + frho_1[i][m+1] - - 2.0*(frho_0[i][m+1]-frho_0[i][m]); - } - - frho_2[i][nrho] = 0.0; - frho_3[i][nrho] = 0.0; - - for (m = 1; m <= nrho; m++) { - frho_4[i][m] = frho_1[i][m]/drho; - frho_5[i][m] = 2.0*frho_2[i][m]/drho; - frho_6[i][m] = 3.0*frho_3[i][m]/drho; - } - } - - // rhor interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - - for (i = 1; i <= atom->ntypes; i++) { - if (setflag[i][i] == 0) continue; - - for (m = 1; m <= nr; m++) rhor_0[i][m] = rhor[i][m]; - - rhor_1[i][1] = rhor_0[i][2]-rhor_0[i][1]; - rhor_1[i][2] = 0.5*(rhor_0[i][3]-rhor_0[i][1]); - rhor_1[i][nr-1] = 0.5*(rhor_0[i][nr]-rhor_0[i][nr-2]); - rhor_1[i][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - rhor_1[i][m] = ((rhor_0[i][m-2]-rhor_0[i][m+2]) + - 8.0*(rhor_0[i][m+1]-rhor_0[i][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - rhor_2[i][m] = 3.0*(rhor_0[i][m+1]-rhor_0[i][m]) - - 2.0*rhor_1[i][m] - rhor_1[i][m+1]; - rhor_3[i][m] = rhor_1[i][m] + rhor_1[i][m+1] - - 2.0*(rhor_0[i][m+1]-rhor_0[i][m]); - } - - rhor_2[i][nr] = 0.0; - rhor_3[i][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - rhor_4[i][m] = rhor_1[i][m]/dr; - rhor_5[i][m] = 2.0*rhor_2[i][m]/dr; - rhor_6[i][m] = 3.0*rhor_3[i][m]/dr; - } - } - - // z2r interpolation for 1:ntypes,1:ntypes - // skip if setflag i,i or j,j = 0 (if hybrid, some may not be set) - // set j,i coeffs = i,j coeffs - - for (i = 1; i <= atom->ntypes; i++) { - for (j = i; j <= atom->ntypes; j++) { - if (setflag[i][i] == 0 || setflag[j][j] == 0) continue; - - for (m = 1; m <= nr; m++) z2r_0[i][j][m] = z2r[i][j][m]; - - z2r_1[i][j][1] = z2r_0[i][j][2]-z2r_0[i][j][1]; - z2r_1[i][j][2] = 0.5*(z2r_0[i][j][3]-z2r_0[i][j][1]); - z2r_1[i][j][nr-1] = 0.5*(z2r_0[i][j][nr]-z2r_0[i][j][nr-2]); - z2r_1[i][j][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - z2r_1[i][j][m] = ((z2r_0[i][j][m-2]-z2r_0[i][j][m+2]) + - 8.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - z2r_2[i][j][m] = 3.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]) - - 2.0*z2r_1[i][j][m] - z2r_1[i][j][m+1]; - z2r_3[i][j][m] = z2r_1[i][j][m] + z2r_1[i][j][m+1] - - 2.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]); - } - - z2r_2[i][j][nr] = 0.0; - z2r_3[i][j][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - z2r_4[i][j][m] = z2r_1[i][j][m]/dr; - z2r_5[i][j][m] = 2.0*z2r_2[i][j][m]/dr; - z2r_6[i][j][m] = 3.0*z2r_3[i][j][m]/dr; - } - - for (m = 1; m <= nr; m++) { - z2r_0[j][i][m] = z2r_0[i][j][m]; - z2r_1[j][i][m] = z2r_1[i][j][m]; - z2r_2[j][i][m] = z2r_2[i][j][m]; - z2r_3[j][i][m] = z2r_3[i][j][m]; - z2r_4[j][i][m] = z2r_4[i][j][m]; - z2r_5[j][i][m] = z2r_5[i][j][m]; - z2r_6[j][i][m] = z2r_6[i][j][m]; - } - } - } -} - -/* ---------------------------------------------------------------------- - grab n values from file fp and put them in list - values can be several to a line - only called by proc 0 -------------------------------------------------------------------------- */ - -void PairEAM::grab(FILE *fp, int n, double *list) -{ - char *ptr; - char line[MAXLINE]; - - int i = 0; - while (i < n) { - fgets(line,MAXLINE,fp); - ptr = strtok(line," \t\n\r\f"); - list[i++] = atof(ptr); - while (ptr = strtok(NULL," \t\n\r\f")) list[i++] = atof(ptr); - } -} - -/* ---------------------------------------------------------------------- - skip n values from file fp - values can be several to a line - only called by proc 0 -------------------------------------------------------------------------- */ - -void PairEAM::skip(FILE *fp, int n) -{ - char line[MAXLINE]; - - int i = 0; - while (i < n) { - fgets(line,MAXLINE,fp); - strtok(line," \t\n\r\f"); - i++; - while (strtok(NULL," \t\n\r\f")) i++; - } -} - -/* ---------------------------------------------------------------------- - deallocate spline interpolation arrays -------------------------------------------------------------------------- */ - -void PairEAM::interpolate_deallocate() -{ - memory->destroy_2d_double_array(frho_0); - memory->destroy_2d_double_array(frho_1); - memory->destroy_2d_double_array(frho_2); - memory->destroy_2d_double_array(frho_3); - memory->destroy_2d_double_array(frho_4); - memory->destroy_2d_double_array(frho_5); - memory->destroy_2d_double_array(frho_6); - - memory->destroy_2d_double_array(rhor_0); - memory->destroy_2d_double_array(rhor_1); - memory->destroy_2d_double_array(rhor_2); - memory->destroy_2d_double_array(rhor_3); - memory->destroy_2d_double_array(rhor_4); - memory->destroy_2d_double_array(rhor_5); - memory->destroy_2d_double_array(rhor_6); - - memory->destroy_3d_double_array(z2r_0); - memory->destroy_3d_double_array(z2r_1); - memory->destroy_3d_double_array(z2r_2); - memory->destroy_3d_double_array(z2r_3); - memory->destroy_3d_double_array(z2r_4); - memory->destroy_3d_double_array(z2r_5); - memory->destroy_3d_double_array(z2r_6); -} - -/* ---------------------------------------------------------------------- */ - -void PairEAM::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, - int eflag, One &one) -{ - double r,p,rhoip,rhojp,z2,z2p,recip,phi,phip,psip; - int m; - - r = sqrt(rsq); - p = r*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - - rhoip = (rhor_6[itype][m]*p + rhor_5[itype][m])*p + - rhor_4[itype][m]; - rhojp = (rhor_6[jtype][m]*p + rhor_5[jtype][m])*p + - rhor_4[jtype][m]; - z2 = ((z2r_3[itype][jtype][m]*p + z2r_2[itype][jtype][m])*p + - z2r_1[itype][jtype][m])*p + z2r_0[itype][jtype][m]; - z2p = (z2r_6[itype][jtype][m]*p + z2r_5[itype][jtype][m])*p + - z2r_4[itype][jtype][m]; - - recip = 1.0/r; - phi = z2*recip; - phip = z2p*recip - phi*recip; - psip = fp[i]*rhojp + fp[j]*rhoip + phip; - one.fforce = -psip*recip; - - if (eflag) { - one.eng_vdwl = phi; - one.eng_coul = 0.0; - } -} - -/* ---------------------------------------------------------------------- */ - -void PairEAM::single_embed(int i, int itype, double &fpi, - int eflag, double &phi) -{ - double p = rho[i]*rdrho + 1.0; - int m = static_cast (p); - m = MAX(1,MIN(m,nrho-1)); - p -= m; - - fpi = (frho_6[itype][m]*p + frho_5[itype][m])*p + frho_4[itype][m]; - if (eflag) - phi = ((frho_3[itype][m]*p + frho_2[itype][m])*p + - frho_1[itype][m])*p + frho_0[itype][m]; -} - -/* ---------------------------------------------------------------------- */ - -int PairEAM::pack_comm(int n, int *list, double *buf, int *pbc_flags) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = fp[j]; - } - return 1; -} - -/* ---------------------------------------------------------------------- */ - -void PairEAM::unpack_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) fp[i] = buf[m++]; -} - -/* ---------------------------------------------------------------------- */ - -int PairEAM::pack_reverse_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) buf[m++] = rho[i]; - return 1; -} - -/* ---------------------------------------------------------------------- */ - -void PairEAM::unpack_reverse_comm(int n, int *list, double *buf) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - rho[j] += buf[m++]; - } -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays -------------------------------------------------------------------------- */ - -int PairEAM::memory_usage() -{ - int bytes = 2 * nmax * sizeof(double); - return bytes; -} diff --git a/src/pair_eam_alloy.cpp b/src/pair_eam_alloy.cpp deleted file mode 100644 index ccd832c6ff..0000000000 --- a/src/pair_eam_alloy.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Stephen Foiles (SNL), Murray Daw (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_eam_alloy.h" -#include "atom.h" -#include "force.h" -#include "comm.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define MAXLINE 1024 - -/* ---------------------------------------------------------------------- */ - -PairEAMAlloy::PairEAMAlloy() -{ - one_coeff = 1; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairEAMAlloy::coeff(int narg, char **arg) -{ - if (!allocated) allocate(); - - if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); - - // insure I,J args are * * - - if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); - - // read EAM setfl file, possibly multiple times - // first clear setflag since are doing this once for I,J = *,* - // read for all i,j pairs where ith,jth mapping is non-zero - // set setflag i,j for non-zero pairs - // set mass of atom type if i = j - - int n = atom->ntypes; - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - setflag[i][j] = 0; - - int itable,ith,jth; - int ilo,ihi,jlo,jhi; - ilo = jlo = 1; - ihi = jhi = n; - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - ith = atoi(arg[2+i]); - jth = atoi(arg[2+j]); - if (ith > 0 && jth > 0) { - itable = read_setfl(arg[2],ith,jth); - if (i == j) atom->set_mass(i,tables[itable].mass); - tabindex[i][j] = itable; - 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 PairEAMAlloy::init_one(int i, int j) -{ - if (setflag[i][j] == 0) - error->all("All EAM pair coeffs are not set"); - - // EAM has only one cutoff = max of all pairwise cutoffs - // determine max by checking table assigned to all type pairs - // only setflag[i][j] = 1 is relevant (if hybrid, some may not be set) - - cutmax = 0.0; - for (int ii = 1; ii <= atom->ntypes; ii++) { - for (int jj = ii; jj <= atom->ntypes; jj++) { - if (setflag[ii][jj] == 0) continue; - cutmax = MAX(cutmax,tables[tabindex[ii][jj]].cut); - } - } - - return cutmax; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairEAMAlloy::init_style() -{ - // set communication sizes in comm class - - comm->maxforward_pair = MAX(comm->maxforward_pair,1); - comm->maxreverse_pair = MAX(comm->maxreverse_pair,1); - - // copy read-in-tables to multi-type setfl format - // interpolate final spline coeffs - - store_setfl(); - interpolate(); - - cutforcesq = cutmax*cutmax; -} - -/* ---------------------------------------------------------------------- - read ith,jth potential values from a multi-element alloy EAM file - read values into table and bcast values -------------------------------------------------------------------------- */ - -int PairEAMAlloy::read_setfl(char *file, int ith, int jth) -{ - // check if ith,jth portion of same file has already been read - // if yes, return index of table entry - // if no, extend table list - - for (int i = 0; i < ntables; i++) - if (ith == tables[i].ith && jth == tables[i].jth) return i; - - tables = (Table *) - memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); - - Table *tb = &tables[ntables]; - int n = strlen(file) + 1; - tb->filename = new char[n]; - strcpy(tb->filename,file); - tb->ith = ith; - tb->jth = jth; - - // open potential file - - int me = comm->me; - FILE *fp; - char line[MAXLINE]; - - if (me == 0) { - fp = fopen(file,"r"); - if (fp == NULL) { - char str[128]; - sprintf(str,"Cannot open EAM potential file %s",file); - error->one(str); - } - } - - // read and broadcast header - - int ntypes; - if (me == 0) { - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - sscanf(line,"%d",&ntypes); - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg %d %lg %lg", - &tb->nrho,&tb->drho,&tb->nr,&tb->dr,&tb->cut); - } - - MPI_Bcast(&ntypes,1,MPI_INT,0,world); - MPI_Bcast(&tb->nrho,1,MPI_INT,0,world); - MPI_Bcast(&tb->drho,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->nr,1,MPI_INT,0,world); - MPI_Bcast(&tb->dr,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->cut,1,MPI_DOUBLE,0,world); - - // check if ith,jth are consistent with ntypes - - if (ith > ntypes || jth > ntypes) - error->all("Requested atom types in EAM setfl file do not exist"); - - // allocate potential arrays and read/bcast them - // skip sections of file that don't correspond to ith,jth - // extract mass, frho, rhor for i,i from ith element section - // extract z2r for i,j from ith,jth array of z2r section - // note that ith can be < or > than jth - // set zr to NULL (funcl array) so it can be deallocated - - tb->frho = new double[tb->nrho+1]; - tb->rhor = new double[tb->nr+1]; - tb->z2r = new double[tb->nr+1]; - tb->zr = NULL; - - int i,j,tmp; - double mass; - - for (i = 1; i <= ntypes; i++) { - if (me == 0) { - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg",&tmp,&mass); - } - MPI_Bcast(&mass,1,MPI_DOUBLE,0,world); - - if (i == ith && ith == jth) { - tb->mass = mass; - if (me == 0) grab(fp,tb->nrho,&tb->frho[1]); - MPI_Bcast(&tb->frho[1],tb->nrho,MPI_DOUBLE,0,world); - if (me == 0) grab(fp,tb->nr,&tb->rhor[1]); - MPI_Bcast(&tb->rhor[1],tb->nr,MPI_DOUBLE,0,world); - } else { - if (me == 0) skip(fp,tb->nrho); - if (me == 0) skip(fp,tb->nr); - } - } - - for (i = 1; i <= ntypes; i++) { - for (j = 1; j <= i; j++) { - if ((i == ith && j == jth) || (j == ith && i == jth)) { - if (me == 0) grab(fp,tb->nr,&tb->z2r[1]); - MPI_Bcast(&tb->z2r[1],tb->nr,MPI_DOUBLE,0,world); - } else if (me == 0) skip(fp,tb->nr); - } - } - - // close the potential file - - if (me == 0) fclose(fp); - - ntables++; - return ntables-1; -} - -/* ---------------------------------------------------------------------- - store read-in setfl values in multi-type setfl format -------------------------------------------------------------------------- */ - -void PairEAMAlloy::store_setfl() -{ - int i,j,m; - - int ntypes = atom->ntypes; - - // set nrho,nr,drho,dr from any i,i table entry since all the same - - for (i = 1; i <= ntypes; i++) - if (setflag[i][i]) break; - - nrho = tables[tabindex[i][i]].nrho; - nr = tables[tabindex[i][i]].nr; - drho = tables[tabindex[i][i]].drho; - dr = tables[tabindex[i][i]].dr; - - // allocate multi-type setfl arrays - - if (frho) { - memory->destroy_2d_double_array(frho); - memory->destroy_2d_double_array(rhor); - memory->destroy_2d_double_array(zrtmp); - memory->destroy_3d_double_array(z2r); - } - - frho = (double **) - memory->create_2d_double_array(ntypes+1,nrho+1,"eam:frho"); - rhor = (double **) - memory->create_2d_double_array(ntypes+1,nr+1,"eam:rhor"); - zrtmp = (double **) - memory->create_2d_double_array(ntypes+1,nr+1,"eam:zrtmp"); - z2r = (double ***) - memory->create_3d_double_array(ntypes+1,ntypes+1,nr+1,"eam:frho"); - - // copy from read-in tables to multi-type setfl arrays - // frho,rhor are 1:ntypes, z2r is 1:ntypes,1:ntypes - // skip if setflag i,j = 0 (if hybrid, some may not be set) - - for (i = 1; i <= ntypes; i++) - for (j = i; j <= ntypes; j++) { - if (setflag[i][j] == 0) continue; - Table *tb = &tables[tabindex[i][j]]; - if (i == j) { - for (m = 1; m <= nrho; m++) frho[i][m] = tb->frho[m]; - for (m = 1; m <= nr; m++) rhor[i][m] = tb->rhor[m]; - } - for (m = 1; m <= nr; m++) z2r[i][j][m] = tb->z2r[m]; - } -} - -/* ---------------------------------------------------------------------- - interpolate EAM potentials -------------------------------------------------------------------------- */ - -void PairEAMAlloy::interpolate() -{ - // free memory from previous interpolation - - if (frho_0) interpolate_deallocate(); - - // interpolation spacings - - rdr = 1.0/dr; - rdrho = 1.0/drho; - - // allocate coeff arrays - - int n = atom->ntypes; - - frho_0 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_0"); - frho_1 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_1"); - frho_2 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_2"); - frho_3 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_3"); - frho_4 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_4"); - frho_5 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_5"); - frho_6 = memory->create_2d_double_array(n+1,nrho+1,"eam:frho_6"); - - rhor_0 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_0"); - rhor_1 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_1"); - rhor_2 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_2"); - rhor_3 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_3"); - rhor_4 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_4"); - rhor_5 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_5"); - rhor_6 = memory->create_2d_double_array(n+1,nr+1,"eam:rhor_6"); - - z2r_0 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_0"); - z2r_1 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_1"); - z2r_2 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_2"); - z2r_3 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_3"); - z2r_4 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_4"); - z2r_5 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_5"); - z2r_6 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam:z2r_6"); - - // frho interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - // if skip, set frho arrays to 0.0, since they will still be accessed - // for non-EAM atoms when compute() calculates embedding function - - int i,j,m; - - for (i = 1; i <= atom->ntypes; i++) { - if (setflag[i][i] == 0) { - for (m = 1; m <= nrho; m++) - frho_0[i][m] = frho_1[i][m] = frho_2[i][m] = frho_3[i][m] = - frho_4[i][m] = frho_5[i][m] = frho_6[i][m] = 0.0; - continue; - } - - for (m = 1; m <= nrho; m++) frho_0[i][m] = frho[i][m]; - - frho_1[i][1] = frho_0[i][2]-frho_0[i][1]; - frho_1[i][2] = 0.5*(frho_0[i][3]-frho_0[i][1]); - frho_1[i][nrho-1] = 0.5*(frho_0[i][nrho]-frho_0[i][nrho-2]); - frho_1[i][nrho] = frho_0[i][nrho]-frho_0[i][nrho-1]; - - for (m = 3; m <= nrho-2; m++) - frho_1[i][m] = ((frho_0[i][m-2]-frho_0[i][m+2]) + - 8.0*(frho_0[i][m+1]-frho_0[i][m-1]))/12.0; - - for (m = 1; m <= nrho-1; m++) { - frho_2[i][m] = 3.*(frho_0[i][m+1]-frho_0[i][m]) - - 2.0*frho_1[i][m] - frho_1[i][m+1]; - frho_3[i][m] = frho_1[i][m] + frho_1[i][m+1] - - 2.0*(frho_0[i][m+1]-frho_0[i][m]); - } - - frho_2[i][nrho] = 0.0; - frho_3[i][nrho] = 0.0; - - for (m = 1; m <= nrho; m++) { - frho_4[i][m] = frho_1[i][m]/drho; - frho_5[i][m] = 2.0*frho_2[i][m]/drho; - frho_6[i][m] = 3.0*frho_3[i][m]/drho; - } - } - - // rhor interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - - for (i = 1; i <= atom->ntypes; i++) { - if (setflag[i][i] == 0) continue; - - for (m = 1; m <= nr; m++) rhor_0[i][m] = rhor[i][m]; - - rhor_1[i][1] = rhor_0[i][2]-rhor_0[i][1]; - rhor_1[i][2] = 0.5*(rhor_0[i][3]-rhor_0[i][1]); - rhor_1[i][nr-1] = 0.5*(rhor_0[i][nr]-rhor_0[i][nr-2]); - rhor_1[i][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - rhor_1[i][m] = ((rhor_0[i][m-2]-rhor_0[i][m+2]) + - 8.0*(rhor_0[i][m+1]-rhor_0[i][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - rhor_2[i][m] = 3.0*(rhor_0[i][m+1]-rhor_0[i][m]) - - 2.0*rhor_1[i][m] - rhor_1[i][m+1]; - rhor_3[i][m] = rhor_1[i][m] + rhor_1[i][m+1] - - 2.0*(rhor_0[i][m+1]-rhor_0[i][m]); - } - - rhor_2[i][nr] = 0.0; - rhor_3[i][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - rhor_4[i][m] = rhor_1[i][m]/dr; - rhor_5[i][m] = 2.0*rhor_2[i][m]/dr; - rhor_6[i][m] = 3.0*rhor_3[i][m]/dr; - } - } - - // z2r interpolation for 1:ntypes,1:ntypes - // skip if setflag i,j = 0 (if hybrid, some may not be set) - // set j,i coeffs = i,j coeffs - - for (i = 1; i <= atom->ntypes; i++) { - for (j = i; j <= atom->ntypes; j++) { - if (setflag[i][j] == 0) continue; - - for (m = 1; m <= nr; m++) z2r_0[i][j][m] = z2r[i][j][m]; - - z2r_1[i][j][1] = z2r_0[i][j][2]-z2r_0[i][j][1]; - z2r_1[i][j][2] = 0.5*(z2r_0[i][j][3]-z2r_0[i][j][1]); - z2r_1[i][j][nr-1] = 0.5*(z2r_0[i][j][nr]-z2r_0[i][j][nr-2]); - z2r_1[i][j][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - z2r_1[i][j][m] = ((z2r_0[i][j][m-2]-z2r_0[i][j][m+2]) + - 8.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - z2r_2[i][j][m] = 3.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]) - - 2.0*z2r_1[i][j][m] - z2r_1[i][j][m+1]; - z2r_3[i][j][m] = z2r_1[i][j][m] + z2r_1[i][j][m+1] - - 2.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]); - } - - z2r_2[i][j][nr] = 0.0; - z2r_3[i][j][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - z2r_4[i][j][m] = z2r_1[i][j][m]/dr; - z2r_5[i][j][m] = 2.0*z2r_2[i][j][m]/dr; - z2r_6[i][j][m] = 3.0*z2r_3[i][j][m]/dr; - } - - for (m = 1; m <= nr; m++) { - z2r_0[j][i][m] = z2r_0[i][j][m]; - z2r_1[j][i][m] = z2r_1[i][j][m]; - z2r_2[j][i][m] = z2r_2[i][j][m]; - z2r_3[j][i][m] = z2r_3[i][j][m]; - z2r_4[j][i][m] = z2r_4[i][j][m]; - z2r_5[j][i][m] = z2r_5[i][j][m]; - z2r_6[j][i][m] = z2r_6[i][j][m]; - } - } - } -} diff --git a/src/pair_eam_alloy.h b/src/pair_eam_alloy.h deleted file mode 100644 index 9296baff48..0000000000 --- a/src/pair_eam_alloy.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_EAM_ALLOY_H -#define PAIR_EAM_ALLOY_H - -#include "pair_eam.h" - -class PairEAMAlloy : public PairEAM { - public: - PairEAMAlloy(); - void coeff(int, char **); - double init_one(int, int); - void init_style(); - - private: - int read_setfl(char *, int, int); - void store_setfl(); - void interpolate(); -}; - -#endif diff --git a/src/pair_eam_fs.cpp b/src/pair_eam_fs.cpp deleted file mode 100644 index e1cf0cc78b..0000000000 --- a/src/pair_eam_fs.cpp +++ /dev/null @@ -1,771 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Tim Lau (MIT) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_eam_fs.h" -#include "atom.h" -#include "force.h" -#include "update.h" -#include "comm.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define MAXLINE 1024 - -/* ---------------------------------------------------------------------- */ - -PairEAMFS::PairEAMFS() -{ - one_coeff = 1; -} - -/* ---------------------------------------------------------------------- */ - -PairEAMFS::~PairEAMFS() { - - // deallocate array unique to derived class, parent will deallocate the rest - - if (frho) memory->destroy_3d_double_array(rhor_fs); - - // insure derived-class's deallocate is called - // set ptr to NULL to prevent parent class from calling it's deallocate - - if (frho_0) interpolate_deallocate(); - frho_0 = NULL; -} - -/* ---------------------------------------------------------------------- */ - -void PairEAMFS::compute(int eflag, int vflag) -{ - int i,j,k,m,numneigh,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r,p,fforce,rhoip,rhojp,z2,z2p,recip,phi,phip,psip; - int *neighs; - double **f; - - // grow energy array if necessary - - if (atom->nmax > nmax) { - memory->sfree(rho); - memory->sfree(fp); - nmax = atom->nmax; - rho = (double *) memory->smalloc(nmax*sizeof(double),"eam:rho"); - fp = (double *) memory->smalloc(nmax*sizeof(double),"eam:fp"); - } - - eng_vdwl = 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; - int *type = atom->type; - int nlocal = atom->nlocal; - int newton_pair = force->newton_pair; - - // zero out density - - if (newton_pair) { - m = nlocal + atom->nghost; - for (i = 0; i < m; i++) rho[i] = 0.0; - } else for (i = 0; i < nlocal; i++) rho[i] = 0.0; - - // rho = density at each atom - // loop over neighbors of my atoms - // FS has type-specific rho functional - - for (i = 0; i < nlocal; 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]; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cutforcesq) { - jtype = type[j]; - p = sqrt(rsq)*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - rho[i] += - ((rhor_fs_3[jtype][itype][m]*p + rhor_fs_2[jtype][itype][m])*p + - rhor_fs_1[jtype][itype][m])*p + rhor_fs_0[jtype][itype][m]; - if (newton_pair || j < nlocal) - rho[j] += - ((rhor_fs_3[itype][jtype][m]*p + rhor_fs_2[itype][jtype][m])*p + - rhor_fs_1[itype][jtype][m])*p + rhor_fs_0[itype][jtype][m]; - } - } - } - - // communicate and sum densities - - if (newton_pair) comm->reverse_comm_pair(this); - - // fp = derivative of embedding energy at each atom - // phi = embedding energy at each atom - // FS is same as standard EAM - - for (i = 0; i < nlocal; i++) { - itype = type[i]; - p = rho[i]*rdrho + 1.0; - m = static_cast (p); - m = MAX(1,MIN(m,nrho-1)); - p -= m; - p = MIN(p,1.0); - fp[i] = (frho_6[itype][m]*p + frho_5[itype][m])*p + frho_4[itype][m]; - if (eflag) { - phi = ((frho_3[itype][m]*p + frho_2[itype][m])*p + - frho_1[itype][m])*p + frho_0[itype][m]; - eng_vdwl += phi; - } - } - - // communicate derivative of embedding function - - comm->comm_pair(this); - - // compute forces on each atom - // loop over neighbors of my atoms - // FS has type-specific rhoip and rhojp - - for (i = 0; i < nlocal; 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]; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cutforcesq) { - jtype = type[j]; - r = sqrt(rsq); - p = r*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - - // rhoip = derivative of (density at atom j due to atom i) - // rhojp = derivative of (density at atom i due to atom j) - // phi = pair potential energy - // phip = phi' - // z2 = phi * r - // z2p = (phi * r)' = (phi' r) + phi - // psip needs both fp[i] and fp[j] terms since r_ij appears in two - // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) - // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip - - rhoip = - (rhor_fs_6[itype][jtype][m]*p + rhor_fs_5[itype][jtype][m])*p + - rhor_fs_4[itype][jtype][m]; - rhojp = - (rhor_fs_6[jtype][itype][m]*p + rhor_fs_5[jtype][itype][m])*p + - rhor_fs_4[jtype][itype][m]; - z2 = ((z2r_3[itype][jtype][m]*p + z2r_2[itype][jtype][m])*p + - z2r_1[itype][jtype][m])*p + z2r_0[itype][jtype][m]; - z2p = (z2r_6[itype][jtype][m]*p + z2r_5[itype][jtype][m])*p + - z2r_4[itype][jtype][m]; - - recip = 1.0/r; - phi = z2*recip; - phip = z2p*recip - phi*recip; - psip = fp[i]*rhojp + fp[j]*rhoip + phip; - fforce = psip*recip; - f[i][0] -= delx*fforce; - f[i][1] -= dely*fforce; - f[i][2] -= delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] += delx*fforce; - f[j][1] += dely*fforce; - f[j][2] += delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) eng_vdwl += phi; - else eng_vdwl += 0.5*phi; - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] -= delx*delx*fforce; - virial[1] -= dely*dely*fforce; - virial[2] -= delz*delz*fforce; - virial[3] -= delx*dely*fforce; - virial[4] -= delx*delz*fforce; - virial[5] -= dely*delz*fforce; - } else { - virial[0] -= 0.5*delx*delx*fforce; - virial[1] -= 0.5*dely*dely*fforce; - virial[2] -= 0.5*delz*delz*fforce; - virial[3] -= 0.5*delx*dely*fforce; - virial[4] -= 0.5*delx*delz*fforce; - virial[5] -= 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairEAMFS::coeff(int narg, char **arg) -{ - if (!allocated) allocate(); - - if (narg != 3 + atom->ntypes) - error->all("Incorrect args for pair coefficients"); - - // insure I,J args are * * - // can only have one file, so clear all setflag settings - - if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) - error->all("Incorrect args for pair coefficients"); - - // read Finnis/Sinclair modified setfl file - // first clear setflag since are doing this once for I,J = *,* - // read for all i,j pairs where ith,jth mapping is non-zero - // set setflag i,j for non-zero pairs - // set mass of atom type if i = j - - int n = atom->ntypes; - for (int i = 1; i <= n; i++) - for (int j = 1; j <= n; j++) - setflag[i][j] = 0; - - int itable,ith,jth; - int ilo,ihi,jlo,jhi; - ilo = jlo = 1; - ihi = jhi = n; - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = jlo; j <= jhi; j++) { - ith = atoi(arg[2+i]); - jth = atoi(arg[2+j]); - if (ith > 0 && jth > 0) { - itable = read_setfl(arg[2],ith,jth); - if (i == j) atom->set_mass(i,tables[itable].mass); - tabindex[i][j] = itable; - 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 PairEAMFS::init_one(int i, int j) -{ - if (setflag[i][j] == 0) - error->all("All EAM pair coeffs are not set"); - - // EAM has only one cutoff = max of all pairwise cutoffs - // determine max by checking table assigned to all type pairs - // only setflag[i][j] = 1 is relevant (if hybrid, some may not be set) - - cutmax = 0.0; - for (int ii = 1; ii <= atom->ntypes; ii++) { - for (int jj = ii; jj <= atom->ntypes; jj++) { - if (setflag[ii][jj] == 0) continue; - cutmax = MAX(cutmax,tables[tabindex[ii][jj]].cut); - } - } - - return cutmax; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairEAMFS::init_style() -{ - // set communication sizes in comm class - - comm->maxforward_pair = MAX(comm->maxforward_pair,1); - comm->maxreverse_pair = MAX(comm->maxreverse_pair,1); - - // copy read-in-tables to multi-type setfl format - // interpolate final spline coeffs - - store_setfl(); - interpolate(); - - cutforcesq = cutmax*cutmax; -} - -/* ---------------------------------------------------------------------- - read ith,jth potential values from a multi-element alloy EAM/FS file - read values into table and bcast values - this file has different format than standard EAM setfl file -------------------------------------------------------------------------- */ - -int PairEAMFS::read_setfl(char *file, int ith, int jth) -{ - // check if ith,jth portion of same file has already been read - // if yes, return index of table entry - // if no, extend table list - - for (int i = 0; i < ntables; i++) - if (ith == tables[i].ith && jth == tables[i].jth) return i; - - tables = (Table *) - memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); - - Table *tb = &tables[ntables]; - int n = strlen(file) + 1; - tb->filename = new char[n]; - strcpy(tb->filename,file); - tb->ith = ith; - tb->jth = jth; - - // open potential file - - int me = comm->me; - FILE *fp; - char line[MAXLINE]; - - if (me == 0) { - fp = fopen(file,"r"); - if (fp == NULL) { - char str[128]; - sprintf(str,"Cannot open EAM potential file %s",file); - error->one(str); - } - } - - // read and broadcast header - - int ntypes; - if (me == 0) { - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - fgets(line,MAXLINE,fp); - sscanf(line,"%d",&ntypes); - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg %d %lg %lg", - &tb->nrho,&tb->drho,&tb->nr,&tb->dr,&tb->cut); - } - - MPI_Bcast(&ntypes,1,MPI_INT,0,world); - MPI_Bcast(&tb->nrho,1,MPI_INT,0,world); - MPI_Bcast(&tb->drho,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->nr,1,MPI_INT,0,world); - MPI_Bcast(&tb->dr,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->cut,1,MPI_DOUBLE,0,world); - - // check if ith,jth are consistent with ntypes - - if (ith > ntypes || jth > ntypes) - error->all("Requested atom types in EAM setfl file do not exist"); - - // allocate potential arrays and read/bcast them - // skip sections of file that don't correspond to ith,jth - // extract mass, frho for i,i from ith element section - // extract rhor for i,j from jth array of ith element section - // extract z2r for i,j from ith,jth array of z2r section - // note that ith can be < or > than jth - // set zr to NULL (funcl array) so it can be deallocated - - tb->frho = new double[tb->nrho+1]; - tb->rhor = new double[tb->nr+1]; - tb->z2r = new double[tb->nr+1]; - tb->zr = NULL; - - int i,j,tmp; - double mass; - - for (i = 1; i <= ntypes; i++) { - if (me == 0) { - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg",&tmp,&mass); - } - MPI_Bcast(&mass,1,MPI_DOUBLE,0,world); - - if (i == ith && ith == jth) { - tb->mass = mass; - if (me == 0) grab(fp,tb->nrho,&tb->frho[1]); - MPI_Bcast(&tb->frho[1],tb->nrho,MPI_DOUBLE,0,world); - - for (j = 1; j <= ntypes; j++) { - if (j == jth) { - if (me == 0) grab(fp,tb->nr,&tb->rhor[1]); - MPI_Bcast(&tb->rhor[1],tb->nr,MPI_DOUBLE,0,world); - } else if (me == 0) skip(fp,tb->nr); - } - - } else if (i == ith && ith != jth) { - if (me == 0) skip(fp,tb->nrho); - for (j = 1; j <= ntypes; j++) { - if (j == jth) { - if (me == 0) grab(fp,tb->nr,&tb->rhor[1]); - MPI_Bcast(&tb->rhor[1],tb->nr,MPI_DOUBLE,0,world); - } else if (me == 0) skip(fp,tb->nr); - } - - } else { - if (me == 0) skip(fp,tb->nrho); - if (me == 0) for (j = 1; j <= ntypes; j = j + 1) skip(fp,tb->nr); - } - } - - for (i = 1; i <= ntypes; i++) { - for (j = 1; j <= i; j++) { - if ((i == ith && j == jth) || (j == ith && i == jth)) { - if (me == 0) grab(fp,tb->nr,&tb->z2r[1]); - MPI_Bcast(&tb->z2r[1],tb->nr,MPI_DOUBLE,0,world); - } else if (me == 0) skip(fp,tb->nr); - } - } - - // close the potential file - - if (me == 0) fclose(fp); - - ntables++; - return ntables-1; -} - -/* ---------------------------------------------------------------------- - store read-in setfl values in multi-type setfl format -------------------------------------------------------------------------- */ - -void PairEAMFS::store_setfl() -{ - int i,j,m; - - int ntypes = atom->ntypes; - - // set nrho,nr,drho,dr from any i,i table entry since all the same - - for (i = 1; i <= ntypes; i++) - if (setflag[i][i]) break; - - nrho = tables[tabindex[i][i]].nrho; - nr = tables[tabindex[i][i]].nr; - drho = tables[tabindex[i][i]].drho; - dr = tables[tabindex[i][i]].dr; - - // allocate multi-type setfl arrays - - if (frho) { - memory->destroy_2d_double_array(frho); - memory->destroy_3d_double_array(rhor_fs); - memory->destroy_2d_double_array(zrtmp); - memory->destroy_3d_double_array(z2r); - } - - frho = (double **) - memory->create_2d_double_array(ntypes+1,nrho+1,"eam/fs:frho"); - rhor_fs = (double ***) - memory->create_3d_double_array(ntypes+1,ntypes+1,nr+1,"eam/fs:rhor_fs"); - zrtmp = (double **) - memory->create_2d_double_array(ntypes+1,nr+1,"eam/fs:zrtmp"); - z2r = (double ***) - memory->create_3d_double_array(ntypes+1,ntypes+1,nr+1,"eam/fs:frho"); - - // copy from read-in tables to multi-type setfl arrays - // frho,rhor are 1:ntypes, z2r is 1:ntypes,1:ntypes - // skip if setflag i,j = 0 (if hybrid, some may not be set) - - for (i = 1; i <= ntypes; i++) - for (j = 1; j <= ntypes; j++) { - if (setflag[i][j] == 0) continue; - Table *tb = &tables[tabindex[i][j]]; - if (i == j) for (m = 1; m <= nrho; m++) frho[i][m] = tb->frho[m]; - for (m = 1; m <= nr; m++) { - rhor_fs[i][j][m] = tb->rhor[m]; - z2r[i][j][m] = tb->z2r[m]; - } - } -} - -/* ---------------------------------------------------------------------- - interpolate EAM potentials -------------------------------------------------------------------------- */ - -void PairEAMFS::interpolate() -{ - // free memory from previous interpolation - - if (frho_0) interpolate_deallocate(); - - // interpolation spacings - - rdr = 1.0/dr; - rdrho = 1.0/drho; - - // allocate coeff arrays - - int n = atom->ntypes; - - frho_0 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_0"); - frho_1 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_1"); - frho_2 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_2"); - frho_3 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_3"); - frho_4 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_4"); - frho_5 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_5"); - frho_6 = memory->create_2d_double_array(n+1,nrho+1,"eam/fs:frho_6"); - - rhor_fs_0 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_0"); - rhor_fs_1 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_1"); - rhor_fs_2 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_2"); - rhor_fs_3 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_3"); - rhor_fs_4 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_4"); - rhor_fs_5 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_5"); - rhor_fs_6 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:rhor_fs_6"); - - z2r_0 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_0"); - z2r_1 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_1"); - z2r_2 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_2"); - z2r_3 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_3"); - z2r_4 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_4"); - z2r_5 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_5"); - z2r_6 = memory->create_3d_double_array(n+1,n+1,nr+1,"eam/fs:z2r_6"); - - // frho interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - // if skip, set frho arrays to 0.0, since they will still be accessed - // for non-EAM atoms when compute() calculates embedding function - - int i,j,m; - - for (i = 1; i <= atom->ntypes; i++) { - if (setflag[i][i] == 0) { - for (j = 1; j <= n; j++) - for (m = 1; m <= nrho; m++) - frho_0[j][m] = frho_1[j][m] = frho_2[j][m] = frho_3[j][m] = - frho_4[j][m] = frho_5[j][m] = frho_6[j][m] = 0.0; - continue; - } - - for (m = 1; m <= nrho; m++) frho_0[i][m] = frho[i][m]; - - frho_1[i][1] = frho_0[i][2]-frho_0[i][1]; - frho_1[i][2] = 0.5*(frho_0[i][3]-frho_0[i][1]); - frho_1[i][nrho-1] = 0.5*(frho_0[i][nrho]-frho_0[i][nrho-2]); - frho_1[i][nrho] = frho_0[i][nrho]-frho_0[i][nrho-1]; - - for (m = 3; m <= nrho-2; m++) - frho_1[i][m] = ((frho_0[i][m-2]-frho_0[i][m+2]) + - 8.0*(frho_0[i][m+1]-frho_0[i][m-1]))/12.0; - - for (m = 1; m <= nrho-1; m++) { - frho_2[i][m] = 3.*(frho_0[i][m+1]-frho_0[i][m]) - - 2.0*frho_1[i][m] - frho_1[i][m+1]; - frho_3[i][m] = frho_1[i][m] + frho_1[i][m+1] - - 2.0*(frho_0[i][m+1]-frho_0[i][m]); - } - - frho_2[i][nrho] = 0.0; - frho_3[i][nrho] = 0.0; - - for (m = 1; m <= nrho; m++) { - frho_4[i][m] = frho_1[i][m]/drho; - frho_5[i][m] = 2.0*frho_2[i][m]/drho; - frho_6[i][m] = 3.0*frho_3[i][m]/drho; - } - } - - // rhor interpolation for 1:ntypes - // skip if setflag = 0 (if hybrid, some may not be set) - - for (i = 1; i <= atom->ntypes; i++) { - for (j = 1; j <= atom->ntypes; j++) { - if (setflag[i][j] == 0) continue; - - for (m = 1; m <= nr; m++) rhor_fs_0[i][j][m] = rhor_fs[i][j][m]; - - rhor_fs_1[i][j][1] = rhor_fs_0[i][j][2]-rhor_fs_0[i][j][1]; - rhor_fs_1[i][j][2] = 0.5*(rhor_fs_0[i][j][3]-rhor_fs_0[i][j][1]); - rhor_fs_1[i][j][nr-1] = 0.5*(rhor_fs_0[i][j][nr]-rhor_fs_0[i][j][nr-2]); - rhor_fs_1[i][j][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - rhor_fs_1[i][j][m] = ((rhor_fs_0[i][j][m-2]-rhor_fs_0[i][j][m+2]) + - 8.0*(rhor_fs_0[i][j][m+1]-rhor_fs_0[i][j][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - rhor_fs_2[i][j][m] = 3.0*(rhor_fs_0[i][j][m+1]-rhor_fs_0[i][j][m]) - - 2.0*rhor_fs_1[i][j][m] - rhor_fs_1[i][j][m+1]; - rhor_fs_3[i][j][m] = rhor_fs_1[i][j][m] + rhor_fs_1[i][j][m+1] - - 2.0*(rhor_fs_0[i][j][m+1]-rhor_fs_0[i][j][m]); - } - - rhor_fs_2[i][j][nr] = 0.0; - rhor_fs_3[i][j][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - rhor_fs_4[i][j][m] = rhor_fs_1[i][j][m]/dr; - rhor_fs_5[i][j][m] = 2.0*rhor_fs_2[i][j][m]/dr; - rhor_fs_6[i][j][m] = 3.0*rhor_fs_3[i][j][m]/dr; - } - } - } - - // z2r interpolation for 1:ntypes,1:ntypes - // skip if setflag i,j = 0 (if hybrid, some may not be set) - // set j,i coeffs = i,j coeffs - - for (i = 1; i <= atom->ntypes; i++) { - for (j = i; j <= atom->ntypes; j++) { - if (setflag[i][j] == 0) continue; - - for (m = 1; m <= nr; m++) z2r_0[i][j][m] = z2r[i][j][m]; - - z2r_1[i][j][1] = z2r_0[i][j][2]-z2r_0[i][j][1]; - z2r_1[i][j][2] = 0.5*(z2r_0[i][j][3]-z2r_0[i][j][1]); - z2r_1[i][j][nr-1] = 0.5*(z2r_0[i][j][nr]-z2r_0[i][j][nr-2]); - z2r_1[i][j][nr] = 0.0; - - for (m = 3; m <= nr-2; m++) - z2r_1[i][j][m] = ((z2r_0[i][j][m-2]-z2r_0[i][j][m+2]) + - 8.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m-1]))/12.; - - for (m = 1; m <= nr-1; m++) { - z2r_2[i][j][m] = 3.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]) - - 2.0*z2r_1[i][j][m] - z2r_1[i][j][m+1]; - z2r_3[i][j][m] = z2r_1[i][j][m] + z2r_1[i][j][m+1] - - 2.0*(z2r_0[i][j][m+1]-z2r_0[i][j][m]); - } - - z2r_2[i][j][nr] = 0.0; - z2r_3[i][j][nr] = 0.0; - - for (m = 1; m <= nr; m++) { - z2r_4[i][j][m] = z2r_1[i][j][m]/dr; - z2r_5[i][j][m] = 2.0*z2r_2[i][j][m]/dr; - z2r_6[i][j][m] = 3.0*z2r_3[i][j][m]/dr; - } - - for (m = 1; m <= nr; m++) { - z2r_0[j][i][m] = z2r_0[i][j][m]; - z2r_1[j][i][m] = z2r_1[i][j][m]; - z2r_2[j][i][m] = z2r_2[i][j][m]; - z2r_3[j][i][m] = z2r_3[i][j][m]; - z2r_4[j][i][m] = z2r_4[i][j][m]; - z2r_5[j][i][m] = z2r_5[i][j][m]; - z2r_6[j][i][m] = z2r_6[i][j][m]; - } - } - } -} - -/* ---------------------------------------------------------------------- - deallocate spline interpolation arrays -------------------------------------------------------------------------- */ - -void PairEAMFS::interpolate_deallocate() -{ - memory->destroy_2d_double_array(frho_0); - memory->destroy_2d_double_array(frho_1); - memory->destroy_2d_double_array(frho_2); - memory->destroy_2d_double_array(frho_3); - memory->destroy_2d_double_array(frho_4); - memory->destroy_2d_double_array(frho_5); - memory->destroy_2d_double_array(frho_6); - - memory->destroy_3d_double_array(rhor_fs_0); - memory->destroy_3d_double_array(rhor_fs_1); - memory->destroy_3d_double_array(rhor_fs_2); - memory->destroy_3d_double_array(rhor_fs_3); - memory->destroy_3d_double_array(rhor_fs_4); - memory->destroy_3d_double_array(rhor_fs_5); - memory->destroy_3d_double_array(rhor_fs_6); - - memory->destroy_3d_double_array(z2r_0); - memory->destroy_3d_double_array(z2r_1); - memory->destroy_3d_double_array(z2r_2); - memory->destroy_3d_double_array(z2r_3); - memory->destroy_3d_double_array(z2r_4); - memory->destroy_3d_double_array(z2r_5); - memory->destroy_3d_double_array(z2r_6); -} - -/* ---------------------------------------------------------------------- */ - -void PairEAMFS::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, - int eflag, One &one) -{ - double r,p,rhoip,rhojp,z2,z2p,recip,phi,phip,psip; - int m; - - r = sqrt(rsq); - p = r*rdr + 1.0; - m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - - rhoip = (rhor_fs_6[itype][jtype][m]*p + rhor_fs_5[itype][jtype][m])*p + - rhor_fs_4[itype][jtype][m]; - rhojp = (rhor_fs_6[jtype][itype][m]*p + rhor_fs_5[jtype][itype][m])*p + - rhor_fs_4[jtype][itype][m]; - z2 = ((z2r_3[itype][jtype][m]*p + z2r_2[itype][jtype][m])*p + - z2r_1[itype][jtype][m])*p + z2r_0[itype][jtype][m]; - z2p = (z2r_6[itype][jtype][m]*p + z2r_5[itype][jtype][m])*p + - z2r_4[itype][jtype][m]; - - recip = 1.0/r; - phi = z2*recip; - phip = z2p*recip - phi*recip; - psip = fp[i]*rhojp + fp[j]*rhoip + phip; - one.fforce = -psip*recip; - - if (eflag) { - one.eng_vdwl = phi; - one.eng_coul = 0.0; - } -} diff --git a/src/pair_eam_fs.h b/src/pair_eam_fs.h deleted file mode 100644 index 1787d1beab..0000000000 --- a/src/pair_eam_fs.h +++ /dev/null @@ -1,40 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_EAM_FS_H -#define PAIR_EAM_FS_H - -#include "pair_eam.h" - -class PairEAMFS : public PairEAM { - public: - PairEAMFS(); - ~PairEAMFS(); - void compute(int, int); - void coeff(int, char **); - double init_one(int, int); - void init_style(); - void single(int, int, int, int, double, double, double, int, One &); - - private: - double ***rhor_fs; - double ***rhor_fs_0,***rhor_fs_1,***rhor_fs_2,***rhor_fs_3; - double ***rhor_fs_4,***rhor_fs_5,***rhor_fs_6; - - int read_setfl(char *, int, int); - void store_setfl(); - void interpolate(); - void interpolate_deallocate(); -}; - -#endif diff --git a/src/pair_lj_charmm_coul_charmm.cpp b/src/pair_lj_charmm_coul_charmm.cpp deleted file mode 100644 index 101043e997..0000000000 --- a/src/pair_lj_charmm_coul_charmm.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "pair_lj_charmm_coul_charmm.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "update.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* ---------------------------------------------------------------------- */ - -PairLJCharmmCoulCharmm::~PairLJCharmmCoulCharmm() -{ - if (allocated) { - memory->destroy_2d_int_array(setflag); - memory->destroy_2d_double_array(cutsq); - - memory->destroy_2d_double_array(epsilon); - memory->destroy_2d_double_array(sigma); - memory->destroy_2d_double_array(eps14); - memory->destroy_2d_double_array(sigma14); - 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(lj14_1); - memory->destroy_2d_double_array(lj14_2); - memory->destroy_2d_double_array(lj14_3); - memory->destroy_2d_double_array(lj14_4); - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double factor,phicoul,philj,switch1,switch2; - 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; - int *type = atom->type; - 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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_bothsq) { - r2inv = 1.0/rsq; - - if (rsq < cut_coulsq) { - forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / denom_coul; - switch2 = 12.0*rsq * (cut_coulsq-rsq) * - (rsq-cut_coul_innersq) / denom_coul; - forcecoul *= switch1 + switch2; - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - jtype = type[j]; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - - fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - phicoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / - denom_coul; - phicoul *= switch1; - } - eng_coul += factor*factor_coul*phicoul; - } - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - eng_vdwl += factor*factor_lj*philj; - } - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::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"); - - epsilon = memory->create_2d_double_array(n+1,n+1,"pair:epsilon"); - sigma = memory->create_2d_double_array(n+1,n+1,"pair:sigma"); - eps14 = memory->create_2d_double_array(n+1,n+1,"pair:eps14"); - sigma14 = memory->create_2d_double_array(n+1,n+1,"pair:sigma14"); - 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"); - lj14_1 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_1"); - lj14_2 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_2"); - lj14_3 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_3"); - lj14_4 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_4"); -} - -/* ---------------------------------------------------------------------- - global settings - unlike other pair styles, - there are no individual pair settings that these override -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::settings(int narg, char **arg) -{ - if (narg != 2 && narg != 4) - error->all("Illegal pair_style command"); - - cut_lj_inner = atof(arg[0]); - cut_lj = atof(arg[1]); - if (narg == 2) { - cut_coul_inner = cut_lj_inner; - cut_coul = cut_lj; - } else { - cut_coul_inner = atof(arg[2]); - cut_coul = atof(arg[3]); - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::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 eps14_one = epsilon_one; - double sigma14_one = sigma_one; - if (narg == 6) { - eps14_one = atof(arg[4]); - sigma14_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; - eps14[i][j] = eps14_one; - sigma14[i][j] = sigma14_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 PairLJCharmmCoulCharmm::init_one(int i, int j) -{ - // always mix arithmetically - - if (setflag[i][j] == 0) { - epsilon[i][j] = sqrt(epsilon[i][i]*epsilon[j][j]); - sigma[i][j] = 0.5 * (sigma[i][i] + sigma[j][j]); - eps14[i][j] = sqrt(eps14[i][i]*eps14[j][j]); - sigma14[i][j] = 0.5 * (sigma14[i][i] + sigma14[j][j]); - } - - double cut = MAX(cut_lj,cut_coul); - - 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); - lj14_1[i][j] = 48.0 * eps14[i][j] * pow(sigma14[i][j],12.0); - lj14_2[i][j] = 24.0 * eps14[i][j] * pow(sigma14[i][j],6.0); - lj14_3[i][j] = 4.0 * eps14[i][j] * pow(sigma14[i][j],12.0); - lj14_4[i][j] = 4.0 * eps14[i][j] * pow(sigma14[i][j],6.0); - - lj1[j][i] = lj1[i][j]; - lj2[j][i] = lj2[i][j]; - lj3[j][i] = lj3[i][j]; - lj4[j][i] = lj4[i][j]; - lj14_1[j][i] = lj14_1[i][j]; - lj14_2[j][i] = lj14_2[i][j]; - lj14_3[j][i] = lj14_3[i][j]; - lj14_4[j][i] = lj14_4[i][j]; - - return cut; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::init_style() -{ - // require an atom style with charge defined - - if (atom->charge_allow == 0) - error->all("Must use charged atom style with this pair style"); - - // require cut_lj_inner < cut_lj, cut_coul_inner < cut_coul - - if (cut_lj_inner >= cut_lj || cut_coul_inner >= cut_coul) - error->all("Pair inner cutoff >= Pair outer cutoff"); - - cut_lj_innersq = cut_lj_inner * cut_lj_inner; - cut_ljsq = cut_lj * cut_lj; - cut_coul_innersq = cut_coul_inner * cut_coul_inner; - cut_coulsq = cut_coul * cut_coul; - cut_bothsq = MAX(cut_ljsq,cut_coulsq); - - denom_lj = (cut_ljsq-cut_lj_innersq) * (cut_ljsq-cut_lj_innersq) * - (cut_ljsq-cut_lj_innersq); - denom_coul = (cut_coulsq-cut_coul_innersq) * (cut_coulsq-cut_coul_innersq) * - (cut_coulsq-cut_coul_innersq); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::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(&eps14[i][j],sizeof(double),1,fp); - fwrite(&sigma14[i][j],sizeof(double),1,fp); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::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(&eps14[i][j],sizeof(double),1,fp); - fread(&sigma14[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(&eps14[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&sigma14[i][j],1,MPI_DOUBLE,0,world); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::write_restart_settings(FILE *fp) -{ - fwrite(&cut_lj_inner,sizeof(double),1,fp); - fwrite(&cut_lj,sizeof(double),1,fp); - fwrite(&cut_coul_inner,sizeof(double),1,fp); - fwrite(&cut_coul,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 PairLJCharmmCoulCharmm::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_lj_inner,sizeof(double),1,fp); - fread(&cut_lj,sizeof(double),1,fp); - fread(&cut_coul_inner,sizeof(double),1,fp); - fread(&cut_coul,sizeof(double),1,fp); - fread(&offset_flag,sizeof(int),1,fp); - fread(&mix_flag,sizeof(int),1,fp); - } - MPI_Bcast(&cut_lj_inner,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_lj,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_coul_inner,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmm::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, - double factor_lj, - int eflag, One &one) -{ - double r2inv,r6inv,switch1,switch2,forcecoul,forcelj,phicoul,philj; - - r2inv = 1.0/rsq; - if (rsq < cut_coulsq) { - forcecoul = force->qqrd2e * atom->q[i]*atom->q[j]*sqrt(r2inv); - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / denom_coul; - switch2 = 12.0*rsq * (cut_coulsq-rsq) * - (rsq-cut_coul_innersq) / denom_coul; - forcecoul *= switch1 + switch2; - } - } else forcecoul = 0.0; - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - one.fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; - - if (eflag) { - if (rsq < cut_coulsq) { - phicoul = force->qqrd2e * atom->q[i]*atom->q[j]*sqrt(r2inv); - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / - denom_coul; - phicoul *= switch1; - } - one.eng_coul = factor_coul*phicoul; - } else one.eng_coul = 0.0; - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - one.eng_vdwl = factor_lj*philj; - } else one.eng_vdwl = 0.0; - } -} diff --git a/src/pair_lj_charmm_coul_charmm.h b/src/pair_lj_charmm_coul_charmm.h deleted file mode 100644 index d6a6c63d29..0000000000 --- a/src/pair_lj_charmm_coul_charmm.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_LJ_CHARMM_COUL_CHARMM_H -#define PAIR_LJ_CHARMM_COUL_CHARMM_H - -#include "pair.h" - -class PairLJCharmmCoulCharmm : public Pair { - public: - // these variables are public so DihedralCharmm can see them - double **lj14_1,**lj14_2,**lj14_3,**lj14_4; - - PairLJCharmmCoulCharmm() {} - ~PairLJCharmmCoulCharmm(); - virtual 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 *); - virtual void single(int, int, int, int, double, double, double, int, One &); - - protected: - double cut_lj_inner,cut_lj,cut_coul_inner,cut_coul; - double cut_lj_innersq,cut_ljsq,cut_coul_innersq,cut_coulsq,cut_bothsq; - double denom_lj,denom_coul; - double **epsilon,**sigma,**eps14,**sigma14; - double **lj1,**lj2,**lj3,**lj4; - - void allocate(); -}; - -#endif diff --git a/src/pair_lj_charmm_coul_charmm_implicit.cpp b/src/pair_lj_charmm_coul_charmm_implicit.cpp deleted file mode 100644 index d4bc75b172..0000000000 --- a/src/pair_lj_charmm_coul_charmm_implicit.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "pair_lj_charmm_coul_charmm_implicit.h" -#include "atom.h" -#include "force.h" -#include "update.h" -#include "neighbor.h" - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double factor,phicoul,philj,switch1,switch2; - 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; - int *type = atom->type; - 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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_bothsq) { - r2inv = 1.0/rsq; - - if (rsq < cut_coulsq) { - forcecoul = 2.0 * qqrd2e * qtmp*q[j]*r2inv; - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / denom_coul; - switch2 = 12.0*rsq * (cut_coulsq-rsq) * - (rsq-cut_coul_innersq) / denom_coul; - forcecoul *= switch1 + switch2; - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - jtype = type[j]; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - - fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - phicoul = qqrd2e * qtmp*q[j]*r2inv; - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / - denom_coul; - phicoul *= switch1; - } - eng_coul += factor*factor_coul*phicoul; - } - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - eng_vdwl += factor*factor_lj*philj; - } - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulCharmmImplicit::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, - double factor_lj, - int eflag, One &one) -{ - double r2inv,r6inv,switch1,switch2,forcecoul,forcelj,phicoul,philj; - - r2inv = 1.0/rsq; - if (rsq < cut_coulsq) { - forcecoul = 2.0 * force->qqrd2e * atom->q[i]*atom->q[j]*r2inv; - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / denom_coul; - switch2 = 12.0*rsq * (cut_coulsq-rsq) * - (rsq-cut_coul_innersq) / denom_coul; - forcecoul *= switch1 + switch2; - } - } else forcecoul = 0.0; - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - one.fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; - - if (eflag) { - if (rsq < cut_coulsq) { - phicoul = force->qqrd2e * atom->q[i]*atom->q[j]*r2inv; - if (rsq > cut_coul_innersq) { - switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * - (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / - denom_coul; - phicoul *= switch1; - } - one.eng_coul = factor_coul*phicoul; - } else one.eng_coul = 0.0; - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - one.eng_vdwl = factor_lj*philj; - } else one.eng_vdwl = 0.0; - } -} diff --git a/src/pair_lj_charmm_coul_charmm_implicit.h b/src/pair_lj_charmm_coul_charmm_implicit.h deleted file mode 100644 index 2ef707551f..0000000000 --- a/src/pair_lj_charmm_coul_charmm_implicit.h +++ /dev/null @@ -1,25 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_LJ_CHARMM_COUL_CHARMM_IMPLICIT_H -#define PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_H - -#include "pair_lj_charmm_coul_charmm.h" - -class PairLJCharmmCoulCharmmImplicit : public PairLJCharmmCoulCharmm { - public: - void compute(int, int); - void single(int, int, int, int, double, double, double, int, One &); -}; - -#endif diff --git a/src/pair_lj_charmm_coul_long.cpp b/src/pair_lj_charmm_coul_long.cpp deleted file mode 100644 index d9e8d1713d..0000000000 --- a/src/pair_lj_charmm_coul_long.cpp +++ /dev/null @@ -1,1160 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_lj_charmm_coul_long.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "kspace.h" -#include "update.h" -#include "integrate.h" -#include "respa.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define A1 0.254829592 -#define A2 -0.284496736 -#define A3 1.421413741 -#define A4 -1.453152027 -#define A5 1.061405429 - -/* ---------------------------------------------------------------------- */ - -PairLJCharmmCoulLong::PairLJCharmmCoulLong() -{ - respa_enable = 1; - ftable = NULL; -} - -/* ---------------------------------------------------------------------- */ - -PairLJCharmmCoulLong::~PairLJCharmmCoulLong() -{ - if (allocated) { - memory->destroy_2d_int_array(setflag); - memory->destroy_2d_double_array(cutsq); - - memory->destroy_2d_double_array(epsilon); - memory->destroy_2d_double_array(sigma); - memory->destroy_2d_double_array(eps14); - memory->destroy_2d_double_array(sigma14); - 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(lj14_1); - memory->destroy_2d_double_array(lj14_2); - memory->destroy_2d_double_array(lj14_3); - memory->destroy_2d_double_array(lj14_4); - } - if (ftable) free_tables(); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype,itable; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; - double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double factor,phicoul,philj,switch1,switch2; - int *neighs; - double **f; - float rsq; - int *int_rsq = (int *) &rsq; - - 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; - int *type = atom->type; - 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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_bothsq) { - r2inv = 1.0/rsq; - - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - jtype = type[j]; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - phicoul = qtmp*q[j] * table; - } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - eng_coul += factor*phicoul; - } - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - eng_vdwl += factor*factor_lj*philj; - } - } - - if (vflag == 1) { - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::compute_inner() -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double rsw; - int *neighs; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_out_on = cut_respa[0]; - double cut_out_off = cut_respa[1]; - - double cut_out_diff = cut_out_off - cut_out_on; - double cut_out_on_sq = cut_out_on*cut_out_on; - double cut_out_off_sq = cut_out_off*cut_out_off; - - // 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_inner[i]; - numneigh = neighbor->numneigh_inner[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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_out_off_sq) { - r2inv = 1.0/rsq; - forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*forcecoul; - - r6inv = r2inv*r2inv*r2inv; - jtype = type[j]; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - if (rsq > cut_out_on_sq) { - rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; - fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); - } - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::compute_middle() -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double philj,switch1,switch2; - double rsw; - int *neighs; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_in_off = cut_respa[0]; - double cut_in_on = cut_respa[1]; - double cut_out_on = cut_respa[2]; - double cut_out_off = cut_respa[3]; - - double cut_in_diff = cut_in_on - cut_in_off; - double cut_out_diff = cut_out_off - cut_out_on; - double cut_in_off_sq = cut_in_off*cut_in_off; - double cut_in_on_sq = cut_in_on*cut_in_on; - double cut_out_on_sq = cut_out_on*cut_out_on; - double cut_out_off_sq = cut_out_off*cut_out_off; - - // 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_middle[i]; - numneigh = neighbor->numneigh_middle[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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_out_off_sq && rsq > cut_in_off_sq) { - r2inv = 1.0/rsq; - forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*forcecoul; - - r6inv = r2inv*r2inv*r2inv; - jtype = type[j]; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - if (rsq < cut_in_on_sq) { - rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; - fforce *= rsw*rsw*(3.0 - 2.0*rsw); - } - if (rsq > cut_out_on_sq) { - rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; - fforce *= 1.0 + rsw*rsw*(2.0*rsw - 3.0); - } - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype,itable; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; - double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double factor,phicoul,philj,switch1,switch2; - double rsw; - int *neighs; - float rsq; - int *int_rsq = (int *) &rsq; - - eng_vdwl = eng_coul = 0.0; - if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_in_off = cut_respa[2]; - double cut_in_on = cut_respa[3]; - - double cut_in_diff = cut_in_on - cut_in_off; - double cut_in_off_sq = cut_in_off*cut_in_off; - double cut_in_on_sq = cut_in_on*cut_in_on; - - // 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 %= 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 < cut_bothsq) { - r2inv = 1.0/rsq; - - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - 1.0); - if (rsq > cut_in_off_sq) { - if (rsq < cut_in_on_sq) { - rsw = (r - cut_in_off)/cut_in_diff; - forcecoul += prefactor*rsw*rsw*(3.0 - 2.0*rsw); - if (factor_coul < 1.0) - forcecoul -= - (1.0-factor_coul)*prefactor*rsw*rsw*(3.0 - 2.0*rsw); - } else { - forcecoul += prefactor; - if (factor_coul < 1.0) - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else { - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq && rsq > cut_in_off_sq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - if (rsq < cut_in_on_sq) { - rsw = (sqrtf(rsq) - cut_in_off)/cut_in_diff; - forcelj *= rsw*rsw*(3.0 - 2.0*rsw); - } - } else forcelj = 0.0; - - fforce = (forcecoul + forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - phicoul = prefactor*erfc; - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - } else { - table = etable[itable] + fraction*detable[itable]; - phicoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ptable[itable] + fraction*dptable[itable]; - prefactor = qtmp*q[j] * table; - phicoul -= (1.0-factor_coul)*prefactor; - } - } - eng_coul += factor*phicoul; - } - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - eng_vdwl += factor*factor_lj*philj; - } - } - - if (vflag) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - table = vtable[itable] + fraction*dvtable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ptable[itable] + fraction*dptable[itable]; - prefactor = qtmp*q[j] * table; - phicoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq <= cut_in_off_sq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else if (rsq <= cut_in_on_sq) { - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::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"); - - epsilon = memory->create_2d_double_array(n+1,n+1,"pair:epsilon"); - sigma = memory->create_2d_double_array(n+1,n+1,"pair:sigma"); - eps14 = memory->create_2d_double_array(n+1,n+1,"pair:eps14"); - sigma14 = memory->create_2d_double_array(n+1,n+1,"pair:sigma14"); - 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"); - lj14_1 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_1"); - lj14_2 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_2"); - lj14_3 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_3"); - lj14_4 = memory->create_2d_double_array(n+1,n+1,"pair:lj14_4"); -} - -/* ---------------------------------------------------------------------- - global settings - unlike other pair styles, - there are no individual pair settings that these override -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::settings(int narg, char **arg) -{ - if (narg != 2 && narg != 3) error->all("Illegal pair_style command"); - - cut_lj_inner = atof(arg[0]); - cut_lj = atof(arg[1]); - if (narg == 2) cut_coul = cut_lj; - else cut_coul = atof(arg[2]); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::coeff(int narg, char **arg) -{ - if (narg != 4 && narg != 6) error->all("Illegal pair_coeff command"); - 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 eps14_one = epsilon_one; - double sigma14_one = sigma_one; - if (narg == 6) { - eps14_one = atof(arg[4]); - sigma14_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; - eps14[i][j] = eps14_one; - sigma14[i][j] = sigma14_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 PairLJCharmmCoulLong::init_one(int i, int j) -{ - // always mix arithmetically - - if (setflag[i][j] == 0) { - epsilon[i][j] = sqrt(epsilon[i][i]*epsilon[j][j]); - sigma[i][j] = 0.5 * (sigma[i][i] + sigma[j][j]); - eps14[i][j] = sqrt(eps14[i][i]*eps14[j][j]); - sigma14[i][j] = 0.5 * (sigma14[i][i] + sigma14[j][j]); - } - - double cut = MAX(cut_lj,cut_coul); - - 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); - lj14_1[i][j] = 48.0 * eps14[i][j] * pow(sigma14[i][j],12.0); - lj14_2[i][j] = 24.0 * eps14[i][j] * pow(sigma14[i][j],6.0); - lj14_3[i][j] = 4.0 * eps14[i][j] * pow(sigma14[i][j],12.0); - lj14_4[i][j] = 4.0 * eps14[i][j] * pow(sigma14[i][j],6.0); - - lj1[j][i] = lj1[i][j]; - lj2[j][i] = lj2[i][j]; - lj3[j][i] = lj3[i][j]; - lj4[j][i] = lj4[i][j]; - lj14_1[j][i] = lj14_1[i][j]; - lj14_2[j][i] = lj14_2[i][j]; - lj14_3[j][i] = lj14_3[i][j]; - lj14_4[j][i] = lj14_4[i][j]; - - return cut; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::init_style() -{ - // require an atom style with charge defined - - if (atom->charge_allow == 0) - error->all("Must use charged atom style with this pair style"); - - // require cut_lj_inner < cut_lj - - if (cut_lj_inner >= cut_lj) - error->all("Pair inner cutoff >= Pair outer cutoff"); - - cut_lj_innersq = cut_lj_inner * cut_lj_inner; - cut_ljsq = cut_lj * cut_lj; - cut_coulsq = cut_coul * cut_coul; - cut_bothsq = MAX(cut_ljsq,cut_coulsq); - - denom_lj = (cut_ljsq-cut_lj_innersq) * (cut_ljsq-cut_lj_innersq) * - (cut_ljsq-cut_lj_innersq); - - // set & error check interior rRESPA cutoffs - - cut_respa = NULL; - if (strcmp(update->integrate_style,"respa") == 0) { - if (((Respa *) update->integrate)->level_inner >= 0) { - cut_respa = ((Respa *) update->integrate)->cutoff; - if (MIN(cut_lj,cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); - if (cut_lj_inner < cut_respa[1]) - error->all("Pair inner cutoff < Respa interior cutoff"); - } - } else cut_respa = NULL; - - // insure use of KSpace long-range solver, set g_ewald - - if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); - else if (strcmp(force->kspace_style,"ewald") == 0) - g_ewald = force->kspace->g_ewald; - else if (strcmp(force->kspace_style,"pppm") == 0) - g_ewald = force->kspace->g_ewald; - else if (strcmp(force->kspace_style,"pppm2") == 0) - g_ewald = force->kspace->g_ewald; - else error->all("Pair style is incompatible with KSpace style"); - - // setup force tables - - if (ncoultablebits) init_tables(); -} - -/* ---------------------------------------------------------------------- - setup force tables used in compute routines -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::init_tables() -{ - int masklo,maskhi; - double r,grij,expm2,derfc,rsw; - double qqrd2e = force->qqrd2e; - - tabinnersq = tabinner*tabinner; - init_bitmap(tabinner,cut_coul,ncoultablebits, - masklo,maskhi,ncoulmask,ncoulshiftbits); - - int ntable = 1; - for (int i = 0; i < ncoultablebits; i++) ntable *= 2; - - // linear lookup tables of length N = 2^ncoultablebits - // stored value = value at lower edge of bin - // d values = delta from lower edge to upper edge of bin - - if (ftable) free_tables(); - - rtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:rtable"); - ftable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ftable"); - ctable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ctable"); - etable = (double *) memory->smalloc(ntable*sizeof(double),"pair:etable"); - drtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:drtable"); - dftable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dftable"); - dctable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dctable"); - detable = (double *) memory->smalloc(ntable*sizeof(double),"pair:detable"); - - if (cut_respa == NULL) { - vtable = ptable = dvtable = dptable = NULL; - } else { - vtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:vtable"); - ptable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ptable"); - dvtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dvtable"); - dptable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dptable"); - } - - float rsq; - int *int_rsq = (int *) &rsq; - float minrsq; - int *int_minrsq = (int *) &minrsq; - int itablemin; - *int_minrsq = 0 << ncoulshiftbits; - *int_minrsq = *int_minrsq | maskhi; - - for (int i = 0; i < ntable; i++) { - *int_rsq = i << ncoulshiftbits; - *int_rsq = *int_rsq | masklo; - if (rsq < tabinnersq) { - *int_rsq = i << ncoulshiftbits; - *int_rsq = *int_rsq | maskhi; - } - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - derfc = erfc(grij); - if (cut_respa == NULL) { - rtable[i] = rsq; - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - ctable[i] = qqrd2e/r; - etable[i] = qqrd2e/r * derfc; - } else { - rtable[i] = rsq; - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2 - 1.0); - ctable[i] = 0.0; - etable[i] = qqrd2e/r * derfc; - ptable[i] = qqrd2e/r; - vtable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - if (rsq > cut_respa[2]*cut_respa[2]) { - if (rsq < cut_respa[3]*cut_respa[3]) { - rsw = (r - cut_respa[2])/(cut_respa[3] - cut_respa[2]); - ftable[i] += qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - ctable[i] = qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - } else { - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - ctable[i] = qqrd2e/r; - } - } - } - minrsq = MIN(minrsq,rsq); - } - - tabinnersq = minrsq; - - int ntablem1 = ntable - 1; - - for (int i = 0; i < ntablem1; i++) { - drtable[i] = 1.0/(rtable[i+1] - rtable[i]); - dftable[i] = ftable[i+1] - ftable[i]; - dctable[i] = ctable[i+1] - ctable[i]; - detable[i] = etable[i+1] - etable[i]; - } - - if (cut_respa) { - for (int i = 0; i < ntablem1; i++) { - dvtable[i] = vtable[i+1] - vtable[i]; - dptable[i] = ptable[i+1] - ptable[i]; - } - } - - // get the delta values for the last table entries - // tables are connected periodically between 0 and ntablem1 - - drtable[ntablem1] = 1.0/(rtable[0] - rtable[ntablem1]); - dftable[ntablem1] = ftable[0] - ftable[ntablem1]; - dctable[ntablem1] = ctable[0] - ctable[ntablem1]; - detable[ntablem1] = etable[0] - etable[ntablem1]; - if (cut_respa) { - dvtable[ntablem1] = vtable[0] - vtable[ntablem1]; - dptable[ntablem1] = ptable[0] - ptable[ntablem1]; - } - - // get the correct delta values at itablemax - // smallest r is in bin itablemin - // largest r is in bin itablemax, which is itablemin-1, - // or ntablem1 if itablemin=0 - // deltas at itablemax only needed if corresponding rsq < cut*cut - // if so, compute deltas between rsq and cut*cut - - double f_tmp,c_tmp,e_tmp,p_tmp,v_tmp; - itablemin = *int_minrsq & ncoulmask; - itablemin >>= ncoulshiftbits; - int itablemax = itablemin - 1; - if (itablemin == 0) itablemax = ntablem1; - *int_rsq = itablemax << ncoulshiftbits; - *int_rsq = *int_rsq | maskhi; - - if (rsq < cut_coulsq) { - rsq = cut_coulsq; - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - derfc = erfc(grij); - - if (cut_respa == NULL) { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - c_tmp = qqrd2e/r; - e_tmp = qqrd2e/r * derfc; - } else { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2 - 1.0); - c_tmp = 0.0; - e_tmp = qqrd2e/r * derfc; - p_tmp = qqrd2e/r; - v_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - if (rsq > cut_respa[2]*cut_respa[2]) { - if (rsq < cut_respa[3]*cut_respa[3]) { - rsw = (r - cut_respa[2])/(cut_respa[3] - cut_respa[2]); - f_tmp += qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - c_tmp = qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - } else { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - c_tmp = qqrd2e/r; - } - } - } - - drtable[itablemax] = 1.0/(rsq - rtable[itablemax]); - dftable[itablemax] = f_tmp - ftable[itablemax]; - dctable[itablemax] = c_tmp - ctable[itablemax]; - detable[itablemax] = e_tmp - etable[itablemax]; - if (cut_respa) { - dvtable[itablemax] = v_tmp - vtable[itablemax]; - dptable[itablemax] = p_tmp - ptable[itablemax]; - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::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(&eps14[i][j],sizeof(double),1,fp); - fwrite(&sigma14[i][j],sizeof(double),1,fp); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::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(&eps14[i][j],sizeof(double),1,fp); - fread(&sigma14[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(&eps14[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&sigma14[i][j],1,MPI_DOUBLE,0,world); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::write_restart_settings(FILE *fp) -{ - fwrite(&cut_lj_inner,sizeof(double),1,fp); - fwrite(&cut_lj,sizeof(double),1,fp); - fwrite(&cut_coul,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 PairLJCharmmCoulLong::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_lj_inner,sizeof(double),1,fp); - fread(&cut_lj,sizeof(double),1,fp); - fread(&cut_coul,sizeof(double),1,fp); - fread(&offset_flag,sizeof(int),1,fp); - fread(&mix_flag,sizeof(int),1,fp); - } - MPI_Bcast(&cut_lj_inner,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_lj,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); -} - -/* ---------------------------------------------------------------------- - free memory for tables used in pair computations -------------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::free_tables() -{ - memory->sfree(rtable); - memory->sfree(drtable); - memory->sfree(ftable); - memory->sfree(dftable); - memory->sfree(ctable); - memory->sfree(dctable); - memory->sfree(etable); - memory->sfree(detable); - memory->sfree(vtable); - memory->sfree(dvtable); - memory->sfree(ptable); - memory->sfree(dptable); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCharmmCoulLong::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - int eflag, One &one) -{ - double r2inv,r6inv,r,grij,expm2,t,erfc,prefactor; - double switch1,switch2,fraction,table,forcecoul,forcelj,phicoul,philj; - int itable; - - r2inv = 1.0/rsq; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - float rsq_single = rsq; - int *int_rsq = (int *) &rsq_single; - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq_single - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = atom->q[i]*atom->q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = atom->q[i]*atom->q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - if (rsq < cut_ljsq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - switch2 = 12.0*rsq * (cut_ljsq-rsq) * - (rsq-cut_lj_innersq) / denom_lj; - philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]); - forcelj = forcelj*switch1 + philj*switch2; - } - } else forcelj = 0.0; - one.fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - if (eflag) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - phicoul = atom->q[i]*atom->q[j] * table; - } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - one.eng_coul = phicoul; - } else one.eng_coul = 0.0; - if (rsq < cut_ljsq) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); - if (rsq > cut_lj_innersq) { - switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * - (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; - philj *= switch1; - } - one.eng_vdwl = factor_lj*philj; - } else one.eng_vdwl = 0.0; - } -} diff --git a/src/pair_lj_cut_coul_long.cpp b/src/pair_lj_cut_coul_long.cpp deleted file mode 100644 index 1b6a364976..0000000000 --- a/src/pair_lj_cut_coul_long.cpp +++ /dev/null @@ -1,1104 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_lj_cut_coul_long.h" -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "kspace.h" -#include "update.h" -#include "integrate.h" -#include "respa.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define A1 0.254829592 -#define A2 -0.284496736 -#define A3 1.421413741 -#define A4 -1.453152027 -#define A5 1.061405429 - -/* ---------------------------------------------------------------------- */ - -PairLJCutCoulLong::PairLJCutCoulLong() -{ - respa_enable = 1; - ftable = NULL; -} - -/* ---------------------------------------------------------------------- - free all arrays -------------------------------------------------------------------------- */ - -PairLJCutCoulLong::~PairLJCutCoulLong() -{ - 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(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); - } - if (ftable) free_tables(); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLong::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype,itable; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; - double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double factor,phicoul,philj; - int *neighs; - double **f; - float rsq; - int *int_rsq = (int *) &rsq; - - 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; - int *type = atom->type; - 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 %= 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; - - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - } else forcelj = 0.0; - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - phicoul = qtmp*q[j] * table; - } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - eng_coul += factor*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 || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } - if (vflag == 2) virial_compute(); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLong::compute_inner() -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double rsw; - int *neighs; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_out_on = cut_respa[0]; - double cut_out_off = cut_respa[1]; - - double cut_out_diff = cut_out_off - cut_out_on; - double cut_out_on_sq = cut_out_on*cut_out_on; - double cut_out_off_sq = cut_out_off*cut_out_off; - - // 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_inner[i]; - numneigh = neighbor->numneigh_inner[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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_out_off_sq) { - r2inv = 1.0/rsq; - forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*forcecoul; - - jtype = type[j]; - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - } else forcelj = 0.0; - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - if (rsq > cut_out_on_sq) { - rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; - fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); - } - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLong::compute_middle() -{ - int i,j,k,numneigh,itype,jtype; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double rsw; - int *neighs; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_in_off = cut_respa[0]; - double cut_in_on = cut_respa[1]; - double cut_out_on = cut_respa[2]; - double cut_out_off = cut_respa[3]; - - double cut_in_diff = cut_in_on - cut_in_off; - double cut_out_diff = cut_out_off - cut_out_on; - double cut_in_off_sq = cut_in_off*cut_in_off; - double cut_in_on_sq = cut_in_on*cut_in_on; - double cut_out_on_sq = cut_out_on*cut_out_on; - double cut_out_off_sq = cut_out_off*cut_out_off; - - // 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_middle[i]; - numneigh = neighbor->numneigh_middle[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 %= nall; - } - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq < cut_out_off_sq && rsq > cut_in_off_sq) { - r2inv = 1.0/rsq; - forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*forcecoul; - - jtype = type[j]; - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - } else forcelj = 0.0; - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - if (rsq < cut_in_on_sq) { - rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; - fforce *= rsw*rsw*(3.0 - 2.0*rsw); - } - if (rsq > cut_out_on_sq) { - rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; - fforce *= 1.0 + rsw*rsw*(2.0*rsw - 3.0); - } - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLong::compute_outer(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype,itable; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; - double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double factor,phicoul,philj; - double rsw; - int *neighs; - float rsq; - int *int_rsq = (int *) &rsq; - - eng_vdwl = eng_coul = 0.0; - if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - - double **f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - 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; - - double cut_in_off = cut_respa[2]; - double cut_in_on = cut_respa[3]; - - double cut_in_diff = cut_in_on - cut_in_off; - double cut_in_off_sq = cut_in_off*cut_in_off; - double cut_in_on_sq = cut_in_on*cut_in_on; - - // 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 %= 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; - - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2 - 1.0); - if (rsq > cut_in_off_sq) { - if (rsq < cut_in_on_sq) { - rsw = (r - cut_in_off)/cut_in_diff; - forcecoul += prefactor*rsw*rsw*(3 - 2*rsw); - if (factor_coul < 1.0) - forcecoul -= (1.0-factor_coul)*prefactor*rsw*rsw*(3 - 2*rsw); - } else { - forcecoul += prefactor; - if (factor_coul < 1.0) - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else { - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq < cut_ljsq[itype][jtype] && rsq > cut_in_off_sq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - if (rsq < cut_in_on_sq) { - rsw = (sqrtf(rsq) - cut_in_off)/cut_in_diff; - forcelj *= rsw*rsw*(3 - 2*rsw); - } - } else forcelj = 0.0; - - fforce = (forcecoul + forcelj) * r2inv; - - f[i][0] += delx*fforce; - f[i][1] += dely*fforce; - f[i][2] += delz*fforce; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fforce; - f[j][1] -= dely*fforce; - f[j][2] -= delz*fforce; - } - - if (eflag) { - if (newton_pair || j < nlocal) factor = 1.0; - else factor = 0.5; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - phicoul = prefactor*erfc; - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - } else { - table = etable[itable] + fraction*detable[itable]; - phicoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ptable[itable] + fraction*dptable[itable]; - prefactor = qtmp*q[j] * table; - phicoul -= (1.0-factor_coul)*prefactor; - } - } - eng_coul += factor*phicoul; - } - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - - offset[itype][jtype]; - eng_vdwl += factor*factor_lj*philj; - } - } - - if (vflag) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - table = vtable[itable] + fraction*dvtable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ptable[itable] + fraction*dptable[itable]; - prefactor = qtmp*q[j] * table; - phicoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - - if (rsq <= cut_in_off_sq) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - } else if (rsq <= cut_in_on_sq) - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - - fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - if (newton_pair || j < nlocal) { - virial[0] += delx*delx*fforce; - virial[1] += dely*dely*fforce; - virial[2] += delz*delz*fforce; - virial[3] += delx*dely*fforce; - virial[4] += delx*delz*fforce; - virial[5] += dely*delz*fforce; - } else { - virial[0] += 0.5*delx*delx*fforce; - virial[1] += 0.5*dely*dely*fforce; - virial[2] += 0.5*delz*delz*fforce; - virial[3] += 0.5*delx*dely*fforce; - virial[4] += 0.5*delx*delz*fforce; - virial[5] += 0.5*dely*delz*fforce; - } - } - } - } - } -} - -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::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"); - 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 PairLJCutCoulLong::settings(int narg, char **arg) -{ - if (narg < 1 || narg > 2) error->all("Illegal pair_style command"); - - cut_lj_global = atof(arg[0]); - if (narg == 1) cut_coul = cut_lj_global; - else cut_coul = 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; - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::coeff(int narg, char **arg) -{ - if (narg < 4 || narg > 5) 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; - if (narg == 5) cut_lj_one = atof(arg[4]); - - 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; - 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 PairLJCutCoulLong::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]); - } - - double cut = MAX(cut_lj[i][j],cut_coul); - cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[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]; - 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]; - - // compute I,J contribution to long-range tail correction - // count total # of atoms of type I and J via Allreduce - - if (tail_flag) { - int *type = atom->type; - int nlocal = atom->nlocal; - - double count[2],all[2]; - count[0] = count[1] = 0.0; - for (int k = 0; k < nlocal; k++) { - if (type[k] == i) count[0] += 1.0; - if (type[k] == j) count[1] += 1.0; - } - MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - - double PI = 4.0*atan(1.0); - double sig2 = sigma[i][j]*sigma[i][j]; - double sig6 = sig2*sig2*sig2; - double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; - double rc6 = rc3*rc3; - double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * - sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * - sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); - } - - return cut; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::init_style() -{ - int i,j; - - // require an atom style with charge defined - - if (atom->charge_allow == 0) - error->all("Must use charged atom style with this pair style"); - - cut_coulsq = cut_coul * cut_coul; - - // set & error check interior rRESPA cutoffs - - if (strcmp(update->integrate_style,"respa") == 0) { - if (((Respa *) update->integrate)->level_inner >= 0) { - cut_respa = ((Respa *) update->integrate)->cutoff; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (MIN(cut_lj[i][j],cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); - } - } else cut_respa = NULL; - - // insure use of KSpace long-range solver, set g_ewald - - if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); - else if (strcmp(force->kspace_style,"ewald") == 0) - g_ewald = force->kspace->g_ewald; - else if (strcmp(force->kspace_style,"pppm") == 0) - g_ewald = force->kspace->g_ewald; - else error->all("Pair style is incompatible with KSpace style"); - - // setup force tables - - if (ncoultablebits) init_tables(); -} - -/* ---------------------------------------------------------------------- - setup force tables used in compute routines -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::init_tables() -{ - int masklo,maskhi; - double r,grij,expm2,derfc,rsw; - double qqrd2e = force->qqrd2e; - - tabinnersq = tabinner*tabinner; - init_bitmap(tabinner,cut_coul,ncoultablebits, - masklo,maskhi,ncoulmask,ncoulshiftbits); - - int ntable = 1; - for (int i = 0; i < ncoultablebits; i++) ntable *= 2; - - // linear lookup tables of length N = 2^ncoultablebits - // stored value = value at lower edge of bin - // d values = delta from lower edge to upper edge of bin - - if (ftable) free_tables(); - - rtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:rtable"); - ftable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ftable"); - ctable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ctable"); - etable = (double *) memory->smalloc(ntable*sizeof(double),"pair:etable"); - drtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:drtable"); - dftable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dftable"); - dctable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dctable"); - detable = (double *) memory->smalloc(ntable*sizeof(double),"pair:detable"); - - if (cut_respa == NULL) { - vtable = ptable = dvtable = dptable = NULL; - } else { - vtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:vtable"); - ptable = (double *) memory->smalloc(ntable*sizeof(double),"pair:ptable"); - dvtable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dvtable"); - dptable = (double *) memory->smalloc(ntable*sizeof(double),"pair:dptable"); - } - - float rsq; - int *int_rsq = (int *) &rsq; - float minrsq; - int *int_minrsq = (int *) &minrsq; - int itablemin; - *int_minrsq = 0 << ncoulshiftbits; - *int_minrsq = *int_minrsq | maskhi; - - for (int i = 0; i < ntable; i++) { - *int_rsq = i << ncoulshiftbits; - *int_rsq = *int_rsq | masklo; - if (rsq < tabinnersq) { - *int_rsq = i << ncoulshiftbits; - *int_rsq = *int_rsq | maskhi; - } - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - derfc = erfc(grij); - if (cut_respa == NULL) { - rtable[i] = rsq; - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - ctable[i] = qqrd2e/r; - etable[i] = qqrd2e/r * derfc; - } else { - rtable[i] = rsq; - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2 - 1.0); - ctable[i] = 0.0; - etable[i] = qqrd2e/r * derfc; - ptable[i] = qqrd2e/r; - vtable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - if (rsq > cut_respa[2]*cut_respa[2]) { - if (rsq < cut_respa[3]*cut_respa[3]) { - rsw = (r - cut_respa[2])/(cut_respa[3] - cut_respa[2]); - ftable[i] += qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - ctable[i] = qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - } else { - ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - ctable[i] = qqrd2e/r; - } - } - } - minrsq = MIN(minrsq,rsq); - } - - tabinnersq = minrsq; - - int ntablem1 = ntable - 1; - - for (int i = 0; i < ntablem1; i++) { - drtable[i] = 1.0/(rtable[i+1] - rtable[i]); - dftable[i] = ftable[i+1] - ftable[i]; - dctable[i] = ctable[i+1] - ctable[i]; - detable[i] = etable[i+1] - etable[i]; - } - - if (cut_respa) { - for (int i = 0; i < ntablem1; i++) { - dvtable[i] = vtable[i+1] - vtable[i]; - dptable[i] = ptable[i+1] - ptable[i]; - } - } - - // get the delta values for the last table entries - // tables are connected periodically between 0 and ntablem1 - - drtable[ntablem1] = 1.0/(rtable[0] - rtable[ntablem1]); - dftable[ntablem1] = ftable[0] - ftable[ntablem1]; - dctable[ntablem1] = ctable[0] - ctable[ntablem1]; - detable[ntablem1] = etable[0] - etable[ntablem1]; - if (cut_respa) { - dvtable[ntablem1] = vtable[0] - vtable[ntablem1]; - dptable[ntablem1] = ptable[0] - ptable[ntablem1]; - } - - // get the correct delta values at itablemax - // smallest r is in bin itablemin - // largest r is in bin itablemax, which is itablemin-1, - // or ntablem1 if itablemin=0 - // deltas at itablemax only needed if corresponding rsq < cut*cut - // if so, compute deltas between rsq and cut*cut - - double f_tmp,c_tmp,e_tmp,p_tmp,v_tmp; - itablemin = *int_minrsq & ncoulmask; - itablemin >>= ncoulshiftbits; - int itablemax = itablemin - 1; - if (itablemin == 0) itablemax = ntablem1; - *int_rsq = itablemax << ncoulshiftbits; - *int_rsq = *int_rsq | maskhi; - - if (rsq < cut_coulsq) { - rsq = cut_coulsq; - r = sqrtf(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - derfc = erfc(grij); - - if (cut_respa == NULL) { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - c_tmp = qqrd2e/r; - e_tmp = qqrd2e/r * derfc; - } else { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2 - 1.0); - c_tmp = 0.0; - e_tmp = qqrd2e/r * derfc; - p_tmp = qqrd2e/r; - v_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - if (rsq > cut_respa[2]*cut_respa[2]) { - if (rsq < cut_respa[3]*cut_respa[3]) { - rsw = (r - cut_respa[2])/(cut_respa[3] - cut_respa[2]); - f_tmp += qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - c_tmp = qqrd2e/r * rsw*rsw*(3.0 - 2.0*rsw); - } else { - f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2); - c_tmp = qqrd2e/r; - } - } - } - - drtable[itablemax] = 1.0/(rsq - rtable[itablemax]); - dftable[itablemax] = f_tmp - ftable[itablemax]; - dctable[itablemax] = c_tmp - ctable[itablemax]; - detable[itablemax] = e_tmp - etable[itablemax]; - if (cut_respa) { - dvtable[itablemax] = v_tmp - vtable[itablemax]; - dptable[itablemax] = p_tmp - ptable[itablemax]; - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::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); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::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); - } - 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); - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::write_restart_settings(FILE *fp) -{ - fwrite(&cut_lj_global,sizeof(double),1,fp); - fwrite(&cut_coul,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 PairLJCutCoulLong::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_lj_global,sizeof(double),1,fp); - fread(&cut_coul,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,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); -} - -/* ---------------------------------------------------------------------- - free memory for tables used in pair computations -------------------------------------------------------------------------- */ - -void PairLJCutCoulLong::free_tables() -{ - memory->sfree(rtable); - memory->sfree(drtable); - memory->sfree(ftable); - memory->sfree(dftable); - memory->sfree(ctable); - memory->sfree(dctable); - memory->sfree(etable); - memory->sfree(detable); - memory->sfree(vtable); - memory->sfree(dvtable); - memory->sfree(ptable); - memory->sfree(dptable); -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLong::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - int eflag, One &one) -{ - double r2inv,r6inv,r,grij,expm2,t,erfc,prefactor; - double fraction,table,forcecoul,forcelj,phicoul,philj; - int itable; - - r2inv = 1.0/rsq; - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrt(rsq); - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor; - } else { - float rsq_single = rsq; - int *int_rsq = (int *) &rsq_single; - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq_single - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = atom->q[i]*atom->q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = atom->q[i]*atom->q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - } else forcecoul = 0.0; - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - } else forcelj = 0.0; - one.fforce = (forcecoul + factor_lj*forcelj) * r2inv; - - if (eflag) { - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - phicoul = atom->q[i]*atom->q[j] * table; - } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - one.eng_coul = 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; - } -} diff --git a/src/pair_lj_cut_coul_long.h b/src/pair_lj_cut_coul_long.h deleted file mode 100644 index bb5827489b..0000000000 --- a/src/pair_lj_cut_coul_long.h +++ /dev/null @@ -1,59 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_LJ_CUT_COUL_LONG_H -#define PAIR_LJ_CUT_COUL_LONG_H - -#include "pair.h" - -class PairLJCutCoulLong : public Pair { - public: - double cut_coul; - - PairLJCutCoulLong(); - ~PairLJCutCoulLong(); - virtual void compute(int, int); - virtual void settings(int, char **); - void coeff(int, char **); - double init_one(int, int); - virtual void init_style(); - void write_restart(FILE *); - void read_restart(FILE *); - virtual void write_restart_settings(FILE *); - virtual void read_restart_settings(FILE *); - virtual void single(int, int, int, int, double, double, double, int, One &); - - void compute_inner(); - void compute_middle(); - void compute_outer(int, int); - - protected: - double cut_lj_global; - double **cut_lj,**cut_ljsq; - double cut_coulsq; - double **epsilon,**sigma; - double **lj1,**lj2,**lj3,**lj4,**offset; - double *cut_respa; - double g_ewald; - - double tabinnersq; - double *rtable,*drtable,*ftable,*dftable,*ctable,*dctable; - double *etable,*detable,*ptable,*dptable,*vtable,*dvtable; - int ncoulshiftbits,ncoulmask; - - void allocate(); - void init_tables(); - void free_tables(); -}; - -#endif diff --git a/src/pair_lj_cut_coul_long_tip4p.cpp b/src/pair_lj_cut_coul_long_tip4p.cpp deleted file mode 100644 index 151573bed7..0000000000 --- a/src/pair_lj_cut_coul_long_tip4p.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Amalie Frischknecht and Ahmed Ismail (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "pair_lj_cut_coul_long_tip4p.h" -#include "angle.h" -#include "atom.h" -#include "bond.h" -#include "comm.h" -#include "domain.h" -#include "force.h" -#include "kspace.h" -#include "update.h" -#include "respa.h" -#include "memory.h" -#include "neighbor.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define EWALD_F 1.12837917 -#define EWALD_P 0.3275911 -#define A1 0.254829592 -#define A2 -0.284496736 -#define A3 1.421413741 -#define A4 -1.453152027 -#define A5 1.061405429 - -/* ---------------------------------------------------------------------- */ - -PairLJCutCoulLongTIP4P::PairLJCutCoulLongTIP4P() -{ - single_enable = 0; -} - -/* ---------------------------------------------------------------------- */ - -void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag) -{ - int i,j,k,numneigh,itype,jtype,itable; - double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; - double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3; - double r,r2inv,r6inv,forcecoul,forcelj,cforce,negforce; - double factor_coul,factor_lj; - double grij,expm2,prefactor,t,erfc; - double phicoul,philj; - int iH1,iH2,jH1,jH2; - double xiM[3],xjM[3]; - double *x1,*x2; - double fO[3],fH[3]; - int *neighs; - double **f; - float rsq; - int *int_rsq = (int *) &rsq; - - eng_vdwl = eng_coul = 0.0; - if (vflag) for (i = 0; i < 6; i++) virial[i] = tvirial[i] = 0.0; - - if (vflag == 2) { - f = update->f_pair; - tf = atom->f; - } - else f = atom->f; - double **x = atom->x; - double *q = atom->q; - int *type = atom->type; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - double *special_coul = force->special_coul; - double *special_lj = force->special_lj; - 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]; - if (itype == typeO) { - find_M(i,iH1,iH2,xiM); - x1 = xiM; - } else x1 = x[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 %= 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; - - if (rsq < cut_ljsq[itype][jtype]) { - r6inv = r2inv*r2inv*r2inv; - forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); - forcelj *= factor_lj * r2inv; - - f[i][0] += delx*forcelj; - f[i][1] += dely*forcelj; - f[i][2] += delz*forcelj; - f[j][0] -= delx*forcelj; - f[j][1] -= dely*forcelj; - f[j][2] -= delz*forcelj; - - if (eflag) { - philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - - offset[itype][jtype]; - eng_vdwl += factor_lj*philj; - } - } - - // adjust rsq for off-site O charge(s) - - if (itype == typeO || jtype == typeO) { - if (jtype == typeO) { - find_M(j,jH1,jH2,xjM); - x2 = xjM; - } else x2 = x[j]; - delx = x1[0] - x2[0]; - dely = x1[1] - x2[1]; - delz = x1[2] - x2[2]; - rsq = delx*delx + dely*dely + delz*delz; - } - - // test current rsq against cutoff and compute Coulombic force - - if (rsq < cut_coulsq) { - if (!ncoultablebits || rsq <= tabinnersq) { - r = sqrtf(rsq); - r2inv = 1 / rsq; - grij = g_ewald * r; - expm2 = exp(-grij*grij); - t = 1.0 / (1.0 + EWALD_P*grij); - erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - prefactor = qqrd2e * qtmp*q[j]/r; - forcecoul = prefactor * (erfc + EWALD_F*grij*expm2); - if (factor_coul < 1.0) { - forcecoul -= (1.0-factor_coul)*prefactor; - } - } else { - r2inv = 1 / rsq; - itable = *int_rsq & ncoulmask; - itable >>= ncoulshiftbits; - fraction = (rsq - rtable[itable]) * drtable[itable]; - table = ftable[itable] + fraction*dftable[itable]; - forcecoul = qtmp*q[j] * table; - if (factor_coul < 1.0) { - table = ctable[itable] + fraction*dctable[itable]; - prefactor = qtmp*q[j] * table; - forcecoul -= (1.0-factor_coul)*prefactor; - } - } - - cforce = forcecoul * r2inv; - - // if i,j are not O atoms, force is applied directly - // if i or j are O atoms, force is on fictitious atoms - // spread force to all 3 atoms in water molecule - // formulas due to Feenstra et al, J Comp Chem, 20, 786 (1999) - - if (itype != typeO) { - if (vflag == 0) { - f[i][0] += delx * cforce; - f[i][1] += dely * cforce; - f[i][2] += delz * cforce; - } else { - tf[i][0] += delx * cforce; - tf[i][1] += dely * cforce; - tf[i][2] += delz * cforce; - - tvirial[0] += 0.5 * delx * delx * cforce; - tvirial[1] += 0.5 * dely * dely * cforce; - tvirial[2] += 0.5 * delz * delz * cforce; - tvirial[3] += 0.5 * dely * delx * cforce; - tvirial[4] += 0.5 * delz * delx * cforce; - tvirial[5] += 0.5 * delz * dely * cforce; - } - - } else { - fO[0] = delx*cforce*(1.0-2.0*alpha); - fO[1] = dely*cforce*(1.0-2.0*alpha); - fO[2] = delz*cforce*(1.0-2.0*alpha); - - fH[0] = alpha * (delx*cforce); - fH[1] = alpha * (dely*cforce); - fH[2] = alpha * (delz*cforce); - - if (vflag == 0) { - f[i][0] += fO[0]; - f[i][1] += fO[1]; - f[i][2] += fO[2]; - - f[iH1][0] += fH[0]; - f[iH1][1] += fH[1]; - f[iH1][2] += fH[2]; - - f[iH2][0] += fH[0]; - f[iH2][1] += fH[1]; - f[iH2][2] += fH[2]; - - } else { - tf[i][0] += fO[0]; - tf[i][1] += fO[1]; - tf[i][2] += fO[2]; - - tf[iH1][0] += fH[0]; - tf[iH1][1] += fH[1]; - tf[iH1][2] += fH[2]; - - tf[iH2][0] += fH[0]; - tf[iH2][1] += fH[1]; - tf[iH2][2] += fH[2]; - - delx1 = x[i][0] - x2[0]; - dely1 = x[i][1] - x2[1]; - delz1 = x[i][2] - x2[2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - delx2 = x[iH1][0] - x2[0]; - dely2 = x[iH1][1] - x2[1]; - delz2 = x[iH1][2] - x2[2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - delx3 = x[iH2][0] - x2[0]; - dely3 = x[iH2][1] - x2[1]; - delz3 = x[iH2][2] - x2[2]; - domain->minimum_image(&delx3,&dely3,&delz3); - - tvirial[0] += 0.5 * (delx1 * fO[0] + (delx2 + delx3) * fH[0]); - tvirial[1] += 0.5 * (dely1 * fO[1] + (dely2 + dely3) * fH[1]); - tvirial[2] += 0.5 * (delz1 * fO[2] + (delz2 + delz3) * fH[2]); - tvirial[3] += 0.5 * (dely1 * fO[0] + (dely2 + dely3) * fH[0]); - tvirial[4] += 0.5 * (delz1 * fO[0] + (delz2 + delz3) * fH[0]); - tvirial[5] += 0.5 * (delz1 * fO[1] + (delz2 + delz3) * fH[1]); - } - } - - if (jtype != typeO) { - if (vflag == 0) { - f[j][0] -= delx * cforce; - f[j][1] -= dely * cforce; - f[j][2] -= delz * cforce; - } else { - tf[j][0] -= delx * cforce; - tf[j][1] -= dely * cforce; - tf[j][2] -= delz * cforce; - - tvirial[0] += 0.5 * (delx * delx * cforce); - tvirial[1] += 0.5 * (dely * dely * cforce); - tvirial[2] += 0.5 * (delz * delz * cforce); - tvirial[3] += 0.5 * (dely * delx * cforce); - tvirial[4] += 0.5 * (delz * delx * cforce); - tvirial[5] += 0.5 * (delz * dely * cforce); - } - - } else { - negforce = -cforce; - - fO[0] = delx*negforce*(1.0-2.0*alpha); - fO[1] = dely*negforce*(1.0-2.0*alpha); - fO[2] = delz*negforce*(1.0-2.0*alpha); - - fH[0] = alpha * (delx*negforce); - fH[1] = alpha * (dely*negforce); - fH[2] = alpha * (delz*negforce); - - if (vflag != 2) { - f[j][0] += fO[0]; - f[j][1] += fO[1]; - f[j][2] += fO[2]; - - f[jH1][0] += fH[0]; - f[jH1][1] += fH[1]; - f[jH1][2] += fH[2]; - - f[jH2][0] += fH[0]; - f[jH2][1] += fH[1]; - f[jH2][2] += fH[2]; - - } else { - tf[j][0] += fO[0]; - tf[j][1] += fO[1]; - tf[j][2] += fO[2]; - - tf[jH1][0] += fH[0]; - tf[jH1][1] += fH[1]; - tf[jH1][2] += fH[2]; - - tf[jH2][0] += fH[0]; - tf[jH2][1] += fH[1]; - tf[jH2][2] += fH[2]; - - delx1 = x[j][0] - x1[0]; - dely1 = x[j][1] - x1[1]; - delz1 = x[j][2] - x1[2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - delx2 = x[jH1][0] - x1[0]; - dely2 = x[jH1][1] - x1[1]; - delz2 = x[jH1][2] - x1[2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - delx3 = x[jH2][0] - x1[0]; - dely3 = x[jH2][1] - x1[1]; - delz3 = x[jH2][2] - x1[2]; - domain->minimum_image(&delx3,&dely3,&delz3); - - tvirial[0] += 0.5 * (delx1 * fO[0] + (delx2 + delx3) * fH[0]); - tvirial[1] += 0.5 * (dely1 * fO[1] + (dely2 + dely3) * fH[1]); - tvirial[2] += 0.5 * (delz1 * fO[2] + (delz2 + delz3) * fH[2]); - tvirial[3] += 0.5 * (dely1 * fO[0] + (dely2 + dely3) * fH[0]); - tvirial[4] += 0.5 * (delz1 * fO[0] + (delz2 + delz3) * fH[0]); - tvirial[5] += 0.5 * (delz1 * fO[1] + (delz2 + delz3) * fH[1]); - } - } - - if (eflag) { - if (!ncoultablebits || rsq <= tabinnersq) - phicoul = prefactor*erfc; - else { - table = etable[itable] + fraction*detable[itable]; - phicoul = qtmp*q[j] * table; - } - if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; - eng_coul += phicoul; - } - } - } - } - } - if (vflag == 2) { - virial_compute(); - for (int i = 0; i < 6; i++) virial[i] += tvirial[i]; - } -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairLJCutCoulLongTIP4P::settings(int narg, char **arg) -{ - if (narg < 6 || narg > 7) error->all("Illegal pair_style command"); - - typeO = atoi(arg[0]); - typeH = atoi(arg[1]); - typeB = atoi(arg[2]); - typeA = atoi(arg[3]); - qdist = atof(arg[4]); - - cut_lj_global = atof(arg[5]); - if (narg == 6) cut_coul = cut_lj_global; - else cut_coul = atof(arg[6]); - - // 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; - } -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLJCutCoulLongTIP4P::init_style() -{ - int i,j; - - if (atom->tag_enable == 0) - error->all("Pair style lj/cut/coul/long/tip4p requires atom IDs"); - if (!force->newton_pair) - error->all("Pair style lj/cut/coul/long/tip4p requires newton pair on"); - if (atom->charge_allow == 0) - error->all("Must use charged atom style with this pair style"); - - cut_coulsq = cut_coul * cut_coul; - - // set & error check interior rRESPA cutoffs - - if (strcmp(update->integrate_style,"respa") == 0) { - if (((Respa *) update->integrate)->level_inner >= 0) { - cut_respa = ((Respa *) update->integrate)->cutoff; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (MIN(cut_lj[i][j],cut_coul) < cut_respa[3]) - error->all("Pair cutoff < Respa interior cutoff"); - } - } else cut_respa = NULL; - - // insure use of correct KSpace long-range solver, set g_ewald - - if (force->kspace == NULL) - error->all("Pair style is incompatible with KSpace style"); - if (strcmp(force->kspace_style,"pppm/tip4p") == 0) - g_ewald = force->kspace->g_ewald; - else error->all("Pair style is incompatible with KSpace style"); - - // setup force tables - - if (ncoultablebits) init_tables(); - - // set alpha parameter - - double theta = force->angle->equilibrium_angle(typeA); - double blen = force->bond->equilibrium_distance(typeB); - alpha = qdist / (2.0 * cos(0.5*theta) * blen); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairLJCutCoulLongTIP4P::write_restart_settings(FILE *fp) -{ - fwrite(&typeO,sizeof(int),1,fp); - fwrite(&typeH,sizeof(int),1,fp); - fwrite(&typeB,sizeof(int),1,fp); - fwrite(&typeA,sizeof(int),1,fp); - fwrite(&qdist,sizeof(double),1,fp); - - fwrite(&cut_lj_global,sizeof(double),1,fp); - fwrite(&cut_coul,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 PairLJCutCoulLongTIP4P::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&typeO,sizeof(int),1,fp); - fread(&typeH,sizeof(int),1,fp); - fread(&typeB,sizeof(int),1,fp); - fread(&typeA,sizeof(int),1,fp); - fread(&qdist,sizeof(double),1,fp); - - fread(&cut_lj_global,sizeof(double),1,fp); - fread(&cut_coul,sizeof(double),1,fp); - fread(&offset_flag,sizeof(int),1,fp); - fread(&mix_flag,sizeof(int),1,fp); - } - - MPI_Bcast(&typeO,1,MPI_INT,0,world); - MPI_Bcast(&typeH,1,MPI_INT,0,world); - MPI_Bcast(&typeB,1,MPI_INT,0,world); - MPI_Bcast(&typeA,1,MPI_INT,0,world); - MPI_Bcast(&qdist,1,MPI_DOUBLE,0,world); - - MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world); - MPI_Bcast(&offset_flag,1,MPI_INT,0,world); - MPI_Bcast(&mix_flag,1,MPI_INT,0,world); - -} - -/* ---------------------------------------------------------------------- - find 2 H atoms bonded to O atom i - compute position xM of fictitious charge site for O atom - also return local indices iH1,iH2 of H atoms -------------------------------------------------------------------------- */ - -void PairLJCutCoulLongTIP4P::find_M(int i, int &iH1, int &iH2, double *xM) -{ - // test that O is correctly bonded to 2 succesive H atoms - - iH1 = atom->map(atom->tag[i] + 1); - iH2 = atom->map(atom->tag[i] + 2); - - if (iH1 == -1 || iH2 == -1) error->one("TIP4P hydrogen is missing"); - if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) - error->one("TIP4P hydrogen has incorrect atom type"); - - double **x = atom->x; - - double delx1 = x[iH1][0] - x[i][0]; - double dely1 = x[iH1][1] - x[i][1]; - double delz1 = x[iH1][2] - x[i][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - double delx2 = x[iH2][0] - x[i][0]; - double dely2 = x[iH2][1] - x[i][1]; - double delz2 = x[iH2][2] - x[i][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - xM[0] = x[i][0] + alpha * (delx1 + delx2); - xM[1] = x[i][1] + alpha * (dely1 + dely2); - xM[2] = x[i][2] + alpha * (delz1 + delz2); -} diff --git a/src/pair_lj_cut_coul_long_tip4p.h b/src/pair_lj_cut_coul_long_tip4p.h deleted file mode 100644 index e7873ebe98..0000000000 --- a/src/pair_lj_cut_coul_long_tip4p.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ---------------------------------------------------------------------- - 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_LJ_CUT_COUL_LONG_TIP4P_H -#define PAIR_LJ_CUT_COUL_LONG_TIP4P_H - -#include "pair_lj_cut_coul_long.h" - -class PairLJCutCoulLongTIP4P : public PairLJCutCoulLong { - friend class PPPM; - - public: - PairLJCutCoulLongTIP4P(); - void compute(int, int); - void settings(int, char **); - void init_style(); - void write_restart_settings(FILE *fp); - void read_restart_settings(FILE *fp); - - private: - int typeH,typeO; // atom types of TIP4P water H and O atoms - int typeA,typeB; // angle and bond types of TIP4P water - double qdist; // distance from O site to negative charge - double alpha; // geometric constraint parameter for TIP4P - double **tf; - double tvirial[6]; - - void find_M(int, int &, int &, double *); -}; - -#endif diff --git a/src/pppm.cpp b/src/pppm.cpp deleted file mode 100644 index ad47238fdf..0000000000 --- a/src/pppm.cpp +++ /dev/null @@ -1,1868 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Roy Pollock (LLNL), Paul Crozier (SNL) -------------------------------------------------------------------------- */ - -#include "mpi.h" -#include "string.h" -#include "stdio.h" -#include "stdlib.h" -#include "math.h" -#include "pppm.h" -#include "atom.h" -#include "comm.h" -#include "neighbor.h" -#include "force.h" -#include "pair_buck_coul_long.h" -#include "pair_lj_cut_coul_long.h" -#include "pair_lj_charmm_coul_long.h" -#include "pair_lj_class2_coul_long.h" -#include "pair_lj_cut_coul_long_tip4p.h" -#include "pair_table.h" -#include "bond.h" -#include "angle.h" -#include "domain.h" -#include "fft3d_wrap.h" -#include "remap_wrap.h" -#include "memory.h" -#include "error.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define MAXORDER 7 -#define OFFSET 4096 -#define SMALL 0.00001 -#define LARGE 10000.0 -#define EPS_HOC 1.0e-7 - -/* ---------------------------------------------------------------------- */ - -PPPM::PPPM(int narg, char **arg) : KSpace(narg, arg) -{ - if (narg != 1) error->all("Illegal kspace_style pppm command"); - - precision = atof(arg[0]); - PI = 4.0*atan(1.0); - - nfactors = 3; - factors = new int[nfactors]; - factors[0] = 2; - factors[1] = 3; - factors[2] = 5; - - MPI_Comm_rank(world,&me); - MPI_Comm_size(world,&nprocs); - - density_brick = vdx_brick = vdy_brick = vdz_brick = NULL; - density_fft = NULL; - greensfn = NULL; - work1 = work2 = NULL; - vg = NULL; - fkx = fky = fkz = NULL; - buf1 = buf2 = NULL; - - gf_b = NULL; - rho1d = rho_coeff = NULL; - - fft1 = fft2 = NULL; - remap = NULL; - - nmax = 0; - part2grid = NULL; -} - -/* ---------------------------------------------------------------------- - free all memory -------------------------------------------------------------------------- */ - -PPPM::~PPPM() -{ - delete [] factors; - deallocate(); - memory->destroy_2d_int_array(part2grid); -} - -/* ---------------------------------------------------------------------- - called once before run -------------------------------------------------------------------------- */ - -void PPPM::init() -{ - if (me == 0) { - if (screen) fprintf(screen,"PPPM initialization ...\n"); - if (logfile) fprintf(logfile,"PPPM initialization ...\n"); - } - - // error check - - if (force->dimension == 2) error->all("Cannot use PPPM with 2d simulation"); - - if (slabflag == 0 && domain->nonperiodic > 0) - error->all("Cannot use nonperiodic boundaries with PPPM"); - if (slabflag == 1) { - if (domain->xperiodic != 1 || domain->yperiodic != 1 || - domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all("Incorrect boundaries with slab PPPM"); - } - - if (order > MAXORDER) { - char str[128]; - sprintf(str,"PPPM order cannot be greater than %d",MAXORDER); - error->all(str); - } - - // free all arrays previously allocated - - deallocate(); - - // insure use of valid pair_style with long-range Coulombics - // set cutoff to short-range Coulombic cutoff - - qqrd2e = force->qqrd2e; - qdist = 0.0; - - Pair *anypair; - if (force->pair == NULL) - error->all("Pair style is incompatible with KSpace style"); - else if (anypair = force->pair_match("buck/coul/long")) - cutoff = ((PairBuckCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/cut/coul/long")) - cutoff = ((PairLJCutCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/charmm/coul/long")) - cutoff = ((PairLJCharmmCoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/class2/coul/long")) - cutoff = ((PairLJClass2CoulLong *) anypair)->cut_coul; - else if (anypair = force->pair_match("lj/cut/coul/long/tip4p")) { - if (strcmp(force->kspace_style,"pppm/tip4p") != 0) - error->all("Pair style is incompatible with KSpace style"); - cutoff = ((PairLJCutCoulLongTIP4P *) anypair)->cut_coul; - qdist = ((PairLJCutCoulLongTIP4P *) anypair)->qdist; - typeO = ((PairLJCutCoulLongTIP4P *) anypair)->typeO; - typeH = ((PairLJCutCoulLongTIP4P *) anypair)->typeH; - int typeA = ((PairLJCutCoulLongTIP4P *) anypair)->typeA; - int typeB = ((PairLJCutCoulLongTIP4P *) anypair)->typeB; - if (force->angle == NULL || force->bond == NULL) - error->all("Bond and angle potentials must be defined for TIP4P"); - double theta = force->angle->equilibrium_angle(typeA); - double blen = force->bond->equilibrium_distance(typeB); - alpha = qdist / (2.0 * cos(0.5*theta) * blen); - } - else if (anypair = force->pair_match("table")) - cutoff = ((PairTable *) anypair)->cut_coul(); - else error->all("Pair style is incompatible with KSpace style"); - - // compute qsum & qsqsum and warn if not charge-neutral - - qsum = qsqsum = 0.0; - for (int i = 0; i < atom->nlocal; i++) { - qsum += atom->q[i]; - qsqsum += atom->q[i]*atom->q[i]; - } - - double tmp; - MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world); - qsum = tmp; - MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world); - qsqsum = tmp; - - if (fabs(qsum) > SMALL && me == 0) { - char str[128]; - sprintf(str,"System is not charge neutral, net charge = %g",qsum); - error->warning(str); - } - - // setup FFT grid resolution and g_ewald - - set_grid(); - - if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) - error->all("PPPM grid is too large"); - - // global indices of PPPM grid range from 0 to N-1 - // nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of - // global PPPM grid that I own without ghost cells - // for slab PPPM, assign z grid as if it were not extended - - nxlo_in = comm->myloc[0]*nx_pppm / comm->procgrid[0]; - nxhi_in = (comm->myloc[0]+1)*nx_pppm / comm->procgrid[0] - 1; - nylo_in = comm->myloc[1]*ny_pppm / comm->procgrid[1]; - nyhi_in = (comm->myloc[1]+1)*ny_pppm / comm->procgrid[1] - 1; - nzlo_in = comm->myloc[2] * - (static_cast (nz_pppm/slab_volfactor)) / comm->procgrid[2]; - nzhi_in = (comm->myloc[2]+1) * - (static_cast (nz_pppm/slab_volfactor)) / comm->procgrid[2] - 1; - - // nlower,nupper = stencil size for mapping particles to PPPM grid - - nlower = -(order-1)/2; - nupper = order/2; - - // shift values for particle <-> grid mapping - // add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1 - - if (order % 2) shift = OFFSET + 0.5; - else shift = OFFSET; - if (order % 2) shiftone = 0.0; - else shiftone = 0.5; - - // nlo_out,nhi_out = lower/upper limits of the 3d sub-brick of - // global PPPM grid that my particles can contribute charge to - // effectively nlo_in,nhi_in + ghost cells - // nlo,nhi = global coords of grid pt to "lower left" of smallest/largest - // position a particle in my box can be at - // particle position bound = subbox + skin/2.0 + qdist - // qdist = offset due to TIP4P fictitious charge - // nlo_out,nhi_out = nlo,nhi + stencil size for particle mapping - // for slab PPPM, assign z grid as if it were not extended - - int nlo,nhi; - double cuthalf = 0.5 * neighbor->skin + qdist; - - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - double zprd_slab = zprd*slab_volfactor; - - nlo = static_cast ((domain->subxlo-cuthalf-domain->boxxlo) * - nx_pppm/xprd + shift) - OFFSET; - nhi = static_cast ((domain->subxhi+cuthalf-domain->boxxlo) * - nx_pppm/xprd + shift) - OFFSET; - nxlo_out = nlo + nlower; - nxhi_out = nhi + nupper; - - nlo = static_cast ((domain->subylo-cuthalf-domain->boxylo) * - ny_pppm/yprd + shift) - OFFSET; - nhi = static_cast ((domain->subyhi+cuthalf-domain->boxylo) * - ny_pppm/yprd + shift) - OFFSET; - nylo_out = nlo + nlower; - nyhi_out = nhi + nupper; - - nlo = static_cast ((domain->subzlo-cuthalf-domain->boxzlo) * - nz_pppm/zprd_slab + shift) - OFFSET; - nhi = static_cast ((domain->subzhi+cuthalf-domain->boxzlo) * - nz_pppm/zprd_slab + shift) - OFFSET; - nzlo_out = nlo + nlower; - nzhi_out = nhi + nupper; - - // for slab PPPM, change the grid boundary for processors at +z end - // to include the empty volume between periodically repeating slabs - // for slab PPPM, want charge data communicated from -z proc to +z proc, - // but not vice versa, also want field data communicated from +z proc to - // -z proc, but not vice versa - // this is accomplished by nzhi_in = nzhi_out on +z end (no ghost cells) - - if (slabflag && ((comm->myloc[2]+1) == (comm->procgrid[2]))) { - nzhi_in = nz_pppm - 1; - nzhi_out = nz_pppm - 1; - } - - // nlo_ghost,nhi_ghost = # of planes I will recv from 6 directions - // that overlay domain I own - // proc in that direction tells me via sendrecv() - // if no neighbor proc, value comes from self since I have ghosts regardless - - int nplanes; - MPI_Status status; - - nplanes = nxlo_in - nxlo_out; - if (comm->procneigh[0][0] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][0],0, - &nxhi_ghost,1,MPI_INT,comm->procneigh[0][1],0,world,&status); - else nxhi_ghost = nplanes; - - nplanes = nxhi_out - nxhi_in; - if (comm->procneigh[0][1] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][1],0, - &nxlo_ghost,1,MPI_INT,comm->procneigh[0][0],0,world,&status); - else nxlo_ghost = nplanes; - - nplanes = nylo_in - nylo_out; - if (comm->procneigh[1][0] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][0],0, - &nyhi_ghost,1,MPI_INT,comm->procneigh[1][1],0,world,&status); - else nyhi_ghost = nplanes; - - nplanes = nyhi_out - nyhi_in; - if (comm->procneigh[1][1] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][1],0, - &nylo_ghost,1,MPI_INT,comm->procneigh[1][0],0,world,&status); - else nylo_ghost = nplanes; - - nplanes = nzlo_in - nzlo_out; - if (comm->procneigh[2][0] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][0],0, - &nzhi_ghost,1,MPI_INT,comm->procneigh[2][1],0,world,&status); - else nzhi_ghost = nplanes; - - nplanes = nzhi_out - nzhi_in; - if (comm->procneigh[2][1] != me) - MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][1],0, - &nzlo_ghost,1,MPI_INT,comm->procneigh[2][0],0,world,&status); - else nzlo_ghost = nplanes; - - // test that ghost overlap is not bigger than my sub-domain - - int flag = 0; - if (nxlo_ghost > nxhi_in-nxlo_in+1) flag = 1; - if (nxhi_ghost > nxhi_in-nxlo_in+1) flag = 1; - if (nylo_ghost > nyhi_in-nylo_in+1) flag = 1; - if (nyhi_ghost > nyhi_in-nylo_in+1) flag = 1; - if (nzlo_ghost > nzhi_in-nzlo_in+1) flag = 1; - if (nzhi_ghost > nzhi_in-nzlo_in+1) flag = 1; - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - - if (flag_all) - error->all("PPPM stencil extends too far, reduce PPPM order"); - - // decomposition of FFT mesh - // global indices range from 0 to N-1 - // proc owns entire x-dimension, clump of columns in y,z dimensions - // npey_fft,npez_fft = # of procs in y,z dims - // if nprocs is small enough, proc can own 1 or more entire xy planes, - // else proc owns 2d sub-blocks of yz plane - // me_y,me_z = which proc (0-npe_fft-1) I am in y,z dimensions - // nlo_fft,nhi_fft = lower/upper limit of the section - // of the global FFT mesh that I own - - int npey_fft,npez_fft; - if (nz_pppm >= nprocs) { - npey_fft = 1; - npez_fft = nprocs; - } else procs2grid2d(nprocs,ny_pppm,nz_pppm,&npey_fft,&npez_fft); - - int me_y = me % npey_fft; - int me_z = me / npey_fft; - - nxlo_fft = 0; - nxhi_fft = nx_pppm - 1; - nylo_fft = me_y*ny_pppm/npey_fft; - nyhi_fft = (me_y+1)*ny_pppm/npey_fft - 1; - nzlo_fft = me_z*nz_pppm/npez_fft; - nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1; - - // PPPM grid for this proc, including ghosts - - ngrid = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * - (nzhi_out-nzlo_out+1); - - // FFT arrays on this proc, without ghosts - // nfft = FFT points in FFT decomposition on this proc - // nfft_brick = FFT points in 3d brick-decomposition on this proc - // nfft_both = greater of 2 values - - nfft = (nxhi_fft-nxlo_fft+1) * (nyhi_fft-nylo_fft+1) * - (nzhi_fft-nzlo_fft+1); - int nfft_brick = (nxhi_in-nxlo_in+1) * (nyhi_in-nylo_in+1) * - (nzhi_in-nzlo_in+1); - nfft_both = MAX(nfft,nfft_brick); - - // buffer space for use in brick2fft and fillbrick - // idel = max # of ghost planes to send or recv in +/- dir of each dim - // nx,ny,nz = owned planes (including ghosts) in each dim - // nxx,nyy,nzz = max # of grid cells to send in each dim - // nbuf = max in any dim, augment by 3x for components of vd_xyz in fillbrick - - int idelx,idely,idelz,nx,ny,nz,nxx,nyy,nzz; - - idelx = MAX(nxlo_ghost,nxhi_ghost); - idelx = MAX(idelx,nxhi_out-nxhi_in); - idelx = MAX(idelx,nxlo_in-nxlo_out); - - idely = MAX(nylo_ghost,nyhi_ghost); - idely = MAX(idely,nyhi_out-nyhi_in); - idely = MAX(idely,nylo_in-nylo_out); - - idelz = MAX(nzlo_ghost,nzhi_ghost); - idelz = MAX(idelz,nzhi_out-nzhi_in); - idelz = MAX(idelz,nzlo_in-nzlo_out); - - nx = nxhi_out - nxlo_out + 1; - ny = nyhi_out - nylo_out + 1; - nz = nzhi_out - nzlo_out + 1; - - nxx = idelx * ny * nz; - nyy = idely * nx * nz; - nzz = idelz * nx * ny; - - nbuf = MAX(nxx,nyy); - nbuf = MAX(nbuf,nzz); - nbuf *= 3; - - // print stats - - int ngrid_max,nfft_both_max,nbuf_max; - MPI_Allreduce(&ngrid,&ngrid_max,1,MPI_INT,MPI_MAX,world); - MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world); - MPI_Allreduce(&nbuf,&nbuf_max,1,MPI_INT,MPI_MAX,world); - - if (me == 0) { - if (screen) fprintf(screen," brick FFT buffer size/proc = %d %d %d\n", - ngrid_max,nfft_both_max,nbuf_max); - if (logfile) fprintf(logfile," brick FFT buffer size/proc = %d %d %d\n", - ngrid_max,nfft_both_max,nbuf_max); - } - - // allocate K-space dependent memory - - allocate(); - - // pre-compute Green's function denomiator expansion - // pre-compute 1d charge distribution coefficients - - compute_gf_denom(); - compute_rho_coeff(); -} - -/* ---------------------------------------------------------------------- - adjust PPPM coeffs, called initially and whenever volume has changed -------------------------------------------------------------------------- */ - -void PPPM::setup() -{ - int i,j,k,l,m,n; - - // volume-dependent factors - - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - - // adjustment of z dimension for 2d slab PPPM - // 3d PPPM just uses zprd since slab_volfactor = 1.0 - - double zprd_slab = zprd*slab_volfactor; - - volume = xprd * yprd * zprd_slab; - - delxinv = nx_pppm/xprd; - delyinv = ny_pppm/yprd; - delzinv = nz_pppm/zprd_slab; - - delvolinv = delxinv*delyinv*delzinv; - - double unitkx = (2.0*PI/xprd); - double unitky = (2.0*PI/yprd); - double unitkz = (2.0*PI/zprd_slab); - - // fkx,fky,fkz for my FFT grid pts - - double per; - - for (i = nxlo_fft; i <= nxhi_fft; i++) { - per = i - nx_pppm*(2*i/nx_pppm); - fkx[i] = unitkx*per; - } - - for (i = nylo_fft; i <= nyhi_fft; i++) { - per = i - ny_pppm*(2*i/ny_pppm); - fky[i] = unitky*per; - } - - for (i = nzlo_fft; i <= nzhi_fft; i++) { - per = i - nz_pppm*(2*i/nz_pppm); - fkz[i] = unitkz*per; - } - - // virial coefficients - - double sqk,vterm; - - n = 0; - for (k = nzlo_fft; k <= nzhi_fft; k++) { - for (j = nylo_fft; j <= nyhi_fft; j++) { - for (i = nxlo_fft; i <= nxhi_fft; i++) { - sqk = fkx[i]*fkx[i] + fky[j]*fky[j] + fkz[k]*fkz[k]; - if (sqk == 0.0) { - vg[n][0] = 0.0; - vg[n][1] = 0.0; - vg[n][2] = 0.0; - vg[n][3] = 0.0; - vg[n][4] = 0.0; - vg[n][5] = 0.0; - } else { - vterm = -2.0 * (1.0/sqk + 0.25/(g_ewald*g_ewald)); - vg[n][0] = 1.0 + vterm*fkx[i]*fkx[i]; - vg[n][1] = 1.0 + vterm*fky[j]*fky[j]; - vg[n][2] = 1.0 + vterm*fkz[k]*fkz[k]; - vg[n][3] = vterm*fkx[i]*fky[j]; - vg[n][4] = vterm*fkx[i]*fkz[k]; - vg[n][5] = vterm*fky[j]*fkz[k]; - } - n++; - } - } - } - - // modified (Hockney-Eastwood) Coulomb Green's function - - int nx,ny,nz,kper,lper,mper; - double snx,sny,snz,snx2,sny2,snz2; - double argx,argy,argz,wx,wy,wz,sx,sy,sz,qx,qy,qz; - double sum1,dot1,dot2; - double numerator,denominator; - - int nbx = static_cast ((g_ewald*xprd/(PI*nx_pppm)) * - pow(-log(EPS_HOC),0.25)); - int nby = static_cast ((g_ewald*yprd/(PI*ny_pppm)) * - pow(-log(EPS_HOC),0.25)); - int nbz = static_cast ((g_ewald*zprd_slab/(PI*nz_pppm)) * - pow(-log(EPS_HOC),0.25)); - - double form = 1.0; - - n = 0; - for (m = nzlo_fft; m <= nzhi_fft; m++) { - mper = m - nz_pppm*(2*m/nz_pppm); - snz = sin(0.5*unitkz*mper*zprd_slab/nz_pppm); - snz2 = snz*snz; - - for (l = nylo_fft; l <= nyhi_fft; l++) { - lper = l - ny_pppm*(2*l/ny_pppm); - sny = sin(0.5*unitky*lper*yprd/ny_pppm); - sny2 = sny*sny; - - for (k = nxlo_fft; k <= nxhi_fft; k++) { - kper = k - nx_pppm*(2*k/nx_pppm); - snx = sin(0.5*unitkx*kper*xprd/nx_pppm); - snx2 = snx*snx; - - sqk = pow(unitkx*kper,2.0) + pow(unitky*lper,2.0) + - pow(unitkz*mper,2.0); - - if (sqk != 0.0) { - numerator = form*12.5663706/sqk; - denominator = gf_denom(snx2,sny2,snz2); - sum1 = 0.0; - for (nx = -nbx; nx <= nbx; nx++) { - qx = unitkx*(kper+nx_pppm*nx); - sx = exp(-.25*pow(qx/g_ewald,2.0)); - wx = 1.0; - argx = 0.5*qx*xprd/nx_pppm; - if (argx != 0.0) wx = pow(sin(argx)/argx,order); - for (ny = -nby; ny <= nby; ny++) { - qy = unitky*(lper+ny_pppm*ny); - sy = exp(-.25*pow(qy/g_ewald,2.0)); - wy = 1.0; - argy = 0.5*qy*yprd/ny_pppm; - if (argy != 0.0) wy = pow(sin(argy)/argy,order); - for (nz = -nbz; nz <= nbz; nz++) { - qz = unitkz*(mper+nz_pppm*nz); - sz = exp(-.25*pow(qz/g_ewald,2.0)); - wz = 1.0; - argz = 0.5*qz*zprd_slab/nz_pppm; - if (argz != 0.0) wz = pow(sin(argz)/argz,order); - - dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz; - dot2 = qx*qx+qy*qy+qz*qz; - sum1 += (dot1/dot2) * sx*sy*sz * pow(wx*wy*wz,2.0); - } - } - } - greensfn[n++] = numerator*sum1/denominator; - } else greensfn[n++] = 0.0; - } - } - } -} - -/* ---------------------------------------------------------------------- - compute the PPPM long-range force, energy, virial -------------------------------------------------------------------------- */ - -void PPPM::compute(int eflag, int vflag) -{ - int i; - - // extend size of nlocal-dependent arrays if necessary - - if (atom->nlocal > nmax) { - memory->destroy_2d_int_array(part2grid); - nmax = atom->nmax; - part2grid = memory->create_2d_int_array(nmax,3,"pppm:part2grid"); - } - - energy = 0.0; - if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - - // find grid points for all my particles - // map my particle charge onto my local 3d density grid - - particle_map(); - make_rho(); - - // all procs communicate density values from their ghost cells - // to fully sum contribution in their 3d bricks - // remap from 3d decomposition to FFT decomposition - - brick2fft(); - - // compute potential gradient on my FFT grid and - // portion of e_long on this proc's FFT grid - // return gradients (electric fields) in 3d brick decomposition - - poisson(eflag,vflag); - - // all procs communicate E-field values to fill ghost cells - // surrounding their 3d bricks - - fillbrick(); - - // calculate the force on my particles - - fieldforce(); - - // sum energy across procs and add in volume-dependent term - - if (eflag) { - double energy_all; - MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); - energy = energy_all; - - energy *= 0.5*volume; - energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); - energy *= qqrd2e; - } - - // sum virial across procs - - if (vflag) { - double virial_all[6]; - MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); - for (i = 0; i < 6; i++) virial[i] = 0.5*qqrd2e*volume*virial_all[i]; - } - - // 2d slab correction - - if (slabflag) slabcorr(eflag); -} - -/* ---------------------------------------------------------------------- - allocate memory that depends on # of K-vectors and order -------------------------------------------------------------------------- */ - -void PPPM::allocate() -{ - density_brick = - memory->create_3d_double_array(nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm:density_brick"); - vdx_brick = - memory->create_3d_double_array(nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm:vdx_brick"); - vdy_brick = - memory->create_3d_double_array(nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm:vdy_brick"); - vdz_brick = - memory->create_3d_double_array(nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm:vdz_brick"); - - density_fft = new double[nfft_both]; - greensfn = new double[nfft_both]; - work1 = new double[2*nfft_both]; - work2 = new double[2*nfft_both]; - vg = memory->create_2d_double_array(nfft_both,6,"pppm:vg"); - - fkx = memory->create_1d_double_array(nxlo_fft,nxhi_fft,"pppm:fkx"); - fky = memory->create_1d_double_array(nylo_fft,nyhi_fft,"pppm:fky"); - fkz = memory->create_1d_double_array(nzlo_fft,nzhi_fft,"pppm:fkz"); - - buf1 = new double[nbuf]; - buf2 = new double[nbuf]; - - // summation coeffs - - gf_b = new double[order]; - rho1d = memory->create_2d_double_array(3,-order/2,order/2,"pppm:rho1d"); - rho_coeff = memory->create_2d_double_array(order,(1-order)/2,order/2, - "pppm:rho_coeff"); - - // create 2 FFTs and a Remap - // 1st FFT keeps data in FFT decompostion - // 2nd FFT returns data in 3d brick decomposition - // remap takes data from 3d brick to FFT decomposition - - int tmp; - - fft1 = new FFT3d(world,nx_pppm,ny_pppm,nz_pppm, - nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, - nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, - 0,0,&tmp); - - fft2 = new FFT3d(world,nx_pppm,ny_pppm,nz_pppm, - nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, - nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, - 0,0,&tmp); - - remap = new Remap(world, - nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, - nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, - 1,0,0,2); -} - -/* ---------------------------------------------------------------------- - deallocate memory that depends on # of K-vectors and order -------------------------------------------------------------------------- */ - -void PPPM::deallocate() -{ - memory->destroy_3d_double_array(density_brick,nzlo_out,nylo_out,nxlo_out); - memory->destroy_3d_double_array(vdx_brick,nzlo_out,nylo_out,nxlo_out); - memory->destroy_3d_double_array(vdy_brick,nzlo_out,nylo_out,nxlo_out); - memory->destroy_3d_double_array(vdz_brick,nzlo_out,nylo_out,nxlo_out); - - delete [] density_fft; - delete [] greensfn; - delete [] work1; - delete [] work2; - memory->destroy_2d_double_array(vg); - - memory->destroy_1d_double_array(fkx,nxlo_fft); - memory->destroy_1d_double_array(fky,nylo_fft); - memory->destroy_1d_double_array(fkz,nzlo_fft); - - delete [] buf1; - delete [] buf2; - - delete [] gf_b; - memory->destroy_2d_double_array(rho1d,-order/2); - memory->destroy_2d_double_array(rho_coeff,(1-order)/2); - - delete fft1; - delete fft2; - delete remap; -} - -/* ---------------------------------------------------------------------- - set size of FFT grid (nx,ny,nz_pppm) and g_ewald -------------------------------------------------------------------------- */ - -void PPPM::set_grid() -{ - // see JCP 109, pg. 7698 for derivation of coefficients - // higher order coefficients may be computed if needed - - double **acons = memory->create_2d_double_array(8,7,"pppm:acons"); - - acons[1][0] = 2.0 / 3.0; - acons[2][0] = 1.0 / 50.0; - acons[2][1] = 5.0 / 294.0; - acons[3][0] = 1.0 / 588.0; - acons[3][1] = 7.0 / 1440.0; - acons[3][2] = 21.0 / 3872.0; - acons[4][0] = 1.0 / 4320.0; - acons[4][1] = 3.0 / 1936.0; - acons[4][2] = 7601.0 / 2271360.0; - acons[4][3] = 143.0 / 28800.0; - acons[5][0] = 1.0 / 23232.0; - acons[5][1] = 7601.0 / 13628160.0; - acons[5][2] = 143.0 / 69120.0; - acons[5][3] = 517231.0 / 106536960.0; - acons[5][4] = 106640677.0 / 11737571328.0; - acons[6][0] = 691.0 / 68140800.0; - acons[6][1] = 13.0 / 57600.0; - acons[6][2] = 47021.0 / 35512320.0; - acons[6][3] = 9694607.0 / 2095994880.0; - acons[6][4] = 733191589.0 / 59609088000.0; - acons[6][5] = 326190917.0 / 11700633600.0; - acons[7][0] = 1.0 / 345600.0; - acons[7][1] = 3617.0 / 35512320.0; - acons[7][2] = 745739.0 / 838397952.0; - acons[7][3] = 56399353.0 / 12773376000.0; - acons[7][4] = 25091609.0 / 1560084480.0; - acons[7][5] = 1755948832039.0 / 36229939200000.0; - acons[7][6] = 4887769399.0 / 37838389248.0; - - double q2 = qsqsum / force->dielectric; - double natoms = atom->natoms; - - // adjustment of z dimension for 2d slab PPPM - // 3d PPPM just uses zprd since slab_volfactor = 1.0 - - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - double zprd_slab = zprd*slab_volfactor; - - // make initial g_ewald estimate - // based on desired error and real space cutoff - // fluid-occupied volume used to estimate real-space error - // zprd used rather than zprd_slab - - if (!gewaldflag) - g_ewald = sqrt(-log(precision*sqrt(natoms*cutoff*xprd*yprd*zprd) / - (2.0*q2))) / cutoff; - - // set optimal nx_pppm,ny_pppm,nz_pppm based on order and precision - // nz_pppm uses extended zprd_slab instead of zprd - - double h,h1,h2,err,er1,er2,lpr; - int ncount; - - if (!gridflag) { - h = 1.0; - h1 = 2.0; - - ncount = 0; - err = LARGE; - er1 = 0.0; - while (fabs(err) > SMALL) { - lpr = rms(h,xprd,natoms,q2,acons); - err = log(lpr) - log(precision); - er2 = er1; - er1 = err; - h2 = h1; - h1 = h; - if ((er1 - er2) == 0.0) h = h1 + er1; - else h = h1 + er1*(h2 - h1)/(er1 - er2); - ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPM X grid spacing"); - } - nx_pppm = static_cast (xprd/h + 1); - - ncount = 0; - err = LARGE; - er1 = 0.0; - while (fabs(err) > SMALL) { - lpr = rms(h,yprd,natoms,q2,acons); - err = log(lpr) - log(precision); - er2 = er1; - er1 = err; - h2 = h1; - h1 = h; - if ((er1 - er2) == 0.0) h = h1 + er1; - else h = h1 + er1*(h2 - h1)/(er1 - er2); - ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPM Y grid spacing"); - } - ny_pppm = static_cast (yprd/h + 1); - - ncount = 0; - err = LARGE; - er1 = 0.0; - while (fabs(err) > SMALL) { - lpr = rms(h,zprd_slab,natoms,q2,acons); - err = log(lpr) - log(precision); - er2 = er1; - er1 = err; - h2 = h1; - h1 = h; - if ((er1 - er2) == 0.0) h = h1 + er1; - else h = h1 + er1*(h2 - h1)/(er1 - er2); - ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPM Z grid spacing"); - } - nz_pppm = static_cast (zprd_slab/h + 1); - - } - - // convert grid into sizes that are factorable - - while (!factorable(nx_pppm)) nx_pppm++; - while (!factorable(ny_pppm)) ny_pppm++; - while (!factorable(nz_pppm)) nz_pppm++; - - // adjust g_ewald for new grid - - double dx = xprd/nx_pppm; - double dy = yprd/ny_pppm; - double dz = zprd_slab/nz_pppm; - - if (!gewaldflag) { - double gew1,gew2,lprx,lpry,lprz,spr; - - gew1 = g_ewald + 0.01; - ncount = 0; - err = LARGE; - er1 = 0.0; - - while (fabs(err) > SMALL) { - lprx = rms(dx,xprd,natoms,q2,acons); - lpry = rms(dy,yprd,natoms,q2,acons); - lprz = rms(dz,zprd_slab,natoms,q2,acons); - lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0); - spr = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) / - sqrt(natoms*cutoff*xprd*yprd*zprd_slab); - - err = log(lpr) - log(spr); - er2 = er1; - er1 = err; - gew2 = gew1; - gew1 = g_ewald; - if ((er1 - er2) == 0.0) g_ewald = gew1 + er1; - else g_ewald = gew1 + er1*(gew2 - gew1)/(er1 - er2); - ncount++; - if (ncount > LARGE) error->all("Cannot compute PPPM G"); - } - } - - // compute final RMS precision - - double lprx = rms(dx,xprd,natoms,q2,acons); - double lpry = rms(dy,yprd,natoms,q2,acons); - double lprz = rms(dz,zprd_slab,natoms,q2,acons); - lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0); - double spr = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) / - sqrt(natoms*cutoff*xprd*yprd*zprd_slab); - - // free local memory - - memory->destroy_2d_double_array(acons); - - // print info - - if (me == 0) { - if (screen) { - fprintf(screen," G vector = %g\n",g_ewald); - fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); - fprintf(screen," RMS precision = %g\n",MAX(lpr,spr)); - } - if (logfile) { - fprintf(logfile," G vector = %g\n",g_ewald); - fprintf(logfile," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); - fprintf(logfile," RMS precision = %g\n",MAX(lpr,spr)); - } - } -} - -/* ---------------------------------------------------------------------- - check if all factors of n are in list of factors - return 1 if yes, 0 if no -------------------------------------------------------------------------- */ - -int PPPM::factorable(int n) -{ - int i; - - while (n > 1) { - for (i = 0; i < nfactors; i++) { - if (n % factors[i] == 0) { - n /= factors[i]; - break; - } - } - if (i == nfactors) return 0; - } - - return 1; -} - -/* ---------------------------------------------------------------------- - compute RMS precision for a dimension -------------------------------------------------------------------------- */ - -double PPPM::rms(double h, double prd, double natoms, - double q2, double **acons) -{ - double sum = 0.0; - for (int m = 0; m < order; m++) - sum += acons[order][m] * pow(h*g_ewald,2.0*m); - double value = q2 * pow(h*g_ewald,order) * - sqrt(g_ewald*prd*sqrt(2.0*PI)*sum/natoms) / (prd*prd); - return value; -} - -/* ---------------------------------------------------------------------- - denominator for Hockney-Eastwood Green's function - of x,y,z = sin(kx*deltax/2), etc - - inf n-1 - S(n,k) = Sum W(k+pi*j)**2 = Sum b(l)*(z*z)**l - j=-inf l=0 - - = -(z*z)**n /(2n-1)! * (d/dx)**(2n-1) cot(x) at z = sin(x) - gf_b = denominator expansion coeffs -------------------------------------------------------------------------- */ - -double PPPM::gf_denom(double x, double y, double z) -{ - double sx,sy,sz; - sz = sy = sx = 0.0; - for (int l = order-1; l >= 0; l--) { - sx = gf_b[l] + sx*x; - sy = gf_b[l] + sy*y; - sz = gf_b[l] + sz*z; - } - double s = sx*sy*sz; - return s*s; -} - -/* ---------------------------------------------------------------------- - pre-compute Green's function denominator expansion coeffs, Gamma(2n) -------------------------------------------------------------------------- */ - -void PPPM::compute_gf_denom() -{ - int k,l,m; - - for (l = 1; l < order; l++) gf_b[l] = 0.0; - gf_b[0] = 1.0; - - for (m = 1; m < order; m++) { - for (l = m; l > 0; l--) - gf_b[l] = 4.0 * (gf_b[l]*(l-m)*(l-m-0.5)-gf_b[l-1]*(l-m-1)*(l-m-1)); - gf_b[0] = 4.0 * (gf_b[0]*(l-m)*(l-m-0.5)); - } - - int ifact = 1; - for (k = 1; k < 2*order; k++) ifact *= k; - double gaminv = 1.0/ifact; - for (l = 0; l < order; l++) gf_b[l] *= gaminv; -} - -/* ---------------------------------------------------------------------- - ghost-swap to accumulate full density in brick decomposition - remap density from 3d brick decomposition to FFT decomposition -------------------------------------------------------------------------- */ - -void PPPM::brick2fft() -{ - int i,n,ix,iy,iz; - MPI_Request request; - MPI_Status status; - - // pack my ghosts for +x processor - // pass data to self or +x processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxhi_in+1; ix <= nxhi_out; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[0][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[0][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[0][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // pack my ghosts for -x processor - // pass data to self or -x processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxlo_out; ix < nxlo_in; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[0][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[0][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[0][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // pack my ghosts for +y processor - // pass data to self or +y processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nyhi_in+1; iy <= nyhi_out; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[1][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[1][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[1][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // pack my ghosts for -y processor - // pass data to self or -y processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy < nylo_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[1][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[1][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[1][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // pack my ghosts for +z processor - // pass data to self or +z processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzhi_in+1; iz <= nzhi_out; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[2][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[2][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[2][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // pack my ghosts for -z processor - // pass data to self or -z processor - // unpack and sum recv data into my real cells - - n = 0; - for (iz = nzlo_out; iz < nzlo_in; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - buf1[n++] = density_brick[iz][iy][ix]; - - if (comm->procneigh[2][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[2][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[2][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - density_brick[iz][iy][ix] += buf2[n++]; - - // remap from 3d brick decomposition to FFT decomposition - // copy grabs inner portion of density from 3d brick - // remap could be done as pre-stage of FFT, - // but this works optimally on only double values, not complex values - - n = 0; - for (iz = nzlo_in; iz <= nzhi_in; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) - density_fft[n++] = density_brick[iz][iy][ix]; - - remap->perform(density_fft,density_fft,work1); -} - -/* ---------------------------------------------------------------------- - ghost-swap to fill ghost cells of my brick with field values -------------------------------------------------------------------------- */ - -void PPPM::fillbrick() -{ - int i,n,ix,iy,iz; - MPI_Request request; - MPI_Status status; - - // pack my real cells for +z processor - // pass data to self or +z processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[2][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[2][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[2][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz < nzlo_in; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } - - // pack my real cells for -z processor - // pass data to self or -z processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[2][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[2][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[2][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzhi_in+1; iz <= nzhi_out; iz++) - for (iy = nylo_in; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } - - // pack my real cells for +y processor - // pass data to self or +y processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[1][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[1][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[1][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy < nylo_in; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } - - // pack my real cells for -y processor - // pass data to self or -y processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[1][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[1][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[1][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nyhi_in+1; iy <= nyhi_out; iy++) - for (ix = nxlo_in; ix <= nxhi_in; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } - - // pack my real cells for +x processor - // pass data to self or +x processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[0][1] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[0][0],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[0][1],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxlo_out; ix < nxlo_in; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } - - // pack my real cells for -x processor - // pass data to self or -x processor - // unpack and sum recv data into my ghost cells - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++) { - buf1[n++] = vdx_brick[iz][iy][ix]; - buf1[n++] = vdy_brick[iz][iy][ix]; - buf1[n++] = vdz_brick[iz][iy][ix]; - } - - if (comm->procneigh[0][0] == me) - for (i = 0; i < n; i++) buf2[i] = buf1[i]; - else { - MPI_Irecv(buf2,nbuf,MPI_DOUBLE,comm->procneigh[0][1],0,world,&request); - MPI_Send(buf1,n,MPI_DOUBLE,comm->procneigh[0][0],0,world); - MPI_Wait(&request,&status); - } - - n = 0; - for (iz = nzlo_out; iz <= nzhi_out; iz++) - for (iy = nylo_out; iy <= nyhi_out; iy++) - for (ix = nxhi_in+1; ix <= nxhi_out; ix++) { - vdx_brick[iz][iy][ix] = buf2[n++]; - vdy_brick[iz][iy][ix] = buf2[n++]; - vdz_brick[iz][iy][ix] = buf2[n++]; - } -} - -/* ---------------------------------------------------------------------- - find center grid pt for each of my particles - check that full stencil for the particle will fit in my 3d brick - store central grid pt indices in part2grid array -------------------------------------------------------------------------- */ - -void PPPM::particle_map() -{ - int nx,ny,nz; - - double **x = atom->x; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - int flag = 0; - for (int i = 0; i < nlocal; i++) { - - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // current particle coord can be outside global and local box - // add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1 - - nx = static_cast ((x[i][0]-boxxlo)*delxinv+shift) - OFFSET; - ny = static_cast ((x[i][1]-boxylo)*delyinv+shift) - OFFSET; - nz = static_cast ((x[i][2]-boxzlo)*delzinv+shift) - OFFSET; - - part2grid[i][0] = nx; - part2grid[i][1] = ny; - part2grid[i][2] = nz; - - // check that entire stencil around nx,ny,nz will fit in my 3d brick - - if (nx+nlower < nxlo_out || nx+nupper > nxhi_out || - ny+nlower < nylo_out || ny+nupper > nyhi_out || - nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag++; - } - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Out of range atoms - cannot compute PPPM"); -} - -/* ---------------------------------------------------------------------- - create discretized "density" on section of global grid due to my particles - density(x,y,z) = charge "density" at grid points of my 3d brick - (nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts) - in global grid -------------------------------------------------------------------------- */ - -void PPPM::make_rho() -{ - int i,l,m,n,nx,ny,nz,mx,my,mz; - double dx,dy,dz,x0,y0,z0; - - // clear 3d density array - - double *vec = &density_brick[nzlo_out][nylo_out][nxlo_out]; - for (i = 0; i < ngrid; i++) vec[i] = 0.0; - - // loop over my charges, add their contribution to nearby grid points - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // (dx,dy,dz) = distance to "lower left" grid pt - // (mx,my,mz) = global coords of moving stencil pt - - double *q = atom->q; - double **x = atom->x; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - for (int i = 0; i < nlocal; i++) { - - nx = part2grid[i][0]; - ny = part2grid[i][1]; - nz = part2grid[i][2]; - dx = nx+shiftone - (x[i][0]-boxxlo)*delxinv; - dy = ny+shiftone - (x[i][1]-boxylo)*delyinv; - dz = nz+shiftone - (x[i][2]-boxzlo)*delzinv; - - compute_rho1d(dx,dy,dz); - - z0 = delvolinv * q[i]; - for (n = nlower; n <= nupper; n++) { - mz = n+nz; - y0 = z0*rho1d[2][n]; - for (m = nlower; m <= nupper; m++) { - my = m+ny; - x0 = y0*rho1d[1][m]; - for (l = nlower; l <= nupper; l++) { - mx = l+nx; - density_brick[mz][my][mx] += x0*rho1d[0][l]; - } - } - } - } -} - -/* ---------------------------------------------------------------------- - FFT-based Poisson solver -------------------------------------------------------------------------- */ - -void PPPM::poisson(int eflag, int vflag) -{ - int i,j,k,n; - double eng; - - // transform charge density (r -> k) - - n = 0; - for (i = 0; i < nfft; i++) { - work1[n++] = density_fft[i]; - work1[n++] = 0.0; - } - - fft1->compute(work1,work1,1); - - // if requested, compute energy and virial contribution - - double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm); - double s2 = scaleinv*scaleinv; - - if (eflag || vflag) { - if (vflag) { - n = 0; - for (i = 0; i < nfft; i++) { - eng = s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]); - for (j = 0; j < 6; j++) virial[j] += eng*vg[i][j]; - energy += eng; - n += 2; - } - } else { - n = 0; - for (i = 0; i < nfft; i++) { - energy += - s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]); - n += 2; - } - } - } - - // scale by 1/total-grid-pts to get rho(k) - // multiply by Green's function to get V(k) - - n = 0; - for (i = 0; i < nfft; i++) { - work1[n++] *= scaleinv * greensfn[i]; - work1[n++] *= scaleinv * greensfn[i]; - } - - // compute gradients of V(r) in each of 3 dims by transformimg -ik*V(k) - // FFT leaves data in 3d brick decomposition - // copy it into inner portion of vdx,vdy,vdz arrays - - // x direction gradient - - n = 0; - for (k = nzlo_fft; k <= nzhi_fft; k++) - for (j = nylo_fft; j <= nyhi_fft; j++) - for (i = nxlo_fft; i <= nxhi_fft; i++) { - work2[n] = fkx[i]*work1[n+1]; - work2[n+1] = -fkx[i]*work1[n]; - n += 2; - } - - fft2->compute(work2,work2,-1); - - n = 0; - for (k = nzlo_in; k <= nzhi_in; k++) - for (j = nylo_in; j <= nyhi_in; j++) - for (i = nxlo_in; i <= nxhi_in; i++) { - vdx_brick[k][j][i] = work2[n]; - n += 2; - } - - // y direction gradient - - n = 0; - for (k = nzlo_fft; k <= nzhi_fft; k++) - for (j = nylo_fft; j <= nyhi_fft; j++) - for (i = nxlo_fft; i <= nxhi_fft; i++) { - work2[n] = fky[j]*work1[n+1]; - work2[n+1] = -fky[j]*work1[n]; - n += 2; - } - - fft2->compute(work2,work2,-1); - - n = 0; - for (k = nzlo_in; k <= nzhi_in; k++) - for (j = nylo_in; j <= nyhi_in; j++) - for (i = nxlo_in; i <= nxhi_in; i++) { - vdy_brick[k][j][i] = work2[n]; - n += 2; - } - - // z direction gradient - - n = 0; - for (k = nzlo_fft; k <= nzhi_fft; k++) - for (j = nylo_fft; j <= nyhi_fft; j++) - for (i = nxlo_fft; i <= nxhi_fft; i++) { - work2[n] = fkz[k]*work1[n+1]; - work2[n+1] = -fkz[k]*work1[n]; - n += 2; - } - - fft2->compute(work2,work2,-1); - - n = 0; - for (k = nzlo_in; k <= nzhi_in; k++) - for (j = nylo_in; j <= nyhi_in; j++) - for (i = nxlo_in; i <= nxhi_in; i++) { - vdz_brick[k][j][i] = work2[n]; - n += 2; - } -} - -/* ---------------------------------------------------------------------- - interpolate from grid to get electric field & force on my particles -------------------------------------------------------------------------- */ - -void PPPM::fieldforce() -{ - int i,l,m,n,nx,ny,nz,mx,my,mz; - double dx,dy,dz,x0,y0,z0; - double ek[3]; - - // loop over my charges, interpolate electric field from nearby grid points - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // (dx,dy,dz) = distance to "lower left" grid pt - // (mx,my,mz) = global coords of moving stencil pt - // ek = 3 components of E-field on particle - - double *q = atom->q; - double **x = atom->x; - double **f = atom->f; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - for (i = 0; i < nlocal; i++) { - - nx = part2grid[i][0]; - ny = part2grid[i][1]; - nz = part2grid[i][2]; - dx = nx+shiftone - (x[i][0]-boxxlo)*delxinv; - dy = ny+shiftone - (x[i][1]-boxylo)*delyinv; - dz = nz+shiftone - (x[i][2]-boxzlo)*delzinv; - - compute_rho1d(dx,dy,dz); - - ek[0] = ek[1] = ek[2] = 0.0; - for (n = nlower; n <= nupper; n++) { - mz = n+nz; - z0 = rho1d[2][n]; - for (m = nlower; m <= nupper; m++) { - my = m+ny; - y0 = z0*rho1d[1][m]; - for (l = nlower; l <= nupper; l++) { - mx = l+nx; - x0 = y0*rho1d[0][l]; - ek[0] -= x0*vdx_brick[mz][my][mx];; - ek[1] -= x0*vdy_brick[mz][my][mx];; - ek[2] -= x0*vdz_brick[mz][my][mx];; - } - } - } - - // convert E-field to force - - f[i][0] += qqrd2e*q[i]*ek[0]; - f[i][1] += qqrd2e*q[i]*ek[1]; - f[i][2] += qqrd2e*q[i]*ek[2]; - } -} - -/* ---------------------------------------------------------------------- - map nprocs to NX by NY grid as PX by PY procs - return optimal px,py -------------------------------------------------------------------------- */ - -void PPPM::procs2grid2d(int nprocs, int nx, int ny, int *px, int *py) -{ - // loop thru all possible factorizations of nprocs - // surf = surface area of largest proc sub-domain - // innermost if test minimizes surface area and surface/volume ratio - - int bestsurf = 2 * (nx + ny); - int bestboxx = 0; - int bestboxy = 0; - - int boxx,boxy,surf,ipx,ipy; - - ipx = 1; - while (ipx <= nprocs) { - if (nprocs % ipx == 0) { - ipy = nprocs/ipx; - boxx = nx/ipx; - if (nx % ipx) boxx++; - boxy = ny/ipy; - if (ny % ipy) boxy++; - surf = boxx + boxy; - if (surf < bestsurf || - (surf == bestsurf && boxx*boxy > bestboxx*bestboxy)) { - bestsurf = surf; - bestboxx = boxx; - bestboxy = boxy; - *px = ipx; - *py = ipy; - } - } - ipx++; - } -} - -/* ---------------------------------------------------------------------- - charge assignment into rho1d - dx,dy,dz = distance of particle from "lower left" grid point -------------------------------------------------------------------------- */ - -void PPPM::compute_rho1d(double dx, double dy, double dz) -{ - int k,l; - - for (k = (1-order)/2; k <= order/2; k++) { - rho1d[0][k] = 0.0; - rho1d[1][k] = 0.0; - rho1d[2][k] = 0.0; - for (l = order-1; l >= 0; l--) { - rho1d[0][k] = rho_coeff[l][k] + rho1d[0][k]*dx; - rho1d[1][k] = rho_coeff[l][k] + rho1d[1][k]*dy; - rho1d[2][k] = rho_coeff[l][k] + rho1d[2][k]*dz; - } - } -} - -/* ---------------------------------------------------------------------- - generate coeffients for the weight function of order n - - (n-1) - Wn(x) = Sum wn(k,x) , Sum is over every other integer - k=-(n-1) - For k=-(n-1),-(n-1)+2, ....., (n-1)-2,n-1 - k is odd integers if n is even and even integers if n is odd - --- - | n-1 - | Sum a(l,j)*(x-k/2)**l if abs(x-k/2) < 1/2 - wn(k,x) = < l=0 - | - | 0 otherwise - --- - a coeffients are packed into the array rho_coeff to eliminate zeros - rho_coeff(l,((k+mod(n+1,2))/2) = a(l,k) -------------------------------------------------------------------------- */ - -void PPPM::compute_rho_coeff() -{ - int j,k,l,m; - double s; - - double **a = memory->create_2d_double_array(order,-order,order,"pppm:a"); - - for (k = -order; k <= order; k++) - for (l = 0; l < order; l++) - a[l][k] = 0.0; - - a[0][0] = 1.0; - for (j = 1; j < order; j++) { - for (k = -j; k <= j; k += 2) { - s = 0.0; - for (l = 0; l < j; l++) { - a[l+1][k] = (a[l][k+1]-a[l][k-1]) / (l+1); - s += pow(0.5,(double) l+1) * - (a[l][k-1] + pow(-1.0,(double) l) * a[l][k+1]) / (l+1); - } - a[0][k] = s; - } - } - - m = (1-order)/2; - for (k = -(order-1); k < order; k += 2) { - for (l = 0; l < order; l++) - rho_coeff[l][m] = a[l][k]; - m++; - } - - memory->destroy_2d_double_array(a,-order); -} - -/* ---------------------------------------------------------------------- - Slab-geometry correction term to dampen inter-slab interactions between - periodically repeating slabs. Yields good approximation to 2D Ewald if - adequate empty space is left between repeating slabs (J. Chem. Phys. - 111, 3155). Slabs defined here to be parallel to the xy plane. -------------------------------------------------------------------------- */ - -void PPPM::slabcorr(int eflag) -{ - // compute local contribution to global dipole moment - - double *q = atom->q; - double **x = atom->x; - int nlocal = atom->nlocal; - - double dipole = 0.0; - for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2]; - - // sum local contributions to get global dipole moment - - double dipole_all; - MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); - - // compute corrections - - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; - - if (eflag) energy += qqrd2e*e_slabcorr; - - // add on force corrections - - double ffact = -4.0*PI*dipole_all/volume; - double **f = atom->f; - - for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*q[i]*ffact; -} - -/* ---------------------------------------------------------------------- - perform and time the 4 FFTs required for N timesteps -------------------------------------------------------------------------- */ - -void PPPM::timing(int n, double &time3d, double &time1d) -{ - double time1,time2; - - for (int i = 0; i < 2*nfft_both; i++) work1[i] = 0.0; - - MPI_Barrier(world); - time1 = MPI_Wtime(); - - for (int i = 0; i < n; i++) { - fft1->compute(work1,work1,1); - fft2->compute(work1,work1,-1); - fft2->compute(work1,work1,-1); - fft2->compute(work1,work1,-1); - } - - MPI_Barrier(world); - time2 = MPI_Wtime(); - time3d = time2 - time1; - - MPI_Barrier(world); - time1 = MPI_Wtime(); - - for (int i = 0; i < n; i++) { - fft1->timing1d(work1,nfft_both,1); - fft2->timing1d(work1,nfft_both,-1); - fft2->timing1d(work1,nfft_both,-1); - fft2->timing1d(work1,nfft_both,-1); - } - - MPI_Barrier(world); - time2 = MPI_Wtime(); - time1d = time2 - time1; -} - -/* ---------------------------------------------------------------------- - memory usage of local arrays -------------------------------------------------------------------------- */ - -int PPPM::memory_usage() -{ - int bytes = nmax*3 * sizeof(double); - int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * - (nzhi_out-nzlo_out+1); - bytes += 4 * nbrick * sizeof(double); - bytes += 6 * nfft_both * sizeof(double); - bytes += nfft_both*6 * sizeof(double); - bytes += 2 * nbuf * sizeof(double); - return bytes; -} diff --git a/src/pppm.h b/src/pppm.h deleted file mode 100644 index f750098426..0000000000 --- a/src/pppm.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 PPPM_H -#define PPPM_H - -#include "kspace.h" - -class FFT3d; -class Remap; - -class PPPM : public KSpace { - public: - PPPM(int, char **); - ~PPPM(); - void init(); - void setup(); - void compute(int, int); - void timing(int, double &, double &); - int memory_usage(); - - protected: - int me,nprocs; - double PI; - double precision; - int nfactors; - int *factors; - double qsum,qsqsum; - double qqrd2e; - double cutoff; - double volume; - double delxinv,delyinv,delzinv,delvolinv; - double shift,shiftone; - - int nxlo_in,nylo_in,nzlo_in,nxhi_in,nyhi_in,nzhi_in; - int nxlo_out,nylo_out,nzlo_out,nxhi_out,nyhi_out,nzhi_out; - int nxlo_ghost,nxhi_ghost,nylo_ghost,nyhi_ghost,nzlo_ghost,nzhi_ghost; - int nxlo_fft,nylo_fft,nzlo_fft,nxhi_fft,nyhi_fft,nzhi_fft; - int nlower,nupper; - int ngrid,nfft,nbuf,nfft_both; - - double ***density_brick; - double ***vdx_brick,***vdy_brick,***vdz_brick; - double *greensfn; - double **vg; - double *fkx,*fky,*fkz; - double *density_fft; - double *work1,*work2; - double *buf1,*buf2; - - double *gf_b; - double **rho1d,**rho_coeff; - - FFT3d *fft1,*fft2; - Remap *remap; - - int **part2grid; // storage for particle -> grid mapping - int nmax; - - // TIP4P settings - int typeH,typeO; // atom types of TIP4P water H and O atoms - double qdist; // distance from O site to negative charge - double alpha; // geometric factor - - void set_grid(); - void allocate(); - void deallocate(); - int factorable(int); - double rms(double, double, double, double, double **); - void compute_gf_denom(); - double gf_denom(double, double, double); - virtual void particle_map(); - virtual void make_rho(); - void brick2fft(); - void fillbrick(); - void poisson(int, int); - virtual void fieldforce(); - void procs2grid2d(int,int,int,int *, int*); - void compute_rho1d(double, double, double); - void compute_rho_coeff(); - void slabcorr(int); -}; - -#endif diff --git a/src/pppm_tip4p.cpp b/src/pppm_tip4p.cpp deleted file mode 100644 index b677629255..0000000000 --- a/src/pppm_tip4p.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 authors: Amalie Frischknecht and Ahmed Ismail (SNL) -------------------------------------------------------------------------- */ - -#include "math.h" -#include "pppm_tip4p.h" -#include "atom.h" -#include "domain.h" -#include "memory.h" -#include "error.h" - -#define OFFSET 4096 - -/* ---------------------------------------------------------------------- */ - -PPPMTIP4P::PPPMTIP4P(int narg, char **arg) : PPPM(narg, arg) {} - -/* ---------------------------------------------------------------------- - find center grid pt for each of my particles - check that full stencil for the particle will fit in my 3d brick - store central grid pt indices in part2grid array -------------------------------------------------------------------------- */ - -void PPPMTIP4P::particle_map() -{ - int nx,ny,nz,iH1,iH2; - double *xi,xM[3]; - - int *type = atom->type; - double **x = atom->x; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - int flag = 0; - for (int i = 0; i < nlocal; i++) { - if (type[i] == typeO) { - find_M(i,iH1,iH2,xM); - xi = xM; - } else xi = x[i]; - - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // current particle coord can be outside global and local box - // add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1 - - nx = static_cast ((xi[0]-boxxlo)*delxinv+shift) - OFFSET; - ny = static_cast ((xi[1]-boxylo)*delyinv+shift) - OFFSET; - nz = static_cast ((xi[2]-boxzlo)*delzinv+shift) - OFFSET; - - part2grid[i][0] = nx; - part2grid[i][1] = ny; - part2grid[i][2] = nz; - - // check that entire stencil around nx,ny,nz will fit in my 3d brick - - if (nx+nlower < nxlo_out || nx+nupper > nxhi_out || - ny+nlower < nylo_out || ny+nupper > nyhi_out || - nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag++; - } - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all("Out of range atoms - cannot compute PPPM"); -} - -/* ---------------------------------------------------------------------- - create discretized "density" on section of global grid due to my particles - density(x,y,z) = charge "density" at grid points of my 3d brick - (nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts) - in global grid -------------------------------------------------------------------------- */ - -void PPPMTIP4P::make_rho() -{ - int i,l,m,n,nx,ny,nz,mx,my,mz,iH1,iH2; - double dx,dy,dz,x0,y0,z0; - double *xi,xM[3]; - - // clear 3d density array - - double *vec = &density_brick[nzlo_out][nylo_out][nxlo_out]; - for (i = 0; i < ngrid; i++) vec[i] = 0.0; - - // loop over my charges, add their contribution to nearby grid points - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // (dx,dy,dz) = distance to "lower left" grid pt - // (mx,my,mz) = global coords of moving stencil pt - - int *type = atom->type; - double *q = atom->q; - double **x = atom->x; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - for (int i = 0; i < nlocal; i++) { - if (type[i] == typeO) { - find_M(i,iH1,iH2,xM); - xi = xM; - } else xi = x[i]; - - nx = part2grid[i][0]; - ny = part2grid[i][1]; - nz = part2grid[i][2]; - dx = nx+shiftone - (xi[0]-boxxlo)*delxinv; - dy = ny+shiftone - (xi[1]-boxylo)*delyinv; - dz = nz+shiftone - (xi[2]-boxzlo)*delzinv; - - compute_rho1d(dx,dy,dz); - - z0 = delvolinv * q[i]; - for (n = nlower; n <= nupper; n++) { - mz = n+nz; - y0 = z0*rho1d[2][n]; - for (m = nlower; m <= nupper; m++) { - my = m+ny; - x0 = y0*rho1d[1][m]; - for (l = nlower; l <= nupper; l++) { - mx = l+nx; - density_brick[mz][my][mx] += x0*rho1d[0][l]; - } - } - } - } -} - -/* ---------------------------------------------------------------------- - interpolate from grid to get electric field & force on my particles -------------------------------------------------------------------------- */ - -void PPPMTIP4P::fieldforce() -{ - int i,l,m,n,nx,ny,nz,mx,my,mz; - double dx,dy,dz,x0,y0,z0; - double ek[3]; - double *xi; - int iH1,iH2; - double xM[3]; - double fx,fy,fz; - - // loop over my charges, interpolate electric field from nearby grid points - // (nx,ny,nz) = global coords of grid pt to "lower left" of charge - // (dx,dy,dz) = distance to "lower left" grid pt - // (mx,my,mz) = global coords of moving stencil pt - // ek = 3 components of E-field on particle - - double *q = atom->q; - double **x = atom->x; - double **f = atom->f; - int *type = atom->type; - int nlocal = atom->nlocal; - double boxxlo = domain->boxxlo; - double boxylo = domain->boxylo; - double boxzlo = domain->boxzlo; - - for (i = 0; i < nlocal; i++) { - if (type[i] == typeO) { - find_M(i,iH1,iH2,xM); - xi = xM; - } else xi = x[i]; - - nx = part2grid[i][0]; - ny = part2grid[i][1]; - nz = part2grid[i][2]; - dx = nx+shiftone - (xi[0]-boxxlo)*delxinv; - dy = ny+shiftone - (xi[1]-boxylo)*delyinv; - dz = nz+shiftone - (xi[2]-boxzlo)*delzinv; - - compute_rho1d(dx,dy,dz); - - ek[0] = ek[1] = ek[2] = 0.0; - for (n = nlower; n <= nupper; n++) { - mz = n+nz; - z0 = rho1d[2][n]; - for (m = nlower; m <= nupper; m++) { - my = m+ny; - y0 = z0*rho1d[1][m]; - for (l = nlower; l <= nupper; l++) { - mx = l+nx; - x0 = y0*rho1d[0][l]; - ek[0] -= x0*vdx_brick[mz][my][mx]; - ek[1] -= x0*vdy_brick[mz][my][mx]; - ek[2] -= x0*vdz_brick[mz][my][mx]; - } - } - } - - // convert E-field to force - - if (type[i] != typeO) { - f[i][0] += qqrd2e*q[i]*ek[0]; - f[i][1] += qqrd2e*q[i]*ek[1]; - f[i][2] += qqrd2e*q[i]*ek[2]; - } else { - - fx = qqrd2e * q[i] * ek[0]; - fy = qqrd2e * q[i] * ek[1]; - fz = qqrd2e * q[i] * ek[2]; - find_M(i,iH1,iH2,xM); - - f[i][0] += fx*(1.0-2.0*alpha); - f[i][1] += fy*(1.0-2.0*alpha); - f[i][2] += fz*(1.0-2.0*alpha); - - f[iH1][0] += alpha*(fx); - f[iH1][1] += alpha*(fy); - f[iH1][2] += alpha*(fz); - - f[iH2][0] += alpha*(fx); - f[iH2][1] += alpha*(fy); - f[iH2][2] += alpha*(fz); - } - } -} - -/* ---------------------------------------------------------------------- - find 2 H atoms bonded to O atom i - compute position xM of fictitious charge site for O atom - also return local indices iH1,iH2 of H atoms -------------------------------------------------------------------------- */ - -void PPPMTIP4P::find_M(int i, int &iH1, int &iH2, double *xM) -{ - iH1 = atom->map(atom->tag[i] + 1); - iH2 = atom->map(atom->tag[i] + 2); - - if (iH1 == -1 || iH2 == -1) error->one("TIP4P hydrogen is missing"); - if (atom->type[iH1] != typeH || atom->type[iH2] != typeH) - error->one("TIP4P hydrogen has incorrect atom type"); - - double **x = atom->x; - - double delx1 = x[iH1][0] - x[i][0]; - double dely1 = x[iH1][1] - x[i][1]; - double delz1 = x[iH1][2] - x[i][2]; - domain->minimum_image(&delx1,&dely1,&delz1); - - double delx2 = x[iH2][0] - x[i][0]; - double dely2 = x[iH2][1] - x[i][1]; - double delz2 = x[iH2][2] - x[i][2]; - domain->minimum_image(&delx2,&dely2,&delz2); - - xM[0] = x[i][0] + alpha * (delx1 + delx2); - xM[1] = x[i][1] + alpha * (dely1 + dely2); - xM[2] = x[i][2] + alpha * (delz1 + delz2); -} diff --git a/src/pppm_tip4p.h b/src/pppm_tip4p.h deleted file mode 100644 index c23ca062ae..0000000000 --- a/src/pppm_tip4p.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 PPPM_TIP4P_H -#define PPPM_TIP4P_H - -#include "pppm.h" - -class PPPMTIP4P : public PPPM { - public: - PPPMTIP4P(int, char **); - - private: - void particle_map(); - void make_rho(); - void fieldforce(); - - void find_M(int, int &, int &, double *); -}; - -#endif diff --git a/src/remap.cpp b/src/remap.cpp deleted file mode 100644 index 215dc5b6d3..0000000000 --- a/src/remap.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "stdio.h" -#include "stdlib.h" -#include "remap.h" -#include "pack.h" - -#define MIN(A,B) ((A) < (B)) ? (A) : (B) -#define MAX(A,B) ((A) > (B)) ? (A) : (B) - -/* ---------------------------------------------------------------------- - Data layout for 3d remaps: - - data set of Nfast x Nmid x Nslow elements is owned by P procs - each element = nqty contiguous datums - on input, each proc owns a subsection of the elements - on output, each proc will own a (presumably different) subsection - my subsection must not overlap with any other proc's subsection, - i.e. the union of all proc's input (or output) subsections must - exactly tile the global Nfast x Nmid x Nslow data set - when called from C, all subsection indices are - C-style from 0 to N-1 where N = Nfast or Nmid or Nslow - when called from F77, all subsection indices are - F77-style from 1 to N where N = Nfast or Nmid or Nslow - a proc can own 0 elements on input or output - by specifying hi index < lo index - on both input and output, data is stored contiguously on a processor - with a fast-varying, mid-varying, and slow-varying index -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Perform 3d remap - - Arguments: - in starting address of input data on this proc - out starting address of where output data for this proc - will be placed (can be same as in) - buf extra memory required for remap - if memory=0 was used in call to remap_3d_create_plan - then buf must be big enough to hold output result - i.e. nqty * (out_ihi-out_ilo+1) * (out_jhi-out_jlo+1) * - (out_khi-out_klo+1) - if memory=1 was used in call to remap_3d_create_plan - then buf is not used, can just be a dummy pointer - plan plan returned by previous call to remap_3d_create_plan -------------------------------------------------------------------------- */ - -void remap_3d(double *in, double *out, double *buf, - struct remap_plan_3d *plan) - -{ - MPI_Status status; - int i,isend,irecv; - double *scratch; - - if (plan->memory == 0) - scratch = buf; - else - scratch = plan->scratch; - - // post all recvs into scratch space - - for (irecv = 0; irecv < plan->nrecv; irecv++) - MPI_Irecv(&scratch[plan->recv_bufloc[irecv]],plan->recv_size[irecv], - MPI_DOUBLE,plan->recv_proc[irecv],0, - plan->comm,&plan->request[irecv]); - - // send all messages to other procs - - for (isend = 0; isend < plan->nsend; isend++) { - plan->pack(&in[plan->send_offset[isend]], - plan->sendbuf,&plan->packplan[isend]); - MPI_Send(plan->sendbuf,plan->send_size[isend],MPI_DOUBLE, - plan->send_proc[isend],0,plan->comm); - } - - // copy in -> scratch -> out for self data - - if (plan->self) { - isend = plan->nsend; - irecv = plan->nrecv; - plan->pack(&in[plan->send_offset[isend]], - &scratch[plan->recv_bufloc[irecv]], - &plan->packplan[isend]); - plan->unpack(&scratch[plan->recv_bufloc[irecv]], - &out[plan->recv_offset[irecv]],&plan->unpackplan[irecv]); - } - - // unpack all messages from scratch -> out - - for (i = 0; i < plan->nrecv; i++) { - MPI_Waitany(plan->nrecv,plan->request,&irecv,&status); - plan->unpack(&scratch[plan->recv_bufloc[irecv]], - &out[plan->recv_offset[irecv]],&plan->unpackplan[irecv]); - } -} - -/* ---------------------------------------------------------------------- - Create plan for performing a 3d remap - - Arguments: - comm MPI communicator for the P procs which own the data - in_ilo,in_ihi input bounds of data I own in fast index - in_jlo,in_jhi input bounds of data I own in mid index - in_klo,in_khi input bounds of data I own in slow index - out_ilo,out_ihi output bounds of data I own in fast index - out_jlo,out_jhi output bounds of data I own in mid index - out_klo,out_khi output bounds of data I own in slow index - nqty # of datums per element - permute permutation in storage order of indices on output - 0 = no permutation - 1 = permute once = mid->fast, slow->mid, fast->slow - 2 = permute twice = slow->fast, fast->mid, mid->slow - memory user provides buffer memory for remap or system does - 0 = user provides memory - 1 = system provides memory - precision precision of data - 1 = single precision (4 bytes per datum) - 2 = double precision (8 bytes per datum) -------------------------------------------------------------------------- */ - -struct remap_plan_3d *remap_3d_create_plan( - MPI_Comm comm, - int in_ilo, int in_ihi, int in_jlo, int in_jhi, - int in_klo, int in_khi, - int out_ilo, int out_ihi, int out_jlo, int out_jhi, - int out_klo, int out_khi, - int nqty, int permute, int memory, int precision) - -{ - struct remap_plan_3d *plan; - struct extent_3d *array; - struct extent_3d in,out,overlap; - int i,iproc,nsend,nrecv,ibuf,size,me,nprocs; - - // query MPI info - - MPI_Comm_rank(comm,&me); - MPI_Comm_size(comm,&nprocs); - - // single precision not yet supported - - if (precision == 1) { - if (me == 0) printf("Single precision not supported\n"); - return NULL; - } - - // allocate memory for plan data struct - - plan = (struct remap_plan_3d *) malloc(sizeof(struct remap_plan_3d)); - if (plan == NULL) return NULL; - - // store parameters in local data structs - - in.ilo = in_ilo; - in.ihi = in_ihi; - in.isize = in.ihi - in.ilo + 1; - - in.jlo = in_jlo; - in.jhi = in_jhi; - in.jsize = in.jhi - in.jlo + 1; - - in.klo = in_klo; - in.khi = in_khi; - in.ksize = in.khi - in.klo + 1; - - out.ilo = out_ilo; - out.ihi = out_ihi; - out.isize = out.ihi - out.ilo + 1; - - out.jlo = out_jlo; - out.jhi = out_jhi; - out.jsize = out.jhi - out.jlo + 1; - - out.klo = out_klo; - out.khi = out_khi; - out.ksize = out.khi - out.klo + 1; - - // combine output extents across all procs - - array = (struct extent_3d *) malloc(nprocs*sizeof(struct extent_3d)); - if (array == NULL) return NULL; - - MPI_Allgather(&out,sizeof(struct extent_3d),MPI_BYTE, - array,sizeof(struct extent_3d),MPI_BYTE,comm); - - // count send collides, including self - - nsend = 0; - iproc = me; - for (i = 0; i < nprocs; i++) { - iproc++; - if (iproc == nprocs) iproc = 0; - nsend += remap_3d_collide(&in,&array[iproc],&overlap); - } - - // malloc space for send info - - if (nsend) { - if (precision == 1) - plan->pack = NULL; - else - plan->pack = pack_3d; - - plan->send_offset = (int *) malloc(nsend*sizeof(int)); - plan->send_size = (int *) malloc(nsend*sizeof(int)); - plan->send_proc = (int *) malloc(nsend*sizeof(int)); - plan->packplan = (struct pack_plan_3d *) - malloc(nsend*sizeof(struct pack_plan_3d)); - - if (plan->send_offset == NULL || plan->send_size == NULL || - plan->send_proc == NULL || plan->packplan == NULL) return NULL; - } - - // store send info, with self as last entry - - nsend = 0; - iproc = me; - for (i = 0; i < nprocs; i++) { - iproc++; - if (iproc == nprocs) iproc = 0; - if (remap_3d_collide(&in,&array[iproc],&overlap)) { - plan->send_proc[nsend] = iproc; - plan->send_offset[nsend] = nqty * - ((overlap.klo-in.klo)*in.jsize*in.isize + - ((overlap.jlo-in.jlo)*in.isize + overlap.ilo-in.ilo)); - plan->packplan[nsend].nfast = nqty*overlap.isize; - plan->packplan[nsend].nmid = overlap.jsize; - plan->packplan[nsend].nslow = overlap.ksize; - plan->packplan[nsend].nstride_line = nqty*in.isize; - plan->packplan[nsend].nstride_plane = nqty*in.jsize*in.isize; - plan->packplan[nsend].nqty = nqty; - plan->send_size[nsend] = nqty*overlap.isize*overlap.jsize*overlap.ksize; - nsend++; - } - } - - // plan->nsend = # of sends not including self - - if (nsend && plan->send_proc[nsend-1] == me) - plan->nsend = nsend - 1; - else - plan->nsend = nsend; - - // combine input extents across all procs - - MPI_Allgather(&in,sizeof(struct extent_3d),MPI_BYTE, - array,sizeof(struct extent_3d),MPI_BYTE,comm); - - // count recv collides, including self - - nrecv = 0; - iproc = me; - for (i = 0; i < nprocs; i++) { - iproc++; - if (iproc == nprocs) iproc = 0; - nrecv += remap_3d_collide(&out,&array[iproc],&overlap); - } - - // malloc space for recv info - - if (nrecv) { - if (precision == 1) { - if (permute == 0) - plan->unpack = NULL; - else if (permute == 1) { - if (nqty == 1) - plan->unpack = NULL; - else if (nqty == 2) - plan->unpack = NULL; - else - plan->unpack = NULL; - } - else if (permute == 2) { - if (nqty == 1) - plan->unpack = NULL; - else if (nqty == 2) - plan->unpack = NULL; - else - plan->unpack = NULL; - } - } - else if (precision == 2) { - if (permute == 0) - plan->unpack = unpack_3d; - else if (permute == 1) { - if (nqty == 1) - plan->unpack = unpack_3d_permute1_1; - else if (nqty == 2) - plan->unpack = unpack_3d_permute1_2; - else - plan->unpack = unpack_3d_permute1_n; - } - else if (permute == 2) { - if (nqty == 1) - plan->unpack = unpack_3d_permute2_1; - else if (nqty == 2) - plan->unpack = unpack_3d_permute2_2; - else - plan->unpack = unpack_3d_permute2_n; - } - } - - plan->recv_offset = (int *) malloc(nrecv*sizeof(int)); - plan->recv_size = (int *) malloc(nrecv*sizeof(int)); - plan->recv_proc = (int *) malloc(nrecv*sizeof(int)); - plan->recv_bufloc = (int *) malloc(nrecv*sizeof(int)); - plan->request = (MPI_Request *) malloc(nrecv*sizeof(MPI_Request)); - plan->unpackplan = (struct pack_plan_3d *) - malloc(nrecv*sizeof(struct pack_plan_3d)); - - if (plan->recv_offset == NULL || plan->recv_size == NULL || - plan->recv_proc == NULL || plan->recv_bufloc == NULL || - plan->request == NULL || plan->unpackplan == NULL) return NULL; - } - - // store recv info, with self as last entry - - ibuf = 0; - nrecv = 0; - iproc = me; - - for (i = 0; i < nprocs; i++) { - iproc++; - if (iproc == nprocs) iproc = 0; - if (remap_3d_collide(&out,&array[iproc],&overlap)) { - plan->recv_proc[nrecv] = iproc; - plan->recv_bufloc[nrecv] = ibuf; - - if (permute == 0) { - plan->recv_offset[nrecv] = nqty * - ((overlap.klo-out.klo)*out.jsize*out.isize + - (overlap.jlo-out.jlo)*out.isize + (overlap.ilo-out.ilo)); - plan->unpackplan[nrecv].nfast = nqty*overlap.isize; - plan->unpackplan[nrecv].nmid = overlap.jsize; - plan->unpackplan[nrecv].nslow = overlap.ksize; - plan->unpackplan[nrecv].nstride_line = nqty*out.isize; - plan->unpackplan[nrecv].nstride_plane = nqty*out.jsize*out.isize; - plan->unpackplan[nrecv].nqty = nqty; - } - else if (permute == 1) { - plan->recv_offset[nrecv] = nqty * - ((overlap.ilo-out.ilo)*out.ksize*out.jsize + - (overlap.klo-out.klo)*out.jsize + (overlap.jlo-out.jlo)); - plan->unpackplan[nrecv].nfast = overlap.isize; - plan->unpackplan[nrecv].nmid = overlap.jsize; - plan->unpackplan[nrecv].nslow = overlap.ksize; - plan->unpackplan[nrecv].nstride_line = nqty*out.jsize; - plan->unpackplan[nrecv].nstride_plane = nqty*out.ksize*out.jsize; - plan->unpackplan[nrecv].nqty = nqty; - } - else { - plan->recv_offset[nrecv] = nqty * - ((overlap.jlo-out.jlo)*out.isize*out.ksize + - (overlap.ilo-out.ilo)*out.ksize + (overlap.klo-out.klo)); - plan->unpackplan[nrecv].nfast = overlap.isize; - plan->unpackplan[nrecv].nmid = overlap.jsize; - plan->unpackplan[nrecv].nslow = overlap.ksize; - plan->unpackplan[nrecv].nstride_line = nqty*out.ksize; - plan->unpackplan[nrecv].nstride_plane = nqty*out.isize*out.ksize; - plan->unpackplan[nrecv].nqty = nqty; - } - - plan->recv_size[nrecv] = nqty*overlap.isize*overlap.jsize*overlap.ksize; - ibuf += plan->recv_size[nrecv]; - nrecv++; - } - } - - // plan->nrecv = # of recvs not including self - - if (nrecv && plan->recv_proc[nrecv-1] == me) - plan->nrecv = nrecv - 1; - else - plan->nrecv = nrecv; - - // init remaining fields in remap plan - - plan->memory = memory; - - if (nrecv == plan->nrecv) - plan->self = 0; - else - plan->self = 1; - - // free locally malloced space - - free(array); - - // find biggest send message (not including self) and malloc space for it - - plan->sendbuf = NULL; - - size = 0; - for (nsend = 0; nsend < plan->nsend; nsend++) - size = MAX(size,plan->send_size[nsend]); - - if (size) { - if (precision == 1) - plan->sendbuf = NULL; - else - plan->sendbuf = (double *) malloc(size*sizeof(double)); - if (plan->sendbuf == NULL) return NULL; - } - - // if requested, allocate internal scratch space for recvs, - // only need it if I will receive any data (including self) - - plan->scratch = NULL; - - if (memory == 1) { - if (nrecv > 0) { - if (precision == 1) - plan->scratch = NULL; - else - plan->scratch = - (double *) malloc(nqty*out.isize*out.jsize*out.ksize*sizeof(double)); - if (plan->scratch == NULL) return NULL; - } - } - - // create new MPI communicator for remap - - MPI_Comm_dup(comm,&plan->comm); - - // return pointer to plan - - return plan; -} - -/* ---------------------------------------------------------------------- - Destroy a 3d remap plan -------------------------------------------------------------------------- */ - -void remap_3d_destroy_plan(struct remap_plan_3d *plan) - -{ - // free MPI communicator - - MPI_Comm_free(&plan->comm); - - // free internal arrays - - if (plan->nsend || plan->self) { - free(plan->send_offset); - free(plan->send_size); - free(plan->send_proc); - free(plan->packplan); - if (plan->sendbuf) free(plan->sendbuf); - } - - if (plan->nrecv || plan->self) { - free(plan->recv_offset); - free(plan->recv_size); - free(plan->recv_proc); - free(plan->recv_bufloc); - free(plan->request); - free(plan->unpackplan); - if (plan->scratch) free(plan->scratch); - } - - // free plan itself - - free(plan); -} - -/* ---------------------------------------------------------------------- - collide 2 sets of indices to determine overlap - compare bounds of block1 with block2 to see if they overlap - return 1 if they do and put bounds of overlapping section in overlap - return 0 if they do not overlap -------------------------------------------------------------------------- */ - -int remap_3d_collide(struct extent_3d *block1, struct extent_3d *block2, - struct extent_3d *overlap) - -{ - overlap->ilo = MAX(block1->ilo,block2->ilo); - overlap->ihi = MIN(block1->ihi,block2->ihi); - overlap->jlo = MAX(block1->jlo,block2->jlo); - overlap->jhi = MIN(block1->jhi,block2->jhi); - overlap->klo = MAX(block1->klo,block2->klo); - overlap->khi = MIN(block1->khi,block2->khi); - - if (overlap->ilo > overlap->ihi || - overlap->jlo > overlap->jhi || - overlap->klo > overlap->khi) return 0; - - overlap->isize = overlap->ihi - overlap->ilo + 1; - overlap->jsize = overlap->jhi - overlap->jlo + 1; - overlap->ksize = overlap->khi - overlap->klo + 1; - - return 1; -} diff --git a/src/remap.h b/src/remap.h deleted file mode 100644 index 15bcdbe41e..0000000000 --- a/src/remap.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ---------------------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -// details of how to do a 3d remap - -struct remap_plan_3d { - double *sendbuf; // buffer for MPI sends - double *scratch; // scratch buffer for MPI recvs - void (*pack)(double *, double *, struct pack_plan_3d *); - // which pack function to use - void (*unpack)(double *, double *, struct pack_plan_3d *); - // which unpack function to use - int *send_offset; // extraction loc for each send - int *send_size; // size of each send message - int *send_proc; // proc to send each message to - struct pack_plan_3d *packplan; // pack plan for each send message - int *recv_offset; // insertion loc for each recv - int *recv_size; // size of each recv message - int *recv_proc; // proc to recv each message from - int *recv_bufloc; // offset in scratch buf for each recv - MPI_Request *request; // MPI request for each posted recv - struct pack_plan_3d *unpackplan; // unpack plan for each recv message - int nrecv; // # of recvs from other procs - int nsend; // # of sends to other procs - int self; // whether I send/recv with myself - int memory; // user provides scratch space or not - MPI_Comm comm; // group of procs performing remap -}; - -// collision between 2 regions - -struct extent_3d { - int ilo,ihi,isize; - int jlo,jhi,jsize; - int klo,khi,ksize; -}; - -// function prototypes - -void remap_3d(double *, double *, double *, struct remap_plan_3d *); -struct remap_plan_3d *remap_3d_create_plan(MPI_Comm, - int, int, int, int, int, int, int, int, int, int, int, int, - int, int, int, int); -void remap_3d_destroy_plan(struct remap_plan_3d *); -int remap_3d_collide(struct extent_3d *, - struct extent_3d *, struct extent_3d *); diff --git a/src/remap_wrap.cpp b/src/remap_wrap.cpp deleted file mode 100644 index 9c652ab0f4..0000000000 --- a/src/remap_wrap.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 "remap_wrap.h" -#include "error.h" - -/* ---------------------------------------------------------------------- */ - -Remap::Remap(MPI_Comm comm, - int in_ilo, int in_ihi, int in_jlo, int in_jhi, - int in_klo, int in_khi, - int out_ilo, int out_ihi, int out_jlo, int out_jhi, - int out_klo, int out_khi, - int nqty, int permute, int memory, int precision) -{ - plan = remap_3d_create_plan(comm, - in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, - out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, - nqty,permute,memory,precision); - if (plan == NULL) error->one("Could not create 3d remap plan"); -} - -/* ---------------------------------------------------------------------- */ - -Remap::~Remap() -{ - remap_3d_destroy_plan(plan); -} - -/* ---------------------------------------------------------------------- */ - -void Remap::perform(double *in, double *out, double *buf) -{ - remap_3d(in,out,buf,plan); -} diff --git a/src/remap_wrap.h b/src/remap_wrap.h deleted file mode 100644 index b27a359322..0000000000 --- a/src/remap_wrap.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 REMAP_WRAP_H -#define REMAP_WRAP_H - -#include "lammps.h" -#include "remap.h" - -class Remap : public LAMMPS { - public: - Remap(MPI_Comm,int,int,int,int,int,int, - int,int,int,int,int,int,int,int,int,int); - ~Remap(); - void perform(double *, double *, double *); - - private: - struct remap_plan_3d *plan; -}; - -#endif diff --git a/src/style_kspace.h b/src/style_kspace.h index c6ea29b73b..e69de29bb2 100644 --- a/src/style_kspace.h +++ b/src/style_kspace.h @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 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 diff --git a/src/style_manybody.h b/src/style_manybody.h index 659f63ca83..e69de29bb2 100644 --- a/src/style_manybody.h +++ b/src/style_manybody.h @@ -1,24 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 PairInclude -#include "pair_eam.h" -#include "pair_eam_alloy.h" -#include "pair_eam_fs.h" -#endif - -#ifdef PairClass -PairStyle(eam,PairEAM) -PairStyle(eam/alloy,PairEAMAlloy) -PairStyle(eam/fs,PairEAMFS) -#endif diff --git a/src/style_molecule.h b/src/style_molecule.h index 1da512819d..e69de29bb2 100644 --- a/src/style_molecule.h +++ b/src/style_molecule.h @@ -1,116 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 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_angle.h" -#include "atom_bond.h" -#include "atom_full.h" -#include "atom_molecular.h" -#endif - -#ifdef AtomClass -AtomStyle(angle,AtomAngle) -AtomStyle(bond,AtomBond) -AtomStyle(full,AtomFull) -AtomStyle(molecular,AtomMolecular) -#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