From 3e908537397e4dc5910fde07fe3a0b0f5abf4590 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Fri, 7 Oct 2011 23:40:08 +0000
Subject: [PATCH 01/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7045
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/MAKE/Makefile.g++ | 8 ++++----
src/MAKE/Makefile.serial | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++
index c9480cd026..62f82e372a 100755
--- a/src/MAKE/Makefile.g++
+++ b/src/MAKE/Makefile.g++
@@ -6,10 +6,10 @@ SHELL = /bin/sh
# compiler/linker settings
# specify flags and libraries needed for your compiler
-CC = g++4
+CC = g++
CCFLAGS = -g -O # -Wunused
DEPFLAGS = -M
-LINK = g++4
+LINK = g++
LINKFLAGS = -g -O
LIB =
ARCHIVE = ar
@@ -35,7 +35,7 @@ LMP_INC = -DLAMMPS_GZIP -DLAMMPS_JPEG
MPI_INC = -DMPICH_SKIP_MPICXX
MPI_PATH =
-MPI_LIB = -lmpich -lpthread
+MPI_LIB = -lmpich -lmpl -lpthread
# FFT library, OPTIONAL
# see discussion in doc/Section_start.html#2_2 (step 6)
@@ -57,7 +57,7 @@ FFT_LIB = -lfftw
JPG_INC =
JPG_PATH =
-JPG_LIB = /usr/local/lib/libjpeg.a
+JPG_LIB = -ljpeg
# ---------------------------------------------------------------------
# build rules and dependencies
diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
index cc4480d79b..8849b18432 100755
--- a/src/MAKE/Makefile.serial
+++ b/src/MAKE/Makefile.serial
@@ -7,10 +7,10 @@ SHELL = /bin/sh
# generally no need to edit this section
# unless additional compiler/linker flags or libraries needed for your machine
-CC = g++4
+CC = g++
CCFLAGS = -O
DEPFLAGS = -M
-LINK = g++4
+LINK = g++
LINKFLAGS = -O
LIB =
ARCHIVE = ar
From 504227e2e602853450f9447501344750db220c57 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Fri, 7 Oct 2011 23:44:14 +0000
Subject: [PATCH 02/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7046
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
tools/amber2lmp/amber2lammps.py | 1986 +++++++++++++++----------------
1 file changed, 993 insertions(+), 993 deletions(-)
diff --git a/tools/amber2lmp/amber2lammps.py b/tools/amber2lmp/amber2lammps.py
index c47a17cfe6..08bdf38d9e 100644
--- a/tools/amber2lmp/amber2lammps.py
+++ b/tools/amber2lmp/amber2lammps.py
@@ -1,993 +1,993 @@
-#! /usr/bin/python
-
-#
-# This is amber2lammps, a program written by Keir E. Novik to convert
-# Amber files to Lammps files.
-#
-# Copyright 1999, 2000 Keir E. Novik; all rights reserved.
-#
-# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README
-#
-
-#============================================================
-
-def Pop(S, I=-1):
- 'Pop item I from list'
- X = S[I]
- del S[I]
- return X
-
-#============================================================
-
-class Lammps:
-
- #--------------------------------------------------------
-
- def Dump(self):
- 'Write out contents of self (intended for debugging)'
- Name_list = self.__dict__.keys()
- Name_list.sort()
- for Name in Name_list:
- print Name + ':', self.__dict__[Name]
-
- #--------------------------------------------------------
-
- def Write_data(self, Basename, Item_list):
- 'Write the Lammps data to file (used by Write_Lammps)'
- import os, sys
-
- Filename = 'data.' + Basename
-
- Dir_list = os.listdir('.')
- i = 1
- while Filename in Dir_list:
- Filename = 'data' + `i` + '.' + Basename
- i = i +1
- del i
-
- print 'Writing', Filename + '...',
- sys.stdout.flush()
-
- try:
- F = open(Filename, 'w')
- except IOError, Detail:
- print '(error:', Detail[1] + '!)'
- return
-
- try:
- F.writelines(Item_list)
- except IOError, Detail:
- print '(error:', Detail[1] + '!)'
- F.close()
- return
-
- F.close()
- print 'done.'
-
- #--------------------------------------------------------
-
- def Write_Lammps(self, Basename):
- 'Write the Lammps data file, ignoring blank sections'
- import string
- L = []
-
- L.append('LAMMPS data file for ' + self.name + '\n\n')
-
- L.append(`self.atoms` + ' atoms\n')
- L.append(`self.bonds` + ' bonds\n')
- L.append(`self.angles` + ' angles\n')
- L.append(`self.dihedrals` + ' dihedrals\n')
- L.append(`self.impropers` + ' impropers\n\n')
-
- L.append(`self.atom_types` + ' atom types\n')
- if self.bonds > 0:
- L.append(`self.bond_types` + ' bond types\n')
- if self.angles > 0:
- L.append(`self.angle_types` + ' angle types\n')
- if self.dihedrals > 0:
- L.append(`self.dihedral_types` + ' dihedral types\n')
- L.append('\n')
-
- L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n')
- L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n')
- L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n')
-
- if self.atom_types != 0:
- L.append('Masses\n\n')
- for i in range(self.atom_types):
- L.append(`i+1` + ' ' + `self.Masses[i]` + '\n')
- L.append('\n')
-
- L.append('Pair Coeffs\n\n')
- for i in range(self.atom_types):
- L.append(`i+1`)
- for j in range(len(self.Nonbond_Coeffs[0])):
- L.append(' ' + `self.Nonbond_Coeffs[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.bonds != 0 and self.bond_types != 0:
- L.append('Bond Coeffs\n\n')
- for i in range(self.bond_types):
- L.append(`i+1`)
- for j in range(len(self.Bond_Coeffs[0])):
- L.append(' ' + `self.Bond_Coeffs[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.angles != 0 and self.angle_types != 0:
- L.append('Angle Coeffs\n\n')
- for i in range(self.angle_types):
- L.append(`i+1`)
- for j in range(len(self.Angle_Coeffs[0])):
- L.append(' ' + `self.Angle_Coeffs[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.dihedrals != 0 and self.dihedral_types != 0:
- L.append('Dihedral Coeffs\n\n')
- for i in range(self.dihedral_types):
- L.append(`i+1`)
- for j in range(len(self.Dihedral_Coeffs[0])):
- L.append(' ' + `self.Dihedral_Coeffs[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.atoms != 0:
- L.append('Atoms\n\n')
- for i in range(self.atoms):
- L.append(`i+1`)
- for j in range(len(self.Atoms[0])):
- L.append(' ' + `self.Atoms[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.bonds != 0 and self.bond_types != 0:
- L.append('Bonds\n\n')
- for i in range(self.bonds):
- L.append(`i+1`)
- for j in range(len(self.Bonds[0])):
- L.append(' ' + `self.Bonds[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.angles != 0 and self.angle_types != 0:
- L.append('Angles\n\n')
- for i in range(self.angles):
- L.append(`i+1`)
- for j in range(len(self.Angles[0])):
- L.append(' ' + `self.Angles[i][j]`)
- L.append('\n')
- L.append('\n')
-
- if self.dihedrals != 0 and self.dihedral_types != 0:
- L.append('Dihedrals\n\n')
- for i in range(self.dihedrals):
- L.append(`i+1`)
- for j in range(len(self.Dihedrals[0])):
- L.append(' ' + `self.Dihedrals[i][j]`)
- L.append('\n')
- L.append('\n')
-
- self.Write_data(Basename, L)
-
-#============================================================
-
-class Amber:
- def __init__(self):
- 'Initialise the Amber class'
- self.CRD_is_read = 0
- self.TOP_is_read = 0
-
- #--------------------------------------------------------
-
- def Dump(self):
- 'Write out contents of self (intended for debugging)'
- Name_list = self.__dict__.keys()
- Name_list.sort()
- for Name in Name_list:
- print Name + ':', self.__dict__[Name]
-
- #--------------------------------------------------------
-
- def Coerce_to_Lammps(self):
- 'Return the Amber data converted to Lammps format'
-
- import math
-
- if self.CRD_is_read and self.TOP_is_read:
- l = Lammps()
- print 'Converting...',
-
- l.name = self.ITITL
- l.atoms = self.NATOM
- l.bonds = self.NBONH + self.MBONA
- l.angles = self.NTHETH + self.MTHETA
- l.dihedrals = self.NPHIH + self.MPHIA
- l.impropers = 0
- l.atom_types = self.NTYPES
- l.bond_types = self.NUMBND
- l.angle_types = self.NUMANG
- l.dihedral_types = self.NPTRA
-
- Shift = 0
- if self.__dict__.has_key('BOX'):
- l.xlo = 0.0
- l.xhi = self.BOX[0]
- l.ylo = 0.0
- l.yhi = self.BOX[1]
- l.zlo = 0.0
- l.zhi = self.BOX[2]
- if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \
- (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \
- (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)):
- # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS
- # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box,
- # please uncomment the below 2 lines.
- print '(warning: Currently not shifting the atoms to the periodic box)'
- #Shift = 1
- else:
- print '(warning: Guessing at periodic box!)',
- l.xlo = min(self.X)
- l.xhi = max(self.X)
- l.ylo = min(self.Y)
- l.yhi = max(self.Y)
- l.zlo = min(self.Z)
- l.zhi = max(self.Z)
-
- # This doesn't check duplicate values
- l.Masses = []
- for i in range(l.atom_types):
- l.Masses.append(0)
- for i in range(self.NATOM):
- l.Masses[self.IAC[i] - 1] = self.AMASS[i]
-
- l.Nonbond_Coeffs = []
- for i in range(self.NTYPES):
- l.Nonbond_Coeffs.append([0,0])
- for i in range(self.NTYPES):
- j = self.ICO[i * (self.NTYPES + 1)] - 1
- if self.CN1[j] == 0.0:
- l.Nonbond_Coeffs[i][0] = 0.0
- else:
- l.Nonbond_Coeffs[i][0] = \
- 0.25 * (self.CN2[j])**2 / self.CN1[j]
- if self.CN2[j] == 0.0:
- l.Nonbond_Coeffs[i][1] = 0.0
- else:
- l.Nonbond_Coeffs[i][1] = \
- (self.CN1[j] / self.CN2[j])**(1.0/6.0)
-
- l.Bond_Coeffs = []
- for i in range(self.NUMBND):
- l.Bond_Coeffs.append([0,0])
- for i in range(self.NUMBND):
- l.Bond_Coeffs[i][0] = self.RK[i]
- l.Bond_Coeffs[i][1] = self.REQ[i]
-
- l.Angle_Coeffs = []
- for i in range(self.NUMANG):
- l.Angle_Coeffs.append([0,0])
- for i in range(self.NUMANG):
- l.Angle_Coeffs[i][0] = self.TK[i]
- l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i]
-
- l.Dihedral_Coeffs = []
- for i in range(self.NPTRA):
- l.Dihedral_Coeffs.append([0,0,0])
- for i in range(self.NPTRA):
- l.Dihedral_Coeffs[i][0] = self.PK[i]
- if self.PHASE[i] == 0:
- l.Dihedral_Coeffs[i][1] = 1
- else:
- l.Dihedral_Coeffs[i][1] = -1
- l.Dihedral_Coeffs[i][2] = int(self.PN[i])
-
- l.Atoms = []
- for i in range(self.NATOM):
- x = self.X[i]
- y = self.Y[i]
- z = self.Z[i]
- if Shift:
- while x < l.xlo:
- x = x + self.BOX[0]
- while x > l.xhi:
- x = x - self.BOX[0]
- while y < l.ylo:
- y = y + self.BOX[1]
- while y > l.yhi:
- y = y - self.BOX[1]
- while z < l.zlo:
- z = z + self.BOX[2]
- while z > l.zhi:
- z = z - self.BOX[2]
- l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \
- x, y, z])
-
- l.Bonds = []
- for i in range(l.bonds):
- l.Bonds.append([0,0,0])
- for i in range(self.NBONH):
- l.Bonds[i][0] = self.ICBH[i]
- l.Bonds[i][1] = abs(self.IBH[i])/3 + 1
- l.Bonds[i][2] = abs(self.JBH[i])/3 + 1
- for i in range(self.NBONA):
- l.Bonds[self.NBONH + i][0] = self.ICB[i]
- l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1
- l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1
-
- l.Angles = []
- for i in range(l.angles):
- l.Angles.append([0,0,0,0])
- for i in range(self.NTHETH):
- l.Angles[i][0] = self.ICTH[i]
- l.Angles[i][1] = abs(self.ITH[i])/3 + 1
- l.Angles[i][2] = abs(self.JTH[i])/3 + 1
- l.Angles[i][3] = abs(self.KTH[i])/3 + 1
- for i in range(self.NTHETA):
- l.Angles[self.NTHETH + i][0] = self.ICT[i]
- l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1
- l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1
- l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1
-
- l.Dihedrals = []
- for i in range(l.dihedrals):
- l.Dihedrals.append([0,0,0,0,0])
- for i in range(self.NPHIH):
- l.Dihedrals[i][0] = self.ICPH[i]
- l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1
- l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1
- l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1
- l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1
- for i in range(self.NPHIA):
- l.Dihedrals[self.NPHIH + i][0] = self.ICP[i]
- l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1
- l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1
- l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1
- l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1
-
- print 'done.'
- return l
- else:
- print '(Error: Not all the Amber data has been read!)'
-
- #--------------------------------------------------------
-
- def Read_data(self, Filename):
- 'Read the filename, returning a list of strings'
-
- import string, sys
-
- print 'Reading', Filename + '...',
- sys.stdout.flush()
-
- try:
- F = open(Filename)
- except IOError, Detail:
- print '(error:', Detail[1] + '!)'
- return
-
- try:
- Lines = F.readlines()
- except IOError, Detail:
- print '(error:', Detail[1] + '!)'
- F.close()
- return
-
- F.close()
-
- # If the first line is empty, use the Basename
- if Filename[-4:] == '.crd':
- if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file
- Basename = Filename[:string.find(Filename, '.')]
- Item_list = [Basename]
- print 'Warning: Title not present... Assigning Basename as Title'
- else:
- Item_list = []
- else:
- if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file
- Basename = Filename[:string.find(Filename, '.')]
- Item_list = [Basename]
- print 'Warning: Title not present... Assigning Basename as Title'
- else:
- Item_list = []
-
- for Line in Lines:
- if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file.
- Item_list.extend(string.split(Line))
-
- return Item_list
-
- #--------------------------------------------------------
-
- def Read_CRD(self, Basename):
- 'Read the Amber coordinate/restart (.crd) file'
-
- # The optional velocities and periodic box size are not yet parsed.
-
- Item_list = self.Read_data(Basename + '.crd')
-
- if Item_list == None:
- return
- elif len(Item_list) < 2:
- print '(error: File too short!)'
- return
-
- # Parse the data
- if self.__dict__.has_key('ITITL'):
- if Pop(Item_list,0) != self.ITITL:
- print '(warning: ITITL differs!)',
- else:
- self.ITITL = Pop(Item_list,0)
- print self.ITITL #Vikas Modification : Priting the Title
-
- if self.__dict__.has_key('NATOM'):
- if eval(Pop(Item_list,0)) != self.NATOM:
- print '(error: NATOM differs!)'
- return
- else:
- self.NATOM = eval(Pop(Item_list,0))
- print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value.
-
- #if len(Item_list) == 1 + 3 * self.NATOM:
- # Vikas' Modification: I changed the condition.
- if (len(Item_list)%3) != 0:
- self.TIME = eval(Pop(Item_list,0))
- else:
- self.TIME = 0
- print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value.
- if len(Item_list) < 3 * self.NATOM:
- print '(error: File too short!)'
- return
-
- self.X = []
- self.Y = []
- self.Z = []
- for i in range(self.NATOM):
- self.X.append(eval(Pop(Item_list,0)))
- self.Y.append(eval(Pop(Item_list,0)))
- self.Z.append(eval(Pop(Item_list,0)))
-
- if (self.NATOM == 1) and len(Item_list):
- print '(warning: Ambiguity!)',
-
- if len(Item_list) >= 3 * self.NATOM:
- self.VX = []
- self.VY = []
- self.VZ = []
- for i in range(self.NATOM):
- self.VX.append(eval(Pop(Item_list,0)))
- self.VY.append(eval(Pop(Item_list,0)))
- self.VZ.append(eval(Pop(Item_list,0)))
-
- if len(Item_list) >= 3:
- self.BOX = []
- for i in range(3):
- self.BOX.append(eval(Pop(Item_list,0)))
-
- if len(Item_list):
- print '(warning: File too large!)',
-
- print 'done.'
- self.CRD_is_read = 1
-
- #--------------------------------------------------------
-
- def Read_TOP(self, Basename):
- 'Read the Amber parameter/topology (.top) file'
- Item_list = self.Read_data(Basename + '.top')
-
- if Item_list == None:
- return
- elif len(Item_list) < 31:
- print '(error: File too short!)'
- return
-
- # Parse the data
- if self.__dict__.has_key('ITITL'):
- if Pop(Item_list,0) != self.ITITL:
- print '(warning: ITITL differs!)'
- else:
- self.ITITL = Pop(Item_list,0)
- print self.ITITL # Printing Self Title
-
- if self.__dict__.has_key('NATOM'):
- if eval(Pop(Item_list,0)) != self.NATOM:
- print '(error: NATOM differs!)'
- return
- else:
- self.NATOM = eval(Pop(Item_list,0))
- print self.NATOM # Printing total number of atoms just to make sure that thing are going right
- self.NTYPES = eval(Pop(Item_list,0))
- self.NBONH = eval(Pop(Item_list,0))
- self.MBONA = eval(Pop(Item_list,0))
- self.NTHETH = eval(Pop(Item_list,0))
- self.MTHETA = eval(Pop(Item_list,0))
- self.NPHIH = eval(Pop(Item_list,0))
- self.MPHIA = eval(Pop(Item_list,0))
- self.NHPARM = eval(Pop(Item_list,0))
- self.NPARM = eval(Pop(Item_list,0))
- self.NEXT = eval(Pop(Item_list,0))
- self.NRES = eval(Pop(Item_list,0))
- self.NBONA = eval(Pop(Item_list,0))
- self.NTHETA = eval(Pop(Item_list,0))
- self.NPHIA = eval(Pop(Item_list,0))
- self.NUMBND = eval(Pop(Item_list,0))
- self.NUMANG = eval(Pop(Item_list,0))
- self.NPTRA = eval(Pop(Item_list,0))
- self.NATYP = eval(Pop(Item_list,0))
- self.NPHB = eval(Pop(Item_list,0))
- self.IFPERT = eval(Pop(Item_list,0))
- self.NBPER = eval(Pop(Item_list,0))
- self.NGPER = eval(Pop(Item_list,0))
- self.NDPER = eval(Pop(Item_list,0))
- self.MBPER = eval(Pop(Item_list,0))
- self.MGPER = eval(Pop(Item_list,0))
- self.MDPER = eval(Pop(Item_list,0))
- self.IFBOX = eval(Pop(Item_list,0))
- self.NMXRS = eval(Pop(Item_list,0))
- self.IFCAP = eval(Pop(Item_list,0))
-
- #....................................................
-
- if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \
- 2*(self.NRES + self.NUMBND + self.NUMANG) + \
- 3*self.NPTRA + self.NATYP:
- print '(error: File too short!)'
- return -1
-
- self.IGRAPH = []
- Pop(Item_list,0)
-
- # A little kludge is needed here, since the IGRAPH strings are
- # not separated by spaces if 4 characters in length.
- for i in range(self.NATOM):
- if len(Item_list[0]) > 4:
- Item_list.insert(1, Item_list[0][4:])
- Item_list.insert(1, Item_list[0][0:4])
- del Item_list[0]
- self.IGRAPH.append(Pop(Item_list,0))
-
- # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file.
- print 'Reading Charges...'
- self.CHRG = []
- for i in range(self.NATOM):
- self.CHRG.append(eval(Pop(Item_list,0)))
-
- print 'Reading Atomic Masses...'
- self.AMASS = []
- for i in range(self.NATOM):
- self.AMASS.append(eval(Pop(Item_list,0)))
-
- print 'Reading Atom Types...'
- self.IAC = []
- for i in range(self.NATOM):
- self.IAC.append(eval(Pop(Item_list,0)))
-
- print 'Reading Excluded Atoms...'
- self.NUMEX = []
- for i in range(self.NATOM):
- self.NUMEX.append(eval(Pop(Item_list,0)))
-
- print 'Reading Non-bonded Parameter Index...'
- self.ICO = []
- for i in range(self.NTYPES**2):
- self.ICO.append(eval(Pop(Item_list,0)))
-
- print 'Reading Residue Labels...'
- self.LABRES = []
- for i in range(self.NRES):
- self.LABRES.append(Pop(Item_list,0))
-
- print 'Reading Residues Starting Pointers...'
- self.IPRES = []
- for i in range(self.NRES):
- self.IPRES.append(eval(Pop(Item_list,0)))
-
- print 'Reading Bond Force Constants...'
- self.RK = []
- for i in range(self.NUMBND):
- self.RK.append(eval(Pop(Item_list,0)))
-
- print 'Reading Equilibrium Bond Values...'
- self.REQ = []
- for i in range(self.NUMBND):
- self.REQ.append(eval(Pop(Item_list,0)))
-
- print 'Reading Angle Force Constants...'
- self.TK = []
- for i in range(self.NUMANG):
- self.TK.append(eval(Pop(Item_list,0)))
-
- print 'Reading Equilibrium Angle Values...'
- self.TEQ = []
- for i in range(self.NUMANG):
- self.TEQ.append(eval(Pop(Item_list,0)))
-
- print 'Reading Dihedral Force Constants...'
- self.PK = []
- for i in range(self.NPTRA):
- self.PK.append(eval(Pop(Item_list,0)))
-
- print 'Reading Dihedral Periodicity...'
- self.PN = []
- for i in range(self.NPTRA):
- self.PN.append(eval(Pop(Item_list,0)))
-
- print 'Reading Dihedral Phase...'
- self.PHASE = []
- for i in range(self.NPTRA):
- self.PHASE.append(eval(Pop(Item_list,0)))
-
- print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though
- self.SOLTY = []
- for i in range(self.NATYP):
- self.SOLTY.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2:
- print '(error: File too short!)'
- return -1
-
- print 'Reading LJ A Coefficient...'
- self.CN1 = []
- for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
- self.CN1.append(eval(Pop(Item_list,0)))
-
- print 'Reading LJ B Coefficient...'
- self.CN2 = []
- for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
- self.CN2.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \
- 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA):
- print '(error: File too short!)'
- return -1
-
- print 'Reading Bonds which include hydrogen...'
- self.IBH = []
- self.JBH = []
- self.ICBH = []
- for i in range(self.NBONH):
- self.IBH.append(eval(Pop(Item_list,0)))
- self.JBH.append(eval(Pop(Item_list,0)))
- self.ICBH.append(eval(Pop(Item_list,0)))
-
- print 'Reading Bonds which dont include hydrogen...'
- self.IB = []
- self.JB = []
- self.ICB = []
- for i in range(self.NBONA):
- self.IB.append(eval(Pop(Item_list,0)))
- self.JB.append(eval(Pop(Item_list,0)))
- self.ICB.append(eval(Pop(Item_list,0)))
-
- print 'Reading Angles which include hydrogen...'
- self.ITH = []
- self.JTH = []
- self.KTH = []
- self.ICTH = []
- for i in range(self.NTHETH):
- self.ITH.append(eval(Pop(Item_list,0)))
- self.JTH.append(eval(Pop(Item_list,0)))
- self.KTH.append(eval(Pop(Item_list,0)))
- self.ICTH.append(eval(Pop(Item_list,0)))
-
- print 'Reading Angles which dont include hydrogen...'
- self.IT = []
- self.JT = []
- self.KT = []
- self.ICT = []
- for i in range(self.NTHETA):
- self.IT.append(eval(Pop(Item_list,0)))
- self.JT.append(eval(Pop(Item_list,0)))
- self.KT.append(eval(Pop(Item_list,0)))
- self.ICT.append(eval(Pop(Item_list,0)))
-
- print 'Reading Dihedrals which include hydrogen...'
- self.IPH = []
- self.JPH = []
- self.KPH = []
- self.LPH = []
- self.ICPH = []
- for i in range(self.NPHIH):
- self.IPH.append(eval(Pop(Item_list,0)))
- self.JPH.append(eval(Pop(Item_list,0)))
- self.KPH.append(eval(Pop(Item_list,0)))
- self.LPH.append(eval(Pop(Item_list,0)))
- self.ICPH.append(eval(Pop(Item_list,0)))
-
- print 'Reading Dihedrals which dont include hydrogen...'
- self.IP = []
- self.JP = []
- self.KP = []
- self.LP = []
- self.ICP = []
- for i in range(self.NPHIA):
- self.IP.append(eval(Pop(Item_list,0)))
- self.JP.append(eval(Pop(Item_list,0)))
- self.KP.append(eval(Pop(Item_list,0)))
- self.LP.append(eval(Pop(Item_list,0)))
- self.ICP.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM:
- print '(error: File too short!)'
- return -1
-
- print 'Reading Excluded Atom List...'
- self.NATEX = []
- for i in range(self.NEXT):
- self.NATEX.append(eval(Pop(Item_list,0)))
-
- print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...'
- self.ASOL = []
- for i in range(self.NPHB):
- self.ASOL.append(eval(Pop(Item_list,0)))
-
- print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...'
- self.BSOL = []
- for i in range(self.NPHB):
- self.BSOL.append(eval(Pop(Item_list,0)))
-
- print 'Reading H-Bond Cut...' # I think it is not being used nowadays
- self.HBCUT = []
- for i in range(self.NPHB):
- self.HBCUT.append(eval(Pop(Item_list,0)))
-
- print 'Reading Amber Atom Types for each atom...'
- self.ISYMBL = []
- for i in range(self.NATOM):
- self.ISYMBL.append(Pop(Item_list,0))
-
- print 'Reading Tree Chain Classification...'
- self.ITREE = []
- for i in range(self.NATOM):
- self.ITREE.append(Pop(Item_list,0))
-
- print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module
- self.JOIN = []
- for i in range(self.NATOM):
- self.JOIN.append(eval(Pop(Item_list,0)))
-
- print 'Reading IRotate...' # Currently unused in Sander and Gibbs
- self.IROTAT = []
- for i in range(self.NATOM):
- self.IROTAT.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if self.IFBOX > 0:
- if len(Item_list) < 3:
- print '(error: File too short!)'
- return -1
-
- print 'Reading final residue which is part of solute...'
- self.IPTRES = eval(Pop(Item_list,0))
- print 'Reading total number of molecules...'
- self.NSPM = eval(Pop(Item_list,0))
- print 'Reading first solvent moleule index...'
- self.NSPSOL = eval(Pop(Item_list,0))
-
- if len(Item_list) < self.NSPM + 4:
- print '(error: File too short!)'
- return -1
-
- print 'Reading atom per molecule...'
- self.NSP = []
- for i in range(self.NSPM):
- self.NSP.append(eval(Pop(Item_list,0)))
-
- self.BETA = eval(Pop(Item_list,0))
-
- print 'Reading Box Dimensions...'
- if self.__dict__.has_key('BOX'):
- BOX = []
- for i in range(3):
- BOX.append(eval(Pop(Item_list,0)))
- for i in range(3):
- if BOX[i] != self.BOX[i]:
- print '(warning: BOX differs!)',
- break
- del BOX
- else:
- self.BOX = []
- for i in range(3):
- self.BOX.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if self.IFCAP > 0:
- if len(Item_list) < 5:
- print '(error: File too short!)'
- return -1
- print 'Reading ICAP variables::: For details, refer to online AMBER format manual'
- self.NATCAP = eval(Pop(Item_list,0))
- self.CUTCAP = eval(Pop(Item_list,0))
- self.XCAP = eval(Pop(Item_list,0))
- self.YCAP = eval(Pop(Item_list,0))
- self.ZCAP = eval(Pop(Item_list,0))
-
- #....................................................
-
- if self.IFPERT > 0:
- if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \
- 6 * self.NDPER + self.NRES + 6 * self.NATOM:
- print '(error: File too short!)'
- return -1
-
- print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual'
- self.IBPER = []
- self.JBPER = []
- for i in range(self.NBPER):
- self.IBPER.append(eval(Pop(Item_list,0)))
- self.JBPER.append(eval(Pop(Item_list,0)))
-
- self.ICBPER = []
- for i in range(2 * self.NBPER):
- self.ICBPER.append(eval(Pop(Item_list,0)))
-
- self.ITPER = []
- self.JTPER = []
- self.KTPER = []
- for i in range(self.NGPER):
- self.ITPER.append(eval(Pop(Item_list,0)))
- self.JTPER.append(eval(Pop(Item_list,0)))
- self.KTPER.append(eval(Pop(Item_list,0)))
-
- self.ICTPER = []
- for i in range(2 * self.NGPER):
- self.ICTPER.append(eval(Pop(Item_list,0)))
-
- self.IPPER = []
- self.JPPER = []
- self.KPPER = []
- self.LPPER = []
- for i in range(self.NDPER):
- self.IPPER.append(eval(Pop(Item_list,0)))
- self.JPPER.append(eval(Pop(Item_list,0)))
- self.KPPER.append(eval(Pop(Item_list,0)))
- self.LPPER.append(eval(Pop(Item_list,0)))
-
- self.ICPPER = []
- for i in range(2 * self.NDPER):
- self.ICPPER.append(eval(Pop(Item_list,0)))
-
- LABRES = []
- for i in range(self.NRES):
- LABRES.append(Pop(Item_list,0))
- for i in range(self.NRES):
- if LABRES[i] != self.LABRES[i]:
- print '(warning: BOX differs!)',
- break
-
- self.IGRPER = []
- for i in range(self.NATOM):
- self.IGRPER.append(eval(Pop(Item_list,0)))
-
- self.ISMPER = []
- for i in range(self.NATOM):
- self.ISMPER.append(eval(Pop(Item_list,0)))
-
- self.ALMPER = []
- for i in range(self.NATOM):
- self.ALMPER.append(eval(Pop(Item_list,0)))
-
- self.IAPER = []
- for i in range(self.NATOM):
- self.IAPER.append(eval(Pop(Item_list,0)))
-
- self.IACPER = []
- for i in range(self.NATOM):
- self.IACPER.append(eval(Pop(Item_list,0)))
-
- self.CGPER = []
- for i in range(self.NATOM):
- self.CGPER.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- self.IPOL = 0
- if self.IPOL == 1:
- if len(Item_list) < self.NATOM:
- print '(error: File too short!)'
- return -1
- print 'Reading Polarizability Data. For details, refer to online AMBER format manual'
- self.ATPOL = []
- for i in range(self.NATOM):
- self.ATPOL.append(eval(Pop(Item_list,0)))
-
- if self.IFPERT == 1:
- if len(Item_list) < self.NATOM:
- print '(error: File too short!)'
- return -1
- self.ATPOL1 = []
- for i in range(self.NATOM):
- self.ATPOL1.append(eval(Pop(Item_list,0)))
-
- #....................................................
-
- if len(Item_list):
- print '(warning: File too large!)',
-
- print 'done.'
- self.TOP_is_read = 1
-
-#============================================================
-
-def Find_Amber_files():
- 'Look for sets of Amber files to process'
- '''If not passed anything on the command line, look for pairs of
- Amber files (.crd and .top) in the current directory. For
- each set if there is no corresponding Lammps file (data.), or it is
- older than any of the Amber files, add its basename to a list of
- strings. This list is returned by the function'''
-
- # Date and existence checks not yet implemented
-
- import os, sys
-
- Basename_list = []
-
- # Extract basenames from command line
- for Name in sys.argv[1:]:
- if Name[-4:] == '.crd':
- Basename_list.append(Name[:-4])
- else:
- if Name[-4:] == '.top':
- Basename_list.append(Name[:-4])
- else:
- Basename_list.append(Name)
-
- # Remove duplicate basenames
- for Basename in Basename_list[:]:
- while Basename_list.count(Basename) > 1:
- Basename_list.remove(Basename)
-
- if Basename_list == []:
- print 'Looking for Amber files...',
- Dir_list = os.listdir('.')
- Dir_list.sort()
- for File in Dir_list:
- if File[-4:] == '.top':
- Basename = File[:-4]
- if (Basename + '.crd') in Dir_list:
- Basename_list.append(Basename)
- if Basename_list != []:
- print 'found',
- for i in range(len(Basename_list)-1):
- print Basename_list[i] + ',',
- print Basename_list[-1] + '\n'
-
- if Basename_list == []:
- print 'none.\n'
-
- return Basename_list
-
-#============================================================
-
-def Convert_Amber_files():
- 'Handle the whole conversion process'
- print
- print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!'
- print
- Basename_list = Find_Amber_files()
- for Basename in Basename_list:
- a = Amber()
- a.Read_CRD(Basename)
- if a.CRD_is_read:
- a.Read_TOP(Basename)
- if a.TOP_is_read:
- l = a.Coerce_to_Lammps()
- l.Write_Lammps(Basename)
- del l
- del a
- print
-
-#============================================================
-
-Convert_Amber_files()
+#! /usr/bin/python
+
+#
+# This is amber2lammps, a program written by Keir E. Novik to convert
+# Amber files to Lammps files.
+#
+# Copyright 1999, 2000 Keir E. Novik; all rights reserved.
+#
+# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README
+# Bug Fixed :Third argument in Dihedral Coeffs section is an integer - Ketan S Khare September 26, 2011
+
+#============================================================
+
+def Pop(S, I=-1):
+ 'Pop item I from list'
+ X = S[I]
+ del S[I]
+ return X
+
+#============================================================
+
+class Lammps:
+
+ #--------------------------------------------------------
+
+ def Dump(self):
+ 'Write out contents of self (intended for debugging)'
+ Name_list = self.__dict__.keys()
+ Name_list.sort()
+ for Name in Name_list:
+ print Name + ':', self.__dict__[Name]
+
+ #--------------------------------------------------------
+
+ def Write_data(self, Basename, Item_list):
+ 'Write the Lammps data to file (used by Write_Lammps)'
+ import os, sys
+
+ Filename = 'data.' + Basename
+
+ Dir_list = os.listdir('.')
+ i = 1
+ while Filename in Dir_list:
+ Filename = 'data' + `i` + '.' + Basename
+ i = i +1
+ del i
+
+ print 'Writing', Filename + '...',
+ sys.stdout.flush()
+
+ try:
+ F = open(Filename, 'w')
+ except IOError, Detail:
+ print '(error:', Detail[1] + '!)'
+ return
+
+ try:
+ F.writelines(Item_list)
+ except IOError, Detail:
+ print '(error:', Detail[1] + '!)'
+ F.close()
+ return
+
+ F.close()
+ print 'done.'
+
+ #--------------------------------------------------------
+
+ def Write_Lammps(self, Basename):
+ 'Write the Lammps data file, ignoring blank sections'
+ import string
+ L = []
+
+ L.append('LAMMPS data file for ' + self.name + '\n\n')
+
+ L.append(`self.atoms` + ' atoms\n')
+ L.append(`self.bonds` + ' bonds\n')
+ L.append(`self.angles` + ' angles\n')
+ L.append(`self.dihedrals` + ' dihedrals\n')
+ L.append(`self.impropers` + ' impropers\n\n')
+
+ L.append(`self.atom_types` + ' atom types\n')
+ if self.bonds > 0:
+ L.append(`self.bond_types` + ' bond types\n')
+ if self.angles > 0:
+ L.append(`self.angle_types` + ' angle types\n')
+ if self.dihedrals > 0:
+ L.append(`self.dihedral_types` + ' dihedral types\n')
+ L.append('\n')
+
+ L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n')
+ L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n')
+ L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n')
+
+ if self.atom_types != 0:
+ L.append('Masses\n\n')
+ for i in range(self.atom_types):
+ L.append(`i+1` + ' ' + `self.Masses[i]` + '\n')
+ L.append('\n')
+
+ L.append('Pair Coeffs\n\n')
+ for i in range(self.atom_types):
+ L.append(`i+1`)
+ for j in range(len(self.Nonbond_Coeffs[0])):
+ L.append(' ' + `self.Nonbond_Coeffs[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.bonds != 0 and self.bond_types != 0:
+ L.append('Bond Coeffs\n\n')
+ for i in range(self.bond_types):
+ L.append(`i+1`)
+ for j in range(len(self.Bond_Coeffs[0])):
+ L.append(' ' + `self.Bond_Coeffs[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.angles != 0 and self.angle_types != 0:
+ L.append('Angle Coeffs\n\n')
+ for i in range(self.angle_types):
+ L.append(`i+1`)
+ for j in range(len(self.Angle_Coeffs[0])):
+ L.append(' ' + `self.Angle_Coeffs[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.dihedrals != 0 and self.dihedral_types != 0:
+ L.append('Dihedral Coeffs\n\n')
+ for i in range(self.dihedral_types):
+ L.append(`i+1`)
+ for j in range(len(self.Dihedral_Coeffs[0])):
+ L.append(' ' + `self.Dihedral_Coeffs[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.atoms != 0:
+ L.append('Atoms\n\n')
+ for i in range(self.atoms):
+ L.append(`i+1`)
+ for j in range(len(self.Atoms[0])):
+ L.append(' ' + `self.Atoms[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.bonds != 0 and self.bond_types != 0:
+ L.append('Bonds\n\n')
+ for i in range(self.bonds):
+ L.append(`i+1`)
+ for j in range(len(self.Bonds[0])):
+ L.append(' ' + `self.Bonds[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.angles != 0 and self.angle_types != 0:
+ L.append('Angles\n\n')
+ for i in range(self.angles):
+ L.append(`i+1`)
+ for j in range(len(self.Angles[0])):
+ L.append(' ' + `self.Angles[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ if self.dihedrals != 0 and self.dihedral_types != 0:
+ L.append('Dihedrals\n\n')
+ for i in range(self.dihedrals):
+ L.append(`i+1`)
+ for j in range(len(self.Dihedrals[0])):
+ L.append(' ' + `self.Dihedrals[i][j]`)
+ L.append('\n')
+ L.append('\n')
+
+ self.Write_data(Basename, L)
+
+#============================================================
+
+class Amber:
+ def __init__(self):
+ 'Initialise the Amber class'
+ self.CRD_is_read = 0
+ self.TOP_is_read = 0
+
+ #--------------------------------------------------------
+
+ def Dump(self):
+ 'Write out contents of self (intended for debugging)'
+ Name_list = self.__dict__.keys()
+ Name_list.sort()
+ for Name in Name_list:
+ print Name + ':', self.__dict__[Name]
+
+ #--------------------------------------------------------
+
+ def Coerce_to_Lammps(self):
+ 'Return the Amber data converted to Lammps format'
+
+ import math
+
+ if self.CRD_is_read and self.TOP_is_read:
+ l = Lammps()
+ print 'Converting...',
+
+ l.name = self.ITITL
+ l.atoms = self.NATOM
+ l.bonds = self.NBONH + self.MBONA
+ l.angles = self.NTHETH + self.MTHETA
+ l.dihedrals = self.NPHIH + self.MPHIA
+ l.impropers = 0
+ l.atom_types = self.NTYPES
+ l.bond_types = self.NUMBND
+ l.angle_types = self.NUMANG
+ l.dihedral_types = self.NPTRA
+
+ Shift = 0
+ if self.__dict__.has_key('BOX'):
+ l.xlo = 0.0
+ l.xhi = self.BOX[0]
+ l.ylo = 0.0
+ l.yhi = self.BOX[1]
+ l.zlo = 0.0
+ l.zhi = self.BOX[2]
+ if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \
+ (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \
+ (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)):
+ # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS
+ # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box,
+ # please uncomment the below 2 lines.
+ print '(warning: Currently not shifting the atoms to the periodic box)'
+ #Shift = 1
+ else:
+ print '(warning: Guessing at periodic box!)',
+ l.xlo = min(self.X)
+ l.xhi = max(self.X)
+ l.ylo = min(self.Y)
+ l.yhi = max(self.Y)
+ l.zlo = min(self.Z)
+ l.zhi = max(self.Z)
+
+ # This doesn't check duplicate values
+ l.Masses = []
+ for i in range(l.atom_types):
+ l.Masses.append(0)
+ for i in range(self.NATOM):
+ l.Masses[self.IAC[i] - 1] = self.AMASS[i]
+
+ l.Nonbond_Coeffs = []
+ for i in range(self.NTYPES):
+ l.Nonbond_Coeffs.append([0,0])
+ for i in range(self.NTYPES):
+ j = self.ICO[i * (self.NTYPES + 1)] - 1
+ if self.CN1[j] == 0.0:
+ l.Nonbond_Coeffs[i][0] = 0.0
+ else:
+ l.Nonbond_Coeffs[i][0] = \
+ 0.25 * (self.CN2[j])**2 / self.CN1[j]
+ if self.CN2[j] == 0.0:
+ l.Nonbond_Coeffs[i][1] = 0.0
+ else:
+ l.Nonbond_Coeffs[i][1] = \
+ (self.CN1[j] / self.CN2[j])**(1.0/6.0)
+
+ l.Bond_Coeffs = []
+ for i in range(self.NUMBND):
+ l.Bond_Coeffs.append([0,0])
+ for i in range(self.NUMBND):
+ l.Bond_Coeffs[i][0] = self.RK[i]
+ l.Bond_Coeffs[i][1] = self.REQ[i]
+
+ l.Angle_Coeffs = []
+ for i in range(self.NUMANG):
+ l.Angle_Coeffs.append([0,0])
+ for i in range(self.NUMANG):
+ l.Angle_Coeffs[i][0] = self.TK[i]
+ l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i]
+
+ l.Dihedral_Coeffs = []
+ for i in range(self.NPTRA):
+ l.Dihedral_Coeffs.append([0,0,0])
+ for i in range(self.NPTRA):
+ l.Dihedral_Coeffs[i][0] = self.PK[i]
+ if self.PHASE[i] == 0:
+ l.Dihedral_Coeffs[i][1] = 1
+ else:
+ l.Dihedral_Coeffs[i][1] = -1
+ l.Dihedral_Coeffs[i][2] = int(self.PN[i])
+
+ l.Atoms = []
+ for i in range(self.NATOM):
+ x = self.X[i]
+ y = self.Y[i]
+ z = self.Z[i]
+ if Shift:
+ while x < l.xlo:
+ x = x + self.BOX[0]
+ while x > l.xhi:
+ x = x - self.BOX[0]
+ while y < l.ylo:
+ y = y + self.BOX[1]
+ while y > l.yhi:
+ y = y - self.BOX[1]
+ while z < l.zlo:
+ z = z + self.BOX[2]
+ while z > l.zhi:
+ z = z - self.BOX[2]
+ l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \
+ x, y, z])
+
+ l.Bonds = []
+ for i in range(l.bonds):
+ l.Bonds.append([0,0,0])
+ for i in range(self.NBONH):
+ l.Bonds[i][0] = self.ICBH[i]
+ l.Bonds[i][1] = abs(self.IBH[i])/3 + 1
+ l.Bonds[i][2] = abs(self.JBH[i])/3 + 1
+ for i in range(self.NBONA):
+ l.Bonds[self.NBONH + i][0] = self.ICB[i]
+ l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1
+ l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1
+
+ l.Angles = []
+ for i in range(l.angles):
+ l.Angles.append([0,0,0,0])
+ for i in range(self.NTHETH):
+ l.Angles[i][0] = self.ICTH[i]
+ l.Angles[i][1] = abs(self.ITH[i])/3 + 1
+ l.Angles[i][2] = abs(self.JTH[i])/3 + 1
+ l.Angles[i][3] = abs(self.KTH[i])/3 + 1
+ for i in range(self.NTHETA):
+ l.Angles[self.NTHETH + i][0] = self.ICT[i]
+ l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1
+ l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1
+ l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1
+
+ l.Dihedrals = []
+ for i in range(l.dihedrals):
+ l.Dihedrals.append([0,0,0,0,0])
+ for i in range(self.NPHIH):
+ l.Dihedrals[i][0] = self.ICPH[i]
+ l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1
+ l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1
+ l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1
+ l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1
+ for i in range(self.NPHIA):
+ l.Dihedrals[self.NPHIH + i][0] = self.ICP[i]
+ l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1
+ l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1
+ l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1
+ l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1
+
+ print 'done.'
+ return l
+ else:
+ print '(Error: Not all the Amber data has been read!)'
+
+ #--------------------------------------------------------
+
+ def Read_data(self, Filename):
+ 'Read the filename, returning a list of strings'
+
+ import string, sys
+
+ print 'Reading', Filename + '...',
+ sys.stdout.flush()
+
+ try:
+ F = open(Filename)
+ except IOError, Detail:
+ print '(error:', Detail[1] + '!)'
+ return
+
+ try:
+ Lines = F.readlines()
+ except IOError, Detail:
+ print '(error:', Detail[1] + '!)'
+ F.close()
+ return
+
+ F.close()
+
+ # If the first line is empty, use the Basename
+ if Filename[-4:] == '.crd':
+ if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file
+ Basename = Filename[:string.find(Filename, '.')]
+ Item_list = [Basename]
+ print 'Warning: Title not present... Assigning Basename as Title'
+ else:
+ Item_list = []
+ else:
+ if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file
+ Basename = Filename[:string.find(Filename, '.')]
+ Item_list = [Basename]
+ print 'Warning: Title not present... Assigning Basename as Title'
+ else:
+ Item_list = []
+
+ for Line in Lines:
+ if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file.
+ Item_list.extend(string.split(Line))
+
+ return Item_list
+
+ #--------------------------------------------------------
+
+ def Read_CRD(self, Basename):
+ 'Read the Amber coordinate/restart (.crd) file'
+
+ # The optional velocities and periodic box size are not yet parsed.
+
+ Item_list = self.Read_data(Basename + '.crd')
+
+ if Item_list == None:
+ return
+ elif len(Item_list) < 2:
+ print '(error: File too short!)'
+ return
+
+ # Parse the data
+ if self.__dict__.has_key('ITITL'):
+ if Pop(Item_list,0) != self.ITITL:
+ print '(warning: ITITL differs!)',
+ else:
+ self.ITITL = Pop(Item_list,0)
+ print self.ITITL #Vikas Modification : Priting the Title
+
+ if self.__dict__.has_key('NATOM'):
+ if eval(Pop(Item_list,0)) != self.NATOM:
+ print '(error: NATOM differs!)'
+ return
+ else:
+ self.NATOM = eval(Pop(Item_list,0))
+ print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value.
+
+ #if len(Item_list) == 1 + 3 * self.NATOM:
+ # Vikas' Modification: I changed the condition.
+ if (len(Item_list)%3) != 0:
+ self.TIME = eval(Pop(Item_list,0))
+ else:
+ self.TIME = 0
+ print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value.
+ if len(Item_list) < 3 * self.NATOM:
+ print '(error: File too short!)'
+ return
+
+ self.X = []
+ self.Y = []
+ self.Z = []
+ for i in range(self.NATOM):
+ self.X.append(eval(Pop(Item_list,0)))
+ self.Y.append(eval(Pop(Item_list,0)))
+ self.Z.append(eval(Pop(Item_list,0)))
+
+ if (self.NATOM == 1) and len(Item_list):
+ print '(warning: Ambiguity!)',
+
+ if len(Item_list) >= 3 * self.NATOM:
+ self.VX = []
+ self.VY = []
+ self.VZ = []
+ for i in range(self.NATOM):
+ self.VX.append(eval(Pop(Item_list,0)))
+ self.VY.append(eval(Pop(Item_list,0)))
+ self.VZ.append(eval(Pop(Item_list,0)))
+
+ if len(Item_list) >= 3:
+ self.BOX = []
+ for i in range(3):
+ self.BOX.append(eval(Pop(Item_list,0)))
+
+ if len(Item_list):
+ print '(warning: File too large!)',
+
+ print 'done.'
+ self.CRD_is_read = 1
+
+ #--------------------------------------------------------
+
+ def Read_TOP(self, Basename):
+ 'Read the Amber parameter/topology (.top) file'
+ Item_list = self.Read_data(Basename + '.top')
+
+ if Item_list == None:
+ return
+ elif len(Item_list) < 31:
+ print '(error: File too short!)'
+ return
+
+ # Parse the data
+ if self.__dict__.has_key('ITITL'):
+ if Pop(Item_list,0) != self.ITITL:
+ print '(warning: ITITL differs!)'
+ else:
+ self.ITITL = Pop(Item_list,0)
+ print self.ITITL # Printing Self Title
+
+ if self.__dict__.has_key('NATOM'):
+ if eval(Pop(Item_list,0)) != self.NATOM:
+ print '(error: NATOM differs!)'
+ return
+ else:
+ self.NATOM = eval(Pop(Item_list,0))
+ print self.NATOM # Printing total number of atoms just to make sure that thing are going right
+ self.NTYPES = eval(Pop(Item_list,0))
+ self.NBONH = eval(Pop(Item_list,0))
+ self.MBONA = eval(Pop(Item_list,0))
+ self.NTHETH = eval(Pop(Item_list,0))
+ self.MTHETA = eval(Pop(Item_list,0))
+ self.NPHIH = eval(Pop(Item_list,0))
+ self.MPHIA = eval(Pop(Item_list,0))
+ self.NHPARM = eval(Pop(Item_list,0))
+ self.NPARM = eval(Pop(Item_list,0))
+ self.NEXT = eval(Pop(Item_list,0))
+ self.NRES = eval(Pop(Item_list,0))
+ self.NBONA = eval(Pop(Item_list,0))
+ self.NTHETA = eval(Pop(Item_list,0))
+ self.NPHIA = eval(Pop(Item_list,0))
+ self.NUMBND = eval(Pop(Item_list,0))
+ self.NUMANG = eval(Pop(Item_list,0))
+ self.NPTRA = eval(Pop(Item_list,0))
+ self.NATYP = eval(Pop(Item_list,0))
+ self.NPHB = eval(Pop(Item_list,0))
+ self.IFPERT = eval(Pop(Item_list,0))
+ self.NBPER = eval(Pop(Item_list,0))
+ self.NGPER = eval(Pop(Item_list,0))
+ self.NDPER = eval(Pop(Item_list,0))
+ self.MBPER = eval(Pop(Item_list,0))
+ self.MGPER = eval(Pop(Item_list,0))
+ self.MDPER = eval(Pop(Item_list,0))
+ self.IFBOX = eval(Pop(Item_list,0))
+ self.NMXRS = eval(Pop(Item_list,0))
+ self.IFCAP = eval(Pop(Item_list,0))
+
+ #....................................................
+
+ if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \
+ 2*(self.NRES + self.NUMBND + self.NUMANG) + \
+ 3*self.NPTRA + self.NATYP:
+ print '(error: File too short!)'
+ return -1
+
+ self.IGRAPH = []
+ Pop(Item_list,0)
+
+ # A little kludge is needed here, since the IGRAPH strings are
+ # not separated by spaces if 4 characters in length.
+ for i in range(self.NATOM):
+ if len(Item_list[0]) > 4:
+ Item_list.insert(1, Item_list[0][4:])
+ Item_list.insert(1, Item_list[0][0:4])
+ del Item_list[0]
+ self.IGRAPH.append(Pop(Item_list,0))
+
+ # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file.
+ print 'Reading Charges...'
+ self.CHRG = []
+ for i in range(self.NATOM):
+ self.CHRG.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Atomic Masses...'
+ self.AMASS = []
+ for i in range(self.NATOM):
+ self.AMASS.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Atom Types...'
+ self.IAC = []
+ for i in range(self.NATOM):
+ self.IAC.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Excluded Atoms...'
+ self.NUMEX = []
+ for i in range(self.NATOM):
+ self.NUMEX.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Non-bonded Parameter Index...'
+ self.ICO = []
+ for i in range(self.NTYPES**2):
+ self.ICO.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Residue Labels...'
+ self.LABRES = []
+ for i in range(self.NRES):
+ self.LABRES.append(Pop(Item_list,0))
+
+ print 'Reading Residues Starting Pointers...'
+ self.IPRES = []
+ for i in range(self.NRES):
+ self.IPRES.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Bond Force Constants...'
+ self.RK = []
+ for i in range(self.NUMBND):
+ self.RK.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Equilibrium Bond Values...'
+ self.REQ = []
+ for i in range(self.NUMBND):
+ self.REQ.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Angle Force Constants...'
+ self.TK = []
+ for i in range(self.NUMANG):
+ self.TK.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Equilibrium Angle Values...'
+ self.TEQ = []
+ for i in range(self.NUMANG):
+ self.TEQ.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Dihedral Force Constants...'
+ self.PK = []
+ for i in range(self.NPTRA):
+ self.PK.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Dihedral Periodicity...'
+ self.PN = []
+ for i in range(self.NPTRA):
+ self.PN.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Dihedral Phase...'
+ self.PHASE = []
+ for i in range(self.NPTRA):
+ self.PHASE.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though
+ self.SOLTY = []
+ for i in range(self.NATYP):
+ self.SOLTY.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2:
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading LJ A Coefficient...'
+ self.CN1 = []
+ for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
+ self.CN1.append(eval(Pop(Item_list,0)))
+
+ print 'Reading LJ B Coefficient...'
+ self.CN2 = []
+ for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
+ self.CN2.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \
+ 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA):
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading Bonds which include hydrogen...'
+ self.IBH = []
+ self.JBH = []
+ self.ICBH = []
+ for i in range(self.NBONH):
+ self.IBH.append(eval(Pop(Item_list,0)))
+ self.JBH.append(eval(Pop(Item_list,0)))
+ self.ICBH.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Bonds which dont include hydrogen...'
+ self.IB = []
+ self.JB = []
+ self.ICB = []
+ for i in range(self.NBONA):
+ self.IB.append(eval(Pop(Item_list,0)))
+ self.JB.append(eval(Pop(Item_list,0)))
+ self.ICB.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Angles which include hydrogen...'
+ self.ITH = []
+ self.JTH = []
+ self.KTH = []
+ self.ICTH = []
+ for i in range(self.NTHETH):
+ self.ITH.append(eval(Pop(Item_list,0)))
+ self.JTH.append(eval(Pop(Item_list,0)))
+ self.KTH.append(eval(Pop(Item_list,0)))
+ self.ICTH.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Angles which dont include hydrogen...'
+ self.IT = []
+ self.JT = []
+ self.KT = []
+ self.ICT = []
+ for i in range(self.NTHETA):
+ self.IT.append(eval(Pop(Item_list,0)))
+ self.JT.append(eval(Pop(Item_list,0)))
+ self.KT.append(eval(Pop(Item_list,0)))
+ self.ICT.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Dihedrals which include hydrogen...'
+ self.IPH = []
+ self.JPH = []
+ self.KPH = []
+ self.LPH = []
+ self.ICPH = []
+ for i in range(self.NPHIH):
+ self.IPH.append(eval(Pop(Item_list,0)))
+ self.JPH.append(eval(Pop(Item_list,0)))
+ self.KPH.append(eval(Pop(Item_list,0)))
+ self.LPH.append(eval(Pop(Item_list,0)))
+ self.ICPH.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Dihedrals which dont include hydrogen...'
+ self.IP = []
+ self.JP = []
+ self.KP = []
+ self.LP = []
+ self.ICP = []
+ for i in range(self.NPHIA):
+ self.IP.append(eval(Pop(Item_list,0)))
+ self.JP.append(eval(Pop(Item_list,0)))
+ self.KP.append(eval(Pop(Item_list,0)))
+ self.LP.append(eval(Pop(Item_list,0)))
+ self.ICP.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM:
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading Excluded Atom List...'
+ self.NATEX = []
+ for i in range(self.NEXT):
+ self.NATEX.append(eval(Pop(Item_list,0)))
+
+ print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...'
+ self.ASOL = []
+ for i in range(self.NPHB):
+ self.ASOL.append(eval(Pop(Item_list,0)))
+
+ print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...'
+ self.BSOL = []
+ for i in range(self.NPHB):
+ self.BSOL.append(eval(Pop(Item_list,0)))
+
+ print 'Reading H-Bond Cut...' # I think it is not being used nowadays
+ self.HBCUT = []
+ for i in range(self.NPHB):
+ self.HBCUT.append(eval(Pop(Item_list,0)))
+
+ print 'Reading Amber Atom Types for each atom...'
+ self.ISYMBL = []
+ for i in range(self.NATOM):
+ self.ISYMBL.append(Pop(Item_list,0))
+
+ print 'Reading Tree Chain Classification...'
+ self.ITREE = []
+ for i in range(self.NATOM):
+ self.ITREE.append(Pop(Item_list,0))
+
+ print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module
+ self.JOIN = []
+ for i in range(self.NATOM):
+ self.JOIN.append(eval(Pop(Item_list,0)))
+
+ print 'Reading IRotate...' # Currently unused in Sander and Gibbs
+ self.IROTAT = []
+ for i in range(self.NATOM):
+ self.IROTAT.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if self.IFBOX > 0:
+ if len(Item_list) < 3:
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading final residue which is part of solute...'
+ self.IPTRES = eval(Pop(Item_list,0))
+ print 'Reading total number of molecules...'
+ self.NSPM = eval(Pop(Item_list,0))
+ print 'Reading first solvent moleule index...'
+ self.NSPSOL = eval(Pop(Item_list,0))
+
+ if len(Item_list) < self.NSPM + 4:
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading atom per molecule...'
+ self.NSP = []
+ for i in range(self.NSPM):
+ self.NSP.append(eval(Pop(Item_list,0)))
+
+ self.BETA = eval(Pop(Item_list,0))
+
+ print 'Reading Box Dimensions...'
+ if self.__dict__.has_key('BOX'):
+ BOX = []
+ for i in range(3):
+ BOX.append(eval(Pop(Item_list,0)))
+ for i in range(3):
+ if BOX[i] != self.BOX[i]:
+ print '(warning: BOX differs!)',
+ break
+ del BOX
+ else:
+ self.BOX = []
+ for i in range(3):
+ self.BOX.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if self.IFCAP > 0:
+ if len(Item_list) < 5:
+ print '(error: File too short!)'
+ return -1
+ print 'Reading ICAP variables::: For details, refer to online AMBER format manual'
+ self.NATCAP = eval(Pop(Item_list,0))
+ self.CUTCAP = eval(Pop(Item_list,0))
+ self.XCAP = eval(Pop(Item_list,0))
+ self.YCAP = eval(Pop(Item_list,0))
+ self.ZCAP = eval(Pop(Item_list,0))
+
+ #....................................................
+
+ if self.IFPERT > 0:
+ if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \
+ 6 * self.NDPER + self.NRES + 6 * self.NATOM:
+ print '(error: File too short!)'
+ return -1
+
+ print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual'
+ self.IBPER = []
+ self.JBPER = []
+ for i in range(self.NBPER):
+ self.IBPER.append(eval(Pop(Item_list,0)))
+ self.JBPER.append(eval(Pop(Item_list,0)))
+
+ self.ICBPER = []
+ for i in range(2 * self.NBPER):
+ self.ICBPER.append(eval(Pop(Item_list,0)))
+
+ self.ITPER = []
+ self.JTPER = []
+ self.KTPER = []
+ for i in range(self.NGPER):
+ self.ITPER.append(eval(Pop(Item_list,0)))
+ self.JTPER.append(eval(Pop(Item_list,0)))
+ self.KTPER.append(eval(Pop(Item_list,0)))
+
+ self.ICTPER = []
+ for i in range(2 * self.NGPER):
+ self.ICTPER.append(eval(Pop(Item_list,0)))
+
+ self.IPPER = []
+ self.JPPER = []
+ self.KPPER = []
+ self.LPPER = []
+ for i in range(self.NDPER):
+ self.IPPER.append(eval(Pop(Item_list,0)))
+ self.JPPER.append(eval(Pop(Item_list,0)))
+ self.KPPER.append(eval(Pop(Item_list,0)))
+ self.LPPER.append(eval(Pop(Item_list,0)))
+
+ self.ICPPER = []
+ for i in range(2 * self.NDPER):
+ self.ICPPER.append(eval(Pop(Item_list,0)))
+
+ LABRES = []
+ for i in range(self.NRES):
+ LABRES.append(Pop(Item_list,0))
+ for i in range(self.NRES):
+ if LABRES[i] != self.LABRES[i]:
+ print '(warning: BOX differs!)',
+ break
+
+ self.IGRPER = []
+ for i in range(self.NATOM):
+ self.IGRPER.append(eval(Pop(Item_list,0)))
+
+ self.ISMPER = []
+ for i in range(self.NATOM):
+ self.ISMPER.append(eval(Pop(Item_list,0)))
+
+ self.ALMPER = []
+ for i in range(self.NATOM):
+ self.ALMPER.append(eval(Pop(Item_list,0)))
+
+ self.IAPER = []
+ for i in range(self.NATOM):
+ self.IAPER.append(eval(Pop(Item_list,0)))
+
+ self.IACPER = []
+ for i in range(self.NATOM):
+ self.IACPER.append(eval(Pop(Item_list,0)))
+
+ self.CGPER = []
+ for i in range(self.NATOM):
+ self.CGPER.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ self.IPOL = 0
+ if self.IPOL == 1:
+ if len(Item_list) < self.NATOM:
+ print '(error: File too short!)'
+ return -1
+ print 'Reading Polarizability Data. For details, refer to online AMBER format manual'
+ self.ATPOL = []
+ for i in range(self.NATOM):
+ self.ATPOL.append(eval(Pop(Item_list,0)))
+
+ if self.IFPERT == 1:
+ if len(Item_list) < self.NATOM:
+ print '(error: File too short!)'
+ return -1
+ self.ATPOL1 = []
+ for i in range(self.NATOM):
+ self.ATPOL1.append(eval(Pop(Item_list,0)))
+
+ #....................................................
+
+ if len(Item_list):
+ print '(warning: File too large!)',
+
+ print 'done.'
+ self.TOP_is_read = 1
+
+#============================================================
+
+def Find_Amber_files():
+ 'Look for sets of Amber files to process'
+ '''If not passed anything on the command line, look for pairs of
+ Amber files (.crd and .top) in the current directory. For
+ each set if there is no corresponding Lammps file (data.), or it is
+ older than any of the Amber files, add its basename to a list of
+ strings. This list is returned by the function'''
+
+ # Date and existence checks not yet implemented
+
+ import os, sys
+
+ Basename_list = []
+
+ # Extract basenames from command line
+ for Name in sys.argv[1:]:
+ if Name[-4:] == '.crd':
+ Basename_list.append(Name[:-4])
+ else:
+ if Name[-4:] == '.top':
+ Basename_list.append(Name[:-4])
+ else:
+ Basename_list.append(Name)
+
+ # Remove duplicate basenames
+ for Basename in Basename_list[:]:
+ while Basename_list.count(Basename) > 1:
+ Basename_list.remove(Basename)
+
+ if Basename_list == []:
+ print 'Looking for Amber files...',
+ Dir_list = os.listdir('.')
+ Dir_list.sort()
+ for File in Dir_list:
+ if File[-4:] == '.top':
+ Basename = File[:-4]
+ if (Basename + '.crd') in Dir_list:
+ Basename_list.append(Basename)
+ if Basename_list != []:
+ print 'found',
+ for i in range(len(Basename_list)-1):
+ print Basename_list[i] + ',',
+ print Basename_list[-1] + '\n'
+
+ if Basename_list == []:
+ print 'none.\n'
+
+ return Basename_list
+
+#============================================================
+
+def Convert_Amber_files():
+ 'Handle the whole conversion process'
+ print
+ print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!'
+ print
+ Basename_list = Find_Amber_files()
+ for Basename in Basename_list:
+ a = Amber()
+ a.Read_CRD(Basename)
+ if a.CRD_is_read:
+ a.Read_TOP(Basename)
+ if a.TOP_is_read:
+ l = a.Coerce_to_Lammps()
+ l.Write_Lammps(Basename)
+ del l
+ del a
+ print
+
+#============================================================
+
+Convert_Amber_files()
From c8fa1bd5df840960f1692c3756017cb689bfd816 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Fri, 7 Oct 2011 23:50:07 +0000
Subject: [PATCH 03/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7047
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/MANYBODY/pair_comb.cpp | 238 ++++++++++++++++++++++++++++---------
src/MANYBODY/pair_comb.h | 15 ++-
2 files changed, 195 insertions(+), 58 deletions(-)
diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp
index 5d0db94997..5c47b8dcf1 100644
--- a/src/MANYBODY/pair_comb.cpp
+++ b/src/MANYBODY/pair_comb.cpp
@@ -12,7 +12,7 @@
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
- Contributing author: Tzu-Ray Shan (U Florida, rayshan@ufl.edu)
+ Contributing author: Tzu-Ray Shan (U Florida, present: tnshan@sandia.gov)
LAMMPS implementation of the Charge-optimized many-body (COMB) potential
based on the HELL MD program (Prof Simon Phillpot, UF, sphil@mse.ufl.edu)
and Aidan Thompson's Tersoff code in LAMMPS
@@ -32,11 +32,13 @@
#include "memory.h"
#include "error.h"
#include "group.h"
+#include "update.h"
using namespace LAMMPS_NS;
#define MAXLINE 1024
#define DELTA 4
+#define PGDELTA 1
/* ---------------------------------------------------------------------- */
@@ -52,6 +54,7 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp)
nmax = 0;
NCo = NULL;
+ bbij = NULL;
nelements = 0;
elements = NULL;
@@ -68,6 +71,11 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp)
dphin = NULL;
erpaw = NULL;
+ sht_num = NULL;
+ sht_first = NULL;
+ maxpage = 0;
+ pages = NULL;
+
// set comm size needed by this Pair
comm_forward = 1;
@@ -84,6 +92,7 @@ PairComb::~PairComb()
if (elements)
for (int i = 0; i < nelements; i++) delete [] elements[i];
+
delete [] elements;
memory->sfree(params);
memory->destroy(elem2param);
@@ -95,6 +104,9 @@ PairComb::~PairComb()
memory->destroy(phin);
memory->destroy(dphin);
memory->destroy(erpaw);
+ memory->destroy(bbij);
+ memory->destroy(sht_num);
+ memory->destroy(sht_first);
if (allocated) {
memory->destroy(setflag);
@@ -122,17 +134,25 @@ void PairComb::compute(int eflag, int vflag)
double yaself;
double potal,fac11,fac11e;
double vionij,fvionij,sr1,sr2,sr3,Eov,Fov;
+ int sht_jnum, *sht_jlist;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = vflag_atom = 0;
- // grow coordination array if necessary
+ // Build short range neighbor list
+ // int every=neighbor->every;
+ // int ntimestep=update->ntimestep;
+ // if(ntimestep <= 1 || (ntimestep % every == 0))
+ Short_neigh();
+ // grow coordination array if necessary
if (atom->nmax > nmax) {
memory->destroy(NCo);
+ memory->destroy(bbij);
nmax = atom->nmax;
memory->create(NCo,nmax,"pair:NCo");
+ memory->create(bbij,nmax,nmax,"pair:bbij");
}
double **x = atom->x;
@@ -177,6 +197,8 @@ void PairComb::compute(int eflag, int vflag)
jlist = firstneigh[i];
jnum = numneigh[i];
+ sht_jlist = sht_first[i];
+ sht_jnum = sht_num[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
@@ -258,8 +280,8 @@ void PairComb::compute(int eflag, int vflag)
// accumulate coordination number information
if (cor_flag) {
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
+ for (jj = 0; jj < sht_jnum; jj++) {
+ j = sht_jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
iparam_ij = elem2param[itype][jtype][jtype];
@@ -277,11 +299,12 @@ void PairComb::compute(int eflag, int vflag)
}
// three-body interactions
- // skip immediately if I-J is not within cutoff
+ // half i-j loop
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
+ for (jj = 0; jj < sht_jnum; jj++) {
+ j = sht_jlist[jj];
j &= NEIGHMASK;
+
jtype = map[type[j]];
iparam_ij = elem2param[itype][jtype][jtype];
@@ -301,9 +324,9 @@ void PairComb::compute(int eflag, int vflag)
zeta_ij = 0.0;
cuo_flag1 = 0; cuo_flag2 = 0;
- for (kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- k = jlist[kk];
+ for (kk = 0; kk < sht_jnum; kk++) {
+ k = sht_jlist[kk];
+ if (j == k) continue;
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
@@ -324,9 +347,9 @@ void PairComb::compute(int eflag, int vflag)
if (cuo_flag1 && cuo_flag2) cuo_flag = 1;
else cuo_flag = 0;
- force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair,
- prefactor,eflag,evdwl,iq,jq);
-
+ force_zeta(¶ms[iparam_ij],eflag,i,j,rsq1,zeta_ij,
+ iq,jq,fpair,prefactor,evdwl);
+
// over-coordination correction for HfO2
if (cor_flag && NCo[i] != 0)
@@ -346,9 +369,9 @@ void PairComb::compute(int eflag, int vflag)
// attractive term via loop over k (3-body forces)
- for (kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- k = jlist[kk];
+ for (kk = 0; kk < sht_jnum; kk++) {
+ k = sht_jlist[kk];
+ if (j == k) continue;
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
@@ -530,6 +553,11 @@ void PairComb::init_style()
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
+ neighbor->requests[irequest]->ghost = 1;
+
+ pgsize = neighbor->pgsize;
+ oneatom = neighbor->oneatom;
+ if (maxpage == 0) add_pages(0);
}
/* ----------------------------------------------------------------------
@@ -799,11 +827,12 @@ void PairComb::setup()
// set cutmax to max of all params
- cutmax = 0.0;
+ cutmax = cutmin = 0.0;
cor_flag = 0;
for (m = 0; m < nparams; m++) {
if (params[m].cut > cutmax) cutmax = params[m].cut;
if (params[m].lcut > cutmax) cutmax = params[m].lcut;
+ if (params[m].cutsq > cutmin) cutmin = params[m].cutsq+1.0;
if (params[m].hfocor > 0.0001) cor_flag = 1;
}
}
@@ -930,7 +959,7 @@ double PairComb::elp(Param *param, double rsqij, double rsqik,
comtt += param->aconf *(4.0-(rmu-c123)*(rmu-c123));
}
- return 0.5 * fck * comtt;
+ return 1.0 * fck * comtt;
}
return 0.0;
@@ -996,10 +1025,10 @@ void PairComb::flp(Param *param, double rsqij, double rsqik,
com4k = fcj * fck_d * comtt;
com5 = fcj * fck * comtt_d;
- ffj1 =-0.5*(com5/(rij*rik));
- ffj2 = 0.5*(com5*rmu/rsqij);
+ ffj1 =-1.0*(com5/(rij*rik));
+ ffj2 = 1.0*(com5*rmu/rsqij);
ffk1 = ffj1;
- ffk2 = 0.5*(-com4k/rik+com5*rmu/rsqik);
+ ffk2 = 1.0*(-com4k/rik+com5*rmu/rsqik);
} else {
ffj1 = 0.0; ffj2 = 0.0;
@@ -1024,9 +1053,9 @@ void PairComb::flp(Param *param, double rsqij, double rsqik,
/* ---------------------------------------------------------------------- */
-void PairComb::force_zeta(Param *param, double rsq, double zeta_ij,
- double &fforce, double &prefactor,
- int eflag, double &eng, double iq, double jq)
+void PairComb::force_zeta(Param *param, int eflag, int i, int j, double rsq,
+ double zeta_ij, double iq, double jq, double &fforce,
+ double &prefactor, double &eng)
{
double r,fa,fa_d,bij;
@@ -1035,11 +1064,13 @@ void PairComb::force_zeta(Param *param, double rsq, double zeta_ij,
fa = comb_fa(r,param,iq,jq);
fa_d = comb_fa_d(r,param,iq,jq);
bij = comb_bij(zeta_ij,param);
+ bbij[i][j] = bij;
+
+ // force
fforce = 0.5*bij*fa_d / r;
prefactor = -0.5*fa * comb_bij_d(zeta_ij,param);
// eng = attractive energy
-
if (eflag) eng = 0.5*bij*fa;
}
@@ -1343,6 +1374,7 @@ void PairComb::sm_table()
double exp2ear,exp2ebr,exp2earsh,exp2ebrsh,fafbsh,dfafbsh;
int n = atom->ntypes;
+ int nmax = atom->nmax;
dra = 0.001; // lookup table step size
drin = 0.1; // starting distance of 1/r
@@ -1351,7 +1383,7 @@ void PairComb::sm_table()
nntypes = int((n+1)*n/2); // interaction types
ncoul = int((rc-drin)/dra)+1;
-
+/*
memory->destroy(intype);
memory->destroy(fafb);
memory->destroy(dfafb);
@@ -1359,7 +1391,7 @@ void PairComb::sm_table()
memory->destroy(phin);
memory->destroy(dphin);
memory->destroy(erpaw);
-
+*/
// allocate arrays
memory->create(intype,n,n,"pair:intype");
@@ -1369,6 +1401,11 @@ void PairComb::sm_table()
memory->create(phin,ncoul,nntypes,"pair:phin");
memory->create(dphin,ncoul,nntypes,"pair:dphin");
memory->create(erpaw,25000,2,"pair:erpaw");
+ memory->create(NCo,nmax,"pair:NCo");
+ memory->create(bbij,nmax,nmax,"pair:bbij");
+ memory->create(sht_num,nmax,"pair:sht_num");
+ sht_first = (int **) memory->smalloc(nmax*sizeof(int *),
+ "pair:sht_first");
// set interaction number: 0-0=0, 1-1=1, 0-1=1-0=2
@@ -1614,7 +1651,7 @@ void PairComb::field(Param *param, double rsq, double iq,double jq,
double PairComb::yasu_char(double *qf_fix, int &igroup)
{
- int i,j,k,ii,jj,kk,jnum;
+ int i,j,k,ii,jj,kk,jnum,itag,jtag;
int itype,jtype,ktype,iparam_i,iparam_ij,iparam_ijk;
double xtmp,ytmp,ztmp;
double rsq1,rsq2,delr1[3],delr2[3],zeta_ij;
@@ -1622,10 +1659,12 @@ double PairComb::yasu_char(double *qf_fix, int &igroup)
double iq,jq,fqi,fqj,fqij,fqjj;
double potal,fac11,fac11e,sr1,sr2,sr3;
int mr1,mr2,mr3,inty;
+ int sht_jnum, *sht_jlist;
double **x = atom->x;
double *q = atom->q;
int *type = atom->type;
+ int *tag = atom->tag;
int inum = list->inum;
ilist = list->ilist;
@@ -1656,6 +1695,7 @@ double PairComb::yasu_char(double *qf_fix, int &igroup)
for (ii = 0; ii < inum; ii ++) {
i = ilist[ii];
+ itag = tag[i];
if (mask[i] & groupbit) {
itype = map[type[i]];
xtmp = x[i][0];
@@ -1672,10 +1712,24 @@ double PairComb::yasu_char(double *qf_fix, int &igroup)
jlist = firstneigh[i];
jnum = numneigh[i];
+ sht_jlist = sht_first[i];
+ sht_jnum = sht_num[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < x[i][2]) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
jtype = map[type[j]];
jq = q[j];
@@ -1706,38 +1760,31 @@ double PairComb::yasu_char(double *qf_fix, int &igroup)
qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqij,fqjj);
fqi += fqij;
qf[j] += fqjj;
+ }
- // polarization field charge force
// three-body interactions
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = vec3_dot(delr1,delr1);
+
+ iparam_ij = elem2param[itype][jtype][jtype];
if (rsq1 > params[iparam_ij].cutsq) continue;
- zeta_ij = 0.0;
-
- for (kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- k = jlist[kk];
- k &= NEIGHMASK;
- ktype = map[type[k]];
- iparam_ijk = elem2param[itype][jtype][ktype];
-
- delr2[0] = x[k][0] - xtmp;
- delr2[1] = x[k][1] - ytmp;
- delr2[2] = x[k][2] - ztmp;
- rsq2 = vec3_dot(delr2,delr2);
-
- if (rsq2 > params[iparam_ijk].cutsq) continue;
- zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
- }
-
// charge force in Aij and Bij
- qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj);
+ qfo_short(¶ms[iparam_ij],i,j,rsq1,iq,jq,fqij,fqjj);
fqi += fqij; qf[j] += fqjj;
}
-
qf[i] += fqi;
-
}
}
@@ -1809,7 +1856,7 @@ void PairComb::qfo_direct(int inty, int mr1, int mr2, int mr3,
erfcc = sr1*erpaw[mr1][0] + sr2*erpaw[mr2][0] + sr3*erpaw[mr3][0];
fafbn1= sr1*fafb[mr1][inty] + sr2*fafb[mr2][inty] + sr3*fafb[mr3][inty];
vm = (erfcc/r * esucon - fac11e);
- fqij = 0.5 * (vm+esucon*fafbn1);
+ fqij = 1.0 * (vm+esucon*fafbn1);
}
/* ---------------------------------------------------------------------- */
@@ -1835,13 +1882,13 @@ void PairComb::qfo_field(Param *param, double rsq,double iq,double jq,
// field correction charge force
- fqij = 0.5 * rf5 * (cmj1 + 2.0 * iq * cmj2);
- fqjj = 0.5 * rf5 * (cmi1 + 2.0 * jq * cmi2);
+ fqij = 1.0 * rf5 * (cmj1 + 2.0 * iq * cmj2);
+ fqjj = 1.0 * rf5 * (cmi1 + 2.0 * jq * cmi2);
}
/* ---------------------------------------------------------------------- */
-void PairComb::qfo_short(Param *param, double rsq, double zeta_ij,
+void PairComb::qfo_short(Param *param, int i, int j, double rsq,
double iq, double jq, double &fqij, double &fqjj)
{
double r,tmp_fc,tmp_fc_d,tmp_exp1,tmp_exp2;
@@ -1866,7 +1913,7 @@ void PairComb::qfo_short(Param *param, double rsq, double zeta_ij,
tmp_fc_d = comb_fc_d(r,param);
tmp_exp1 = exp(-param->rlm1 * r);
tmp_exp2 = exp(-param->rlm2 * r);
- bij = comb_bij(zeta_ij,param);
+ bij = bbij[i][j]; //comb_bij(zeta_ij,param);
arr1 = 2.22850; arr2 = 1.89350;
fc2j = comb_fc2(r);
@@ -2025,5 +2072,86 @@ double PairComb::memory_usage()
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
bytes += nmax * sizeof(int);
+ bytes += nmax * nmax * sizeof(int);
return bytes;
}
+/* ---------------------------------------------------------------------- */
+
+void PairComb::Short_neigh()
+{
+ int nj,npntj,*neighptrj,itype,jtype;
+ int iparam_ij,*ilist,*jlist,*numneigh,**firstneigh;
+ int inum,jnum,i,j,ii,jj;
+ double xtmp,ytmp,ztmp,rr,rsq,delrj[3];
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int ntype = atom->ntypes;
+
+ if (atom->nmax > nmax) {
+ nmax = int(1.0 * atom->nmax);
+ memory->sfree(sht_num);
+ memory->sfree(sht_first);
+ memory->create(sht_num,nmax,"pair:sht_num");
+ sht_first = (int **) memory->smalloc(nmax*sizeof(int *),
+ "pair:sht_first");
+ }
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ npage = npntj = 0;
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ itype = type[i];
+
+ if(pgsize - npntj < oneatom) {
+ npntj = 0;
+ npage++;
+ if (npage == maxpage) add_pages(npage);
+ }
+
+ nj = 0;
+ neighptrj = &pages[npage][npntj];
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ delrj[0] = xtmp - x[j][0];
+ delrj[1] = ytmp - x[j][1];
+ delrj[2] = ztmp - x[j][2];
+ rsq = vec3_dot(delrj,delrj);
+
+ if (rsq > cutmin) continue;
+ neighptrj[nj++] = j;
+ }
+ sht_first[i] = neighptrj;
+ sht_num[i] = nj;
+ npntj += nj;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairComb::add_pages(int npage)
+{
+ maxpage += PGDELTA;
+ pages = (int **)
+ memory->srealloc(pages,maxpage*sizeof(int *),"pair:pages");
+ for (int i = npage; i < maxpage; i++)
+ memory->create(pages[i],pgsize,"pair:pages[i]");
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h
index 555cf7509b..c8782b4bbf 100644
--- a/src/MANYBODY/pair_comb.h
+++ b/src/MANYBODY/pair_comb.h
@@ -76,6 +76,7 @@ class PairComb : public Pair {
double *charge;
int **intype, *typeno;
int *NCo, cor_flag, cuo_flag, cuo_flag1, cuo_flag2;
+ double **bbij;
void allocate();
virtual void read_file(char *);
@@ -83,8 +84,8 @@ class PairComb : public Pair {
virtual void repulsive(Param *, double, double &, int,
double &, double, double);
double zeta(Param *, double, double, double *, double *);
- void force_zeta(Param *, double, double, double &, double &,
- int, double &, double,double);
+ void force_zeta(Param *, int, int, int, double, double, double, double,
+ double &, double &, double &);
void attractive(Param *, double, double, double, double *, double *,
double *, double *, double *);
double elp(Param *, double, double, double *, double *);
@@ -115,7 +116,8 @@ class PairComb : public Pair {
double,double,double,double &,double &);
void field(Param *,double,double,double,double &,double &);
double qfo_self(Param *, double, double);
- void qfo_short(Param *, double, double, double, double, double &, double &);
+ void qfo_short(Param *, int, int, double, double, double,
+ double &, double &);
void qfo_direct (int, int, int, int, double, double, double, double,
double, double &);
void qfo_field(Param *, double,double ,double ,double &, double &);
@@ -126,6 +128,13 @@ class PairComb : public Pair {
int pack_comm(int , int *, double *, int, int *);
void unpack_comm(int , int , double *);
+ // Short range neighbor list
+ void add_pages(int );
+ void Short_neigh();
+ int npage, maxpage, pgsize, oneatom, **pages;
+ int *sht_num, **sht_first; // short-range neighbor list
+ double cutmin;
+
// vector functions, inline for efficiency
inline double vec3_dot(double *x, double *y) {
From 4591d9958dbb931b5fc6de69b2c6069f2c634922 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Fri, 7 Oct 2011 23:52:06 +0000
Subject: [PATCH 04/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7048
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
lib/cuda/Makefile.defaults | 2 +-
lib/cuda/Makefile.lammps | 4 ++--
lib/gpu/Makefile.linux | 4 +++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/cuda/Makefile.defaults b/lib/cuda/Makefile.defaults
index 3f39f7d606..ea0c53a349 100644
--- a/lib/cuda/Makefile.defaults
+++ b/lib/cuda/Makefile.defaults
@@ -3,7 +3,7 @@
precision ?= 1
#GPU architecture (compute capability): 13, 20, 21
-arch ?= 20
+arch ?= 21
#Using cufft (should not be changed)
cufft ?= 1
diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps
index 172fbc91ec..711e827a65 100644
--- a/lib/cuda/Makefile.lammps
+++ b/lib/cuda/Makefile.lammps
@@ -1,6 +1,6 @@
# Settings that the LAMMPS build will import when this package library is used
- CUDA_FLAGS = -I/usr/local/cuda/include -I../../lib/cuda -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20
- CUDA_USRLIB_CONDITIONAL = -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft
+CUDA_FLAGS := -I/usr/local/cuda/include -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20
+CUDA_USRLIB_CONDITIONAL := -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft
user-cuda_SYSINC = ${CUDA_FLAGS}
user-cuda_SYSLIB = -lcuda -lcudart -lrt
diff --git a/lib/gpu/Makefile.linux b/lib/gpu/Makefile.linux
index 1777187010..c8dd8350d1 100644
--- a/lib/gpu/Makefile.linux
+++ b/lib/gpu/Makefile.linux
@@ -20,8 +20,10 @@
CUDA_HOME = /usr/local/cuda
NVCC = nvcc
+# Tesla CUDA
+CUDA_ARCH = -arch=sm_21
# newer CUDA
-CUDA_ARCH = -arch=sm_13
+#CUDA_ARCH = -arch=sm_13
# older CUDA
#CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE
From 2182b0443bba24509324dd3eee4da964bb2a5bd8 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Fri, 7 Oct 2011 23:52:09 +0000
Subject: [PATCH 05/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7049
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/version.h b/src/version.h
index 4d760c21f6..e5b656e825 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "6 Oct 2011"
+#define LAMMPS_VERSION "7 Oct 2011"
From c1bfbd8e616501b33fbd00cd5a78c206ff828d99 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 14:58:50 +0000
Subject: [PATCH 06/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7057
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/input.cpp | 2 +-
src/lammps.cpp | 38 +++++++++++++++++++++++++-------------
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/src/input.cpp b/src/input.cpp
index ca4d450d72..2251335b43 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -89,7 +89,7 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
int iarg = 0;
while (iarg < argc) {
if (strcmp(argv[iarg],"-var") == 0 || strcmp(argv[iarg],"-v") == 0) {
- int jarg = iarg+2;
+ int jarg = iarg+3;
while (jarg < argc && argv[jarg][0] != '-') jarg++;
variable->set(argv[iarg+1],jarg-iarg-2,&argv[iarg+2]);
iarg = jarg;
diff --git a/src/lammps.cpp b/src/lammps.cpp
index 09b6a487de..f316a03ad7 100644
--- a/src/lammps.cpp
+++ b/src/lammps.cpp
@@ -81,7 +81,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
if (strcmp(arg[iarg],"-partition") == 0 ||
strcmp(arg[iarg],"-p") == 0) {
universe->existflag = 1;
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
iarg++;
while (iarg < narg && arg[iarg][0] != '-') {
universe->add_world(arg[iarg]);
@@ -89,27 +90,32 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
}
} else if (strcmp(arg[iarg],"-in") == 0 ||
strcmp(arg[iarg],"-i") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
inflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-screen") == 0 ||
strcmp(arg[iarg],"-sc") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
screenflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-log") == 0 ||
strcmp(arg[iarg],"-l") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
logflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-var") == 0 ||
strcmp(arg[iarg],"-v") == 0) {
- if (iarg+3 > narg) error->universe_all(FLERR,"Invalid command-line argument");
- iarg += 2;
+ if (iarg+3 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
+ iarg += 3;
while (iarg < narg && arg[iarg][0] != '-') iarg++;
} else if (strcmp(arg[iarg],"-echo") == 0 ||
strcmp(arg[iarg],"-e") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
iarg += 2;
} else if (strcmp(arg[iarg],"-pscreen") == 0 ||
strcmp(arg[iarg],"-ps") == 0) {
@@ -125,14 +131,16 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
iarg += 2;
} else if (strcmp(arg[iarg],"-cuda") == 0 ||
strcmp(arg[iarg],"-c") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
if (strcmp(arg[iarg+1],"on") == 0) cudaflag = 1;
else if (strcmp(arg[iarg+1],"off") == 0) cudaflag = 0;
else error->universe_all(FLERR,"Invalid command-line argument");
iarg += 2;
} else if (strcmp(arg[iarg],"-suffix") == 0 ||
strcmp(arg[iarg],"-sf") == 0) {
- if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+2 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
delete [] suffix;
int n = strlen(arg[iarg+1]) + 1;
suffix = new char[n];
@@ -141,7 +149,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
iarg += 2;
} else if (strcmp(arg[iarg],"-help") == 0 ||
strcmp(arg[iarg],"-h") == 0) {
- if (iarg+1 > narg) error->universe_all(FLERR,"Invalid command-line argument");
+ if (iarg+1 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
helpflag = 1;
iarg += 1;
} else error->universe_all(FLERR,"Invalid command-line argument");
@@ -334,10 +343,12 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
int mpisize;
MPI_Type_size(MPI_LMP_TAGINT,&mpisize);
if (mpisize != sizeof(tagint))
- error->all(FLERR,"MPI_LMP_TAGINT and tagint in lmptype.h are not compatible");
+ error->all(FLERR,
+ "MPI_LMP_TAGINT and tagint in lmptype.h are not compatible");
MPI_Type_size(MPI_LMP_BIGINT,&mpisize);
if (mpisize != sizeof(bigint))
- error->all(FLERR,"MPI_LMP_BIGINT and bigint in lmptype.h are not compatible");
+ error->all(FLERR,
+ "MPI_LMP_BIGINT and bigint in lmptype.h are not compatible");
#ifdef LAMMPS_SMALLBIG
if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 8)
@@ -352,7 +363,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
error->all(FLERR,"Small, tag, big integers are not sized correctly");
#endif
- if (sizeof(tagint) == 8) error->all(FLERR,"64-bit atom IDs are not yet supported");
+ if (sizeof(tagint) == 8)
+ error->all(FLERR,"64-bit atom IDs are not yet supported");
// create CUDA class if USER-CUDA installed, unless explicitly switched off
// instantiation creates dummy CUDA class if USER-CUDA is not installed
From 6a2a96053c405a3a87ce17820391ba8df0e7ff3b Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 15:01:46 +0000
Subject: [PATCH 07/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7058
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/Section_start.html | 6 ++++++
doc/Section_start.txt | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/doc/Section_start.html b/doc/Section_start.html
index bfe24d404e..438f879dd6 100644
--- a/doc/Section_start.html
+++ b/doc/Section_start.html
@@ -1016,6 +1016,12 @@ defining index and other kinds of variables and
2.7 LAMMPS screen output
diff --git a/doc/Section_start.txt b/doc/Section_start.txt
index 5ae3fb715c..674dec45b7 100644
--- a/doc/Section_start.txt
+++ b/doc/Section_start.txt
@@ -1008,6 +1008,12 @@ defining index and other kinds of variables and "this
section"_Section_commands.html#cmd_2 for more info on using variables
in input scripts.
+NOTE: Currently, the command-line parser looks for arguments that
+start with "-" to indicate new switches. Thus you cannot specify
+multiple variable values if any of they start with a "-", e.g. a
+negative numeric value. It is OK if the first value1 starts with a
+"-", since it is automatically skipped.
+
:line
2.7 LAMMPS screen output :h4,link(start_7)
From 76da1a753ba17d47166c7f793423d31b7ed6bed8 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 15:03:34 +0000
Subject: [PATCH 08/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7059
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/version.h b/src/version.h
index e5b656e825..9da39c4204 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "7 Oct 2011"
+#define LAMMPS_VERSION "10 Oct 2011"
From 6d849fea0e361c349098e9d5b747b903ac8e9e45 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 16:26:58 +0000
Subject: [PATCH 09/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7061
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/MOLECULE/pair_hbond_dreiding_lj.cpp | 7 ++++---
src/MOLECULE/pair_hbond_dreiding_morse.cpp | 7 ++++---
src/fix_addforce.cpp | 15 ++++++++++-----
3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
index cb5429b3f4..eae9e4aa83 100644
--- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
@@ -76,7 +76,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
{
int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype;
double delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
- double factor_hb,force_angle,force_kernel,evdwl,eng_lj;
+ double factor_hb,force_angle,force_kernel,evdwl,eng_lj,ehbond;
double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
double fi[3],fj[3],delr1[3],delr2[3];
double r2inv,r10inv;
@@ -84,7 +84,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
int *ilist,*jlist,*klist,*numneigh,**firstneigh;
Param *pm;
- evdwl = 0.0;
+ evdwl = ehbond = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
@@ -186,6 +186,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
if (eflag) {
evdwl = eng_lj * pow(c,pm->ap);
evdwl *= factor_hb;
+ ehbond += evdwl;
}
a = factor_hb*force_angle/s;
@@ -234,7 +235,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
if (eflag_global) {
pvector[0] = hbcount;
- pvector[1] = evdwl;
+ pvector[1] = ehbond;
}
}
diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
index 2e70d928d1..ebd3b27ef0 100644
--- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
@@ -46,14 +46,14 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
{
int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype;
double delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
- double factor_hb,force_angle,force_kernel,evdwl;
+ double factor_hb,force_angle,force_kernel,evdwl,ehbond;
double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
double fi[3],fj[3],delr1[3],delr2[3];
double r,dr,dexp,eng_morse,switch1,switch2;
int *ilist,*jlist,*klist,*numneigh,**firstneigh;
Param *pm;
- evdwl = 0.0;
+ evdwl = ehbond = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
@@ -154,6 +154,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
if (eflag) {
evdwl = eng_morse * pow(c,params[m].ap);
evdwl *= factor_hb;
+ ehbond += evdwl;
}
a = factor_hb*force_angle/s;
@@ -202,7 +203,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
if (eflag_global) {
pvector[0] = hbcount;
- pvector[1] = evdwl;
+ pvector[1] = ehbond;
}
}
diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp
index 16a3c1feab..fee57525d8 100644
--- a/src/fix_addforce.cpp
+++ b/src/fix_addforce.cpp
@@ -137,28 +137,32 @@ void FixAddForce::init()
if (xstr) {
xvar = input->variable->find(xstr);
- if (xvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist");
+ if (xvar < 0)
+ error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(xvar)) xstyle = EQUAL;
else if (input->variable->atomstyle(xvar)) xstyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
- if (yvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist");
+ if (yvar < 0)
+ error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(yvar)) ystyle = EQUAL;
else if (input->variable->atomstyle(yvar)) ystyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (zstr) {
zvar = input->variable->find(zstr);
- if (zvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist");
+ if (zvar < 0)
+ error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(zvar)) zstyle = EQUAL;
else if (input->variable->atomstyle(zvar)) zstyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (estr) {
evar = input->variable->find(estr);
- if (evar < 0) error->all(FLERR,"Variable name for fix addforce does not exist");
+ if (evar < 0)
+ error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->atomstyle(evar)) estyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
} else estyle = NONE;
@@ -167,7 +171,8 @@ void FixAddForce::init()
if (iregion >= 0) {
iregion = domain->find_region(idregion);
- if (iregion == -1) error->all(FLERR,"Region ID for fix addforce does not exist");
+ if (iregion == -1)
+ error->all(FLERR,"Region ID for fix addforce does not exist");
}
if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM)
From 789f069c2bc857259e0b73ed310976e9f4e10bba Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 16:33:07 +0000
Subject: [PATCH 10/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7062
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
examples/README | 1 +
examples/dreiding/README | 5 +
examples/dreiding/ch3oh.box.dreiding.bgf | 780 +++++++++
.../ch3oh.box.dreiding.cerius2.eng.dat | 56 +
examples/dreiding/data.dreiding | 1400 +++++++++++++++++
examples/dreiding/in.dreiding | 39 +
.../dreiding/log.dreiding.11Oct11.linux.1 | 97 ++
.../dreiding/log.dreiding.11Oct11.linux.4 | 121 ++
8 files changed, 2499 insertions(+)
create mode 100644 examples/dreiding/README
create mode 100644 examples/dreiding/ch3oh.box.dreiding.bgf
create mode 100644 examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat
create mode 100644 examples/dreiding/data.dreiding
create mode 100644 examples/dreiding/in.dreiding
create mode 100644 examples/dreiding/log.dreiding.11Oct11.linux.1
create mode 100644 examples/dreiding/log.dreiding.11Oct11.linux.4
diff --git a/examples/README b/examples/README
index ffad2e66c5..814497cf81 100644
--- a/examples/README
+++ b/examples/README
@@ -29,6 +29,7 @@ colloid: big colloid particles in a small particle solvent, 2d system
comb: models using the COMB potential
crack: crack propagation in a 2d solid
dipole: point dipolar particles, 2d system
+dreiding: methanol via Dreiding FF
eim: NaCl using the EIM potential
ellipse: ellipsoidal particles in spherical solvent, 2d system
flow: Couette and Poiseuille flow in a 2d channel
diff --git a/examples/dreiding/README b/examples/dreiding/README
new file mode 100644
index 0000000000..351f7e9e5c
--- /dev/null
+++ b/examples/dreiding/README
@@ -0,0 +1,5 @@
+The LAMMPS input script and data file were built to
+match the Cerius Dreiding files included
+in this directory (ch3oh.box.*) so that you
+can compare LAMMPS output to a Dreiding implementation
+in the Cerius code.
diff --git a/examples/dreiding/ch3oh.box.dreiding.bgf b/examples/dreiding/ch3oh.box.dreiding.bgf
new file mode 100644
index 0000000000..b9431153aa
--- /dev/null
+++ b/examples/dreiding/ch3oh.box.dreiding.bgf
@@ -0,0 +1,780 @@
+XTLGRF 200
+DESCRP Model6
+REMARK BGF file created by Cerius2
+FORCEFIELD DREIDING
+PERIOD 111
+AXES ZYX
+SGNAME P 1 1 1
+CRYSTX 19.99689 19.12816 19.46971 90.00000 90.00000 90.00000
+CELLS -1 1 -1 1 -1 1
+FORMAT ATOM (a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5, i3,i2,1x,f8.5)
+HETATM 1 C1 RES A 444 9.75768 9.43603 9.44978 C_3 4 0 0.03193
+HETATM 2 O2 RES A 444 9.07001 9.89252 10.61030 O_3 2 2 -0.39965
+HETATM 3 H3 RES A 444 9.56169 8.37372 9.30573 H_ 1 0 0.05269
+HETATM 4 H4 RES A 444 9.40633 9.98872 8.57739 H_ 1 0 0.05269
+HETATM 5 H5 RES A 444 10.83081 9.58873 9.56849 H_ 1 0 0.05269
+HETATM 6 H6 RES A 444 9.28861 10.84826 10.67569 H___A 1 0 0.20964
+HETATM 7 C7 RES A 444 7.87790 6.57305 4.37926 C_3 4 0 0.03193
+HETATM 8 O8 RES A 444 9.21046 6.55811 3.88167 O_3 2 2 -0.39965
+HETATM 9 H9 RES A 444 7.42565 7.54437 4.17519 H_ 1 0 0.05269
+HETATM 10 H10 RES A 444 7.28908 5.79550 3.89029 H_ 1 0 0.05269
+HETATM 11 H11 RES A 444 7.88159 6.39628 5.45605 H_ 1 0 0.05269
+HETATM 12 H12 RES A 444 9.55621 5.66386 4.09964 H___A 1 0 0.20964
+HETATM 13 C13 RES A 444 19.38728 8.01844 0.29841 C_3 4 0 0.03193
+HETATM 14 O14 RES A 444 18.30059 8.67235 0.94403 O_3 2 2 -0.39965
+HETATM 15 H15 RES A 444 20.09420 7.66052 1.04704 H_ 1 0 0.05269
+HETATM 16 H16 RES A 444 19.01558 7.17130 -0.27928 H_ 1 0 0.05269
+HETATM 17 H17 RES A 444 19.89453 8.71684 -0.36839 H_ 1 0 0.05269
+HETATM 18 H18 RES A 444 17.72537 8.98355 0.21436 H___A 1 0 0.20964
+HETATM 19 C19 RES A 444 3.43963 14.29741 12.62221 C_3 4 0 0.03193
+HETATM 20 O20 RES A 444 3.07671 15.61822 12.23631 O_3 2 2 -0.39965
+HETATM 21 H21 RES A 444 4.27302 14.34187 13.32349 H_ 1 0 0.05269
+HETATM 22 H22 RES A 444 2.59308 13.81008 13.10508 H_ 1 0 0.05269
+HETATM 23 H23 RES A 444 3.73991 13.72415 11.74356 H_ 1 0 0.05269
+HETATM 24 H24 RES A 444 2.32966 15.52033 11.61130 H___A 1 0 0.20964
+HETATM 25 C25 RES A 444 16.06751 17.84957 14.39706 C_3 4 0 0.03193
+HETATM 26 O26 RES A 444 15.98970 19.07282 15.11734 O_3 2 2 -0.39965
+HETATM 27 H27 RES A 444 16.77526 17.18402 14.89204 H_ 1 0 0.05269
+HETATM 28 H28 RES A 444 15.08510 17.37867 14.36938 H_ 1 0 0.05269
+HETATM 29 H29 RES A 444 16.40684 18.04085 13.37809 H_ 1 0 0.05269
+HETATM 30 H30 RES A 444 15.35997 19.62900 14.61094 H___A 1 0 0.20964
+HETATM 31 C31 RES A 444 5.61540 13.90261 0.28024 C_3 4 0 0.03193
+HETATM 32 O32 RES A 444 6.96329 14.33980 0.39819 O_3 2 2 -0.39965
+HETATM 33 H33 RES A 444 5.39381 13.18200 1.06831 H_ 1 0 0.05269
+HETATM 34 H34 RES A 444 4.93854 14.75467 0.36989 H_ 1 0 0.05269
+HETATM 35 H35 RES A 444 5.46825 13.42632 -0.68848 H_ 1 0 0.05269
+HETATM 36 H36 RES A 444 7.08381 14.99923 -0.31851 H___A 1 0 0.20964
+HETATM 37 C37 RES A 444 10.38444 13.74977 1.74423 C_3 4 0 0.03193
+HETATM 38 O38 RES A 444 10.34865 13.00890 2.96031 O_3 2 2 -0.39965
+HETATM 39 H39 RES A 444 11.31498 14.30998 1.68756 H_ 1 0 0.05269
+HETATM 40 H40 RES A 444 10.32135 13.06875 0.89580 H_ 1 0 0.05269
+HETATM 41 H41 RES A 444 9.54190 14.44190 1.71309 H_ 1 0 0.05269
+HETATM 42 H42 RES A 444 9.45315 12.60486 2.98815 H___A 1 0 0.20964
+HETATM 43 C43 RES A 444 2.71877 -0.19852 13.91482 C_3 4 0 0.03193
+HETATM 44 O44 RES A 444 2.55981 1.00656 13.16980 O_3 2 2 -0.39965
+HETATM 45 H45 RES A 444 3.42887 -0.85053 13.40421 H_ 1 0 0.05269
+HETATM 46 H46 RES A 444 3.09835 0.02977 14.91227 H_ 1 0 0.05269
+HETATM 47 H47 RES A 444 1.76062 -0.71177 13.99933 H_ 1 0 0.05269
+HETATM 48 H48 RES A 444 1.92580 1.55260 13.68058 H___A 1 0 0.20964
+HETATM 49 C49 RES A 444 12.86271 12.87291 9.10254 C_3 4 0 0.03193
+HETATM 50 O50 RES A 444 12.72964 12.19590 7.85730 O_3 2 2 -0.39965
+HETATM 51 H51 RES A 444 11.91715 12.83126 9.64447 H_ 1 0 0.05269
+HETATM 52 H52 RES A 444 13.63913 12.39659 9.70188 H_ 1 0 0.05269
+HETATM 53 H53 RES A 444 13.12955 13.91577 8.92585 H_ 1 0 0.05269
+HETATM 54 H54 RES A 444 13.60640 12.28637 7.42000 H___A 1 0 0.20964
+HETATM 55 C55 RES A 444 0.91345 1.84436 7.21758 C_3 4 0 0.03193
+HETATM 56 O56 RES A 444 0.16704 0.83109 7.88260 O_3 2 2 -0.39965
+HETATM 57 H57 RES A 444 1.73149 1.39473 6.65448 H_ 1 0 0.05269
+HETATM 58 H58 RES A 444 0.25949 2.38287 6.53090 H_ 1 0 0.05269
+HETATM 59 H59 RES A 444 1.31674 2.54212 7.95173 H_ 1 0 0.05269
+HETATM 60 H60 RES A 444 0.79209 0.41480 8.51642 H___A 1 0 0.20964
+HETATM 61 C61 RES A 444 3.28235 16.40235 6.34784 C_3 4 0 0.03193
+HETATM 62 O62 RES A 444 4.40446 15.86811 5.64397 O_3 2 2 -0.39965
+HETATM 63 H63 RES A 444 3.52775 16.47384 7.40940 H_ 1 0 0.05269
+HETATM 64 H64 RES A 444 3.04852 17.39543 5.96551 H_ 1 0 0.05269
+HETATM 65 H65 RES A 444 2.41989 15.75077 6.22278 H_ 1 0 0.05269
+HETATM 66 H66 RES A 444 4.15040 15.88018 4.69552 H___A 1 0 0.20964
+HETATM 67 C67 RES A 444 14.28685 11.84833 2.69644 C_3 4 0 0.03193
+HETATM 68 O68 RES A 444 14.47540 12.00775 4.09802 O_3 2 2 -0.39965
+HETATM 69 H69 RES A 444 15.22519 11.52503 2.24449 H_ 1 0 0.05269
+HETATM 70 H70 RES A 444 13.51978 11.09713 2.50925 H_ 1 0 0.05269
+HETATM 71 H71 RES A 444 13.98187 12.79680 2.25228 H_ 1 0 0.05269
+HETATM 72 H72 RES A 444 13.60420 12.29868 4.44979 H___A 1 0 0.20964
+HETATM 73 C73 RES A 444 3.74650 0.37490 9.28202 C_3 4 0 0.03193
+HETATM 74 O74 RES A 444 4.68624 1.26369 8.68537 O_3 2 2 -0.39965
+HETATM 75 H75 RES A 444 4.28178 -0.38700 9.84868 H_ 1 0 0.05269
+HETATM 76 H76 RES A 444 3.08874 0.92642 9.95440 H_ 1 0 0.05269
+HETATM 77 H77 RES A 444 3.15691 -0.10643 8.50276 H_ 1 0 0.05269
+HETATM 78 H78 RES A 444 4.15269 1.92251 8.18619 H___A 1 0 0.20964
+HETATM 79 C79 RES A 444 17.93191 1.98830 17.28592 C_3 4 0 0.03193
+HETATM 80 O80 RES A 444 16.68990 1.36769 17.60090 O_3 2 2 -0.39965
+HETATM 81 H81 RES A 444 18.23740 2.63433 18.10865 H_ 1 0 0.05269
+HETATM 82 H82 RES A 444 18.69345 1.22519 17.12938 H_ 1 0 0.05269
+HETATM 83 H83 RES A 444 17.82727 2.59026 16.38313 H_ 1 0 0.05269
+HETATM 84 H84 RES A 444 16.45659 0.83462 16.81232 H___A 1 0 0.20964
+HETATM 85 C85 RES A 444 4.61466 10.52979 17.10957 C_3 4 0 0.03193
+HETATM 86 O86 RES A 444 3.62035 11.42538 17.60198 O_3 2 2 -0.39965
+HETATM 87 H87 RES A 444 5.60177 10.98718 17.19552 H_ 1 0 0.05269
+HETATM 88 H88 RES A 444 4.60514 9.60666 17.68872 H_ 1 0 0.05269
+HETATM 89 H89 RES A 444 4.42040 10.30112 16.06086 H_ 1 0 0.05269
+HETATM 90 H90 RES A 444 2.76200 10.96432 17.46823 H___A 1 0 0.20964
+HETATM 91 C91 RES A 444 4.21479 2.76452 1.93621 C_3 4 0 0.03193
+HETATM 92 O92 RES A 444 3.45640 2.43822 3.09183 O_3 2 2 -0.39965
+HETATM 93 H93 RES A 444 5.15561 3.22498 2.23935 H_ 1 0 0.05269
+HETATM 94 H94 RES A 444 4.42333 1.85922 1.36296 H_ 1 0 0.05269
+HETATM 95 H95 RES A 444 3.65868 3.46500 1.31342 H_ 1 0 0.05269
+HETATM 96 H96 RES A 444 2.68968 1.92747 2.75853 H___A 1 0 0.20964
+HETATM 97 C97 RES A 444 2.10781 10.76856 1.36312 C_3 4 0 0.03193
+HETATM 98 O98 RES A 444 0.80698 11.27394 1.07892 O_3 2 2 -0.39965
+HETATM 99 H99 RES A 444 2.85114 11.53660 1.14272 H_ 1 0 0.05269
+HETATM 100 H100 RES A 444 2.17873 10.49350 2.41651 H_ 1 0 0.05269
+HETATM 101 H101 RES A 444 2.31220 9.89096 0.74802 H_ 1 0 0.05269
+HETATM 102 H102 RES A 444 0.18009 10.55168 1.30975 H___A 1 0 0.20964
+HETATM 103 C103 RES A 444 16.26093 8.92927 6.57643 C_3 4 0 0.03193
+HETATM 104 O104 RES A 444 15.77968 8.06983 7.60177 O_3 2 2 -0.39965
+HETATM 105 H105 RES A 444 17.30509 9.17300 6.76897 H_ 1 0 0.05269
+HETATM 106 H106 RES A 444 16.18069 8.42876 5.61195 H_ 1 0 0.05269
+HETATM 107 H107 RES A 444 15.67380 9.84869 6.55835 H_ 1 0 0.05269
+HETATM 108 H108 RES A 444 14.84042 7.91008 7.37720 H___A 1 0 0.20964
+HETATM 109 C109 RES A 444 17.80004 2.06792 1.87371 C_3 4 0 0.03193
+HETATM 110 O110 RES A 444 18.48862 0.99081 1.24012 O_3 2 2 -0.39965
+HETATM 111 H111 RES A 444 18.23871 2.25534 2.85453 H_ 1 0 0.05269
+HETATM 112 H112 RES A 444 17.87937 2.96817 1.26859 H_ 1 0 0.05269
+HETATM 113 H113 RES A 444 16.74643 1.80633 1.99693 H_ 1 0 0.05269
+HETATM 114 H114 RES A 444 18.02202 0.85350 0.38356 H___A 1 0 0.20964
+HETATM 115 C115 RES A 444 13.75521 14.57173 15.42181 C_3 4 0 0.03193
+HETATM 116 O116 RES A 444 12.73183 15.48504 15.80455 O_3 2 2 -0.39965
+HETATM 117 H117 RES A 444 14.51862 14.53760 16.20019 H_ 1 0 0.05269
+HETATM 118 H118 RES A 444 13.33164 13.57618 15.29114 H_ 1 0 0.05269
+HETATM 119 H119 RES A 444 14.21175 14.89091 14.48437 H_ 1 0 0.05269
+HETATM 120 H120 RES A 444 12.11746 15.52768 15.03694 H___A 1 0 0.20964
+HETATM 121 C121 RES A 444 6.22569 16.46321 11.49168 C_3 4 0 0.03193
+HETATM 122 O122 RES A 444 7.37834 15.65849 11.27192 O_3 2 2 -0.39965
+HETATM 123 H123 RES A 444 6.47325 17.50688 11.31115 H_ 1 0 0.05269
+HETATM 124 H124 RES A 444 5.42639 16.16714 10.80967 H_ 1 0 0.05269
+HETATM 125 H125 RES A 444 5.88670 16.35324 12.52283 H_ 1 0 0.05269
+HETATM 126 H126 RES A 444 7.09224 14.73066 11.41776 H___A 1 0 0.20964
+HETATM 127 C127 RES A 444 20.01012 9.33317 4.86657 C_3 4 0 0.03193
+HETATM 128 O128 RES A 444 19.63827 8.14994 5.56401 O_3 2 2 -0.39965
+HETATM 129 H129 RES A 444 20.82510 9.82112 5.40128 H_ 1 0 0.05269
+HETATM 130 H130 RES A 444 20.34186 9.07963 3.85908 H_ 1 0 0.05269
+HETATM 131 H131 RES A 444 19.16051 10.01349 4.80673 H_ 1 0 0.05269
+HETATM 132 H132 RES A 444 18.86130 7.79949 5.07585 H___A 1 0 0.20964
+HETATM 133 C133 RES A 444 5.99486 1.97634 5.72513 C_3 4 0 0.03193
+HETATM 134 O134 RES A 444 6.74021 3.13466 6.08586 O_3 2 2 -0.39965
+HETATM 135 H135 RES A 444 4.92875 2.19578 5.79288 H_ 1 0 0.05269
+HETATM 136 H136 RES A 444 6.23376 1.68432 4.70221 H_ 1 0 0.05269
+HETATM 137 H137 RES A 444 6.23815 1.15441 6.40034 H_ 1 0 0.05269
+HETATM 138 H138 RES A 444 7.67684 2.83917 6.07790 H___A 1 0 0.20964
+HETATM 139 C139 RES A 444 13.03835 7.12913 5.28770 C_3 4 0 0.03193
+HETATM 140 O140 RES A 444 13.02644 7.55487 6.64544 O_3 2 2 -0.39965
+HETATM 141 H141 RES A 444 12.06949 6.70203 5.02747 H_ 1 0 0.05269
+HETATM 142 H142 RES A 444 13.24117 7.98172 4.63978 H_ 1 0 0.05269
+HETATM 143 H143 RES A 444 13.81531 6.37647 5.14697 H_ 1 0 0.05269
+HETATM 144 H144 RES A 444 12.38966 8.29858 6.65964 H___A 1 0 0.20964
+HETATM 145 C145 RES A 444 10.64649 1.42163 6.99575 C_3 4 0 0.03193
+HETATM 146 O146 RES A 444 11.32932 1.55767 8.23581 O_3 2 2 -0.39965
+HETATM 147 H147 RES A 444 9.77461 0.78340 7.13967 H_ 1 0 0.05269
+HETATM 148 H148 RES A 444 10.32031 2.40213 6.64261 H_ 1 0 0.05269
+HETATM 149 H149 RES A 444 11.30461 0.96891 6.25436 H_ 1 0 0.05269
+HETATM 150 H150 RES A 444 12.13048 2.09412 8.04749 H___A 1 0 0.20964
+HETATM 151 C151 RES A 444 7.70974 10.56643 0.43745 C_3 4 0 0.03193
+HETATM 152 O152 RES A 444 6.69643 10.25499 1.38817 O_3 2 2 -0.39965
+HETATM 153 H153 RES A 444 8.59868 10.91732 0.96199 H_ 1 0 0.05269
+HETATM 154 H154 RES A 444 7.96121 9.67471 -0.13665 H_ 1 0 0.05269
+HETATM 155 H155 RES A 444 7.36428 11.34806 -0.24011 H_ 1 0 0.05269
+HETATM 156 H156 RES A 444 5.94241 9.89154 0.87302 H___A 1 0 0.20964
+HETATM 157 C157 RES A 444 12.78344 1.18067 14.16301 C_3 4 0 0.03193
+HETATM 158 O158 RES A 444 14.01647 1.62010 13.60417 O_3 2 2 -0.39965
+HETATM 159 H159 RES A 444 12.98217 0.47776 14.97222 H_ 1 0 0.05269
+HETATM 160 H160 RES A 444 12.23227 2.03435 14.55662 H_ 1 0 0.05269
+HETATM 161 H161 RES A 444 12.18352 0.68832 13.39874 H_ 1 0 0.05269
+HETATM 162 H162 RES A 444 13.77530 2.26070 12.89474 H___A 1 0 0.20964
+HETATM 163 C163 RES A 444 16.94139 17.42253 1.05686 C_3 4 0 0.03193
+HETATM 164 O164 RES A 444 16.08424 16.29569 1.04946 O_3 2 2 -0.39965
+HETATM 165 H165 RES A 444 17.18791 17.69368 0.02960 H_ 1 0 0.05269
+HETATM 166 H166 RES A 444 16.43795 18.25970 1.54236 H_ 1 0 0.05269
+HETATM 167 H167 RES A 444 17.85566 17.18021 1.60025 H_ 1 0 0.05269
+HETATM 168 H168 RES A 444 15.85827 16.14412 1.99459 H___A 1 0 0.20964
+HETATM 169 C169 RES A 444 12.48878 18.07306 2.58158 C_3 4 0 0.03193
+HETATM 170 O170 RES A 444 13.76343 18.70451 2.65479 O_3 2 2 -0.39965
+HETATM 171 H171 RES A 444 12.02971 18.30966 1.62310 H_ 1 0 0.05269
+HETATM 172 H172 RES A 444 12.61189 16.99304 2.67149 H_ 1 0 0.05269
+HETATM 173 H173 RES A 444 11.85062 18.43623 3.38623 H_ 1 0 0.05269
+HETATM 174 H174 RES A 444 14.05960 18.54980 3.57438 H___A 1 0 0.20964
+HETATM 175 C175 RES A 444 19.92937 14.32320 3.09954 C_3 4 0 0.03193
+HETATM 176 O176 RES A 444 20.47921 14.98239 4.23349 O_3 2 2 -0.39965
+HETATM 177 H177 RES A 444 19.06424 14.88021 2.74247 H_ 1 0 0.05269
+HETATM 178 H178 RES A 444 20.67424 14.26863 2.30532 H_ 1 0 0.05269
+HETATM 179 H179 RES A 444 19.62003 13.31457 3.37662 H_ 1 0 0.05269
+HETATM 180 H180 RES A 444 21.24382 14.42340 4.50083 H___A 1 0 0.20964
+HETATM 181 C181 RES A 444 10.63009 10.62036 5.48247 C_3 4 0 0.03193
+HETATM 182 O182 RES A 444 11.32080 9.96459 6.53930 O_3 2 2 -0.39965
+HETATM 183 H183 RES A 444 9.97896 9.90801 4.97371 H_ 1 0 0.05269
+HETATM 184 H184 RES A 444 10.02580 11.43533 5.88411 H_ 1 0 0.05269
+HETATM 185 H185 RES A 444 11.34799 11.02578 4.76860 H_ 1 0 0.05269
+HETATM 186 H186 RES A 444 11.85790 10.67095 6.95281 H___A 1 0 0.20964
+HETATM 187 C187 RES A 444 15.65699 9.09727 17.99408 C_3 4 0 0.03193
+HETATM 188 O188 RES A 444 16.90142 9.78939 17.98916 O_3 2 2 -0.39965
+HETATM 189 H189 RES A 444 15.04412 9.44428 18.82685 H_ 1 0 0.05269
+HETATM 190 H190 RES A 444 15.12611 9.28242 17.05809 H_ 1 0 0.05269
+HETATM 191 H191 RES A 444 15.82887 8.02576 18.10423 H_ 1 0 0.05269
+HETATM 192 H192 RES A 444 17.40700 9.38003 17.24481 H___A 1 0 0.20964
+HETATM 193 C193 RES A 444 17.18063 5.09511 5.97377 C_3 4 0 0.03193
+HETATM 194 O194 RES A 444 17.00699 3.69621 6.16625 O_3 2 2 -0.39965
+HETATM 195 H195 RES A 444 16.80087 5.38050 4.99222 H_ 1 0 0.05269
+HETATM 196 H196 RES A 444 16.63290 5.63866 6.74297 H_ 1 0 0.05269
+HETATM 197 H197 RES A 444 18.23947 5.34654 6.03632 H_ 1 0 0.05269
+HETATM 198 H198 RES A 444 17.37922 3.51369 7.05728 H___A 1 0 0.20964
+HETATM 199 C199 RES A 444 9.27176 16.96360 18.60348 C_3 4 0 0.03193
+HETATM 200 O200 RES A 444 10.16048 17.88001 19.23027 O_3 2 2 -0.39965
+HETATM 201 H201 RES A 444 8.24372 17.25233 18.82182 H_ 1 0 0.05269
+HETATM 202 H202 RES A 444 9.42846 16.97594 17.52377 H_ 1 0 0.05269
+HETATM 203 H203 RES A 444 9.45162 15.95835 18.98512 H_ 1 0 0.05269
+HETATM 204 H204 RES A 444 11.05433 17.57777 18.98374 H___A 1 0 0.20964
+HETATM 205 C205 RES A 444 19.02698 11.32629 8.74382 C_3 4 0 0.03193
+HETATM 206 O206 RES A 444 19.55395 11.57496 7.44476 O_3 2 2 -0.39965
+HETATM 207 H207 RES A 444 19.84306 11.28874 9.46486 H_ 1 0 0.05269
+HETATM 208 H208 RES A 444 18.34041 12.12651 9.02172 H_ 1 0 0.05269
+HETATM 209 H209 RES A 444 18.49941 10.37268 8.75573 H_ 1 0 0.05269
+HETATM 210 H210 RES A 444 18.77484 11.55877 6.84653 H___A 1 0 0.20964
+HETATM 211 C211 RES A 444 13.70984 17.91381 18.18096 C_3 4 0 0.03193
+HETATM 212 O212 RES A 444 12.78082 16.86629 18.42949 O_3 2 2 -0.39965
+HETATM 213 H213 RES A 444 14.65264 17.49419 17.82801 H_ 1 0 0.05269
+HETATM 214 H214 RES A 444 13.30579 18.58561 17.42320 H_ 1 0 0.05269
+HETATM 215 H215 RES A 444 13.88737 18.47185 19.10049 H_ 1 0 0.05269
+HETATM 216 H216 RES A 444 12.70938 16.39241 17.57615 H___A 1 0 0.20964
+HETATM 217 C217 RES A 444 7.96084 1.88854 9.90132 C_3 4 0 0.03193
+HETATM 218 O218 RES A 444 7.16836 0.76877 10.27166 O_3 2 2 -0.39965
+HETATM 219 H219 RES A 444 8.08701 1.90679 8.82000 H_ 1 0 0.05269
+HETATM 220 H220 RES A 444 7.47244 2.80930 10.22050 H_ 1 0 0.05269
+HETATM 221 H221 RES A 444 8.93667 1.81039 10.37952 H_ 1 0 0.05269
+HETATM 222 H222 RES A 444 6.33219 0.87991 9.77220 H___A 1 0 0.20964
+HETATM 223 C223 RES A 444 8.67989 16.70958 5.83790 C_3 4 0 0.03193
+HETATM 224 O224 RES A 444 8.12024 17.60224 6.79460 O_3 2 2 -0.39965
+HETATM 225 H225 RES A 444 8.09228 16.75013 4.91967 H_ 1 0 0.05269
+HETATM 226 H226 RES A 444 9.70728 17.00048 5.62151 H_ 1 0 0.05269
+HETATM 227 H227 RES A 444 8.66415 15.69153 6.22812 H_ 1 0 0.05269
+HETATM 228 H228 RES A 444 8.61953 17.44038 7.62546 H___A 1 0 0.20964
+HETATM 229 C229 RES A 444 8.92912 4.00904 0.50900 C_3 4 0 0.03193
+HETATM 230 O230 RES A 444 8.96759 5.27857 -0.13058 O_3 2 2 -0.39965
+HETATM 231 H231 RES A 444 8.33969 4.08141 1.42278 H_ 1 0 0.05269
+HETATM 232 H232 RES A 444 8.47682 3.27429 -0.15833 H_ 1 0 0.05269
+HETATM 233 H233 RES A 444 9.94193 3.69036 0.75961 H_ 1 0 0.05269
+HETATM 234 H234 RES A 444 9.53405 5.14064 -0.92363 H___A 1 0 0.20964
+HETATM 235 C235 RES A 444 14.12006 6.78048 11.59632 C_3 4 0 0.03193
+HETATM 236 O236 RES A 444 13.07688 7.13628 10.69542 O_3 2 2 -0.39965
+HETATM 237 H237 RES A 444 14.86068 7.57932 11.63302 H_ 1 0 0.05269
+HETATM 238 H238 RES A 444 13.70582 6.62813 12.59405 H_ 1 0 0.05269
+HETATM 239 H239 RES A 444 14.60290 5.86276 11.26001 H_ 1 0 0.05269
+HETATM 240 H240 RES A 444 12.46641 6.36815 10.68540 H___A 1 0 0.20964
+HETATM 241 C241 RES A 444 11.17366 12.60541 17.35410 C_3 4 0 0.03193
+HETATM 242 O242 RES A 444 11.02139 13.96786 17.73395 O_3 2 2 -0.39965
+HETATM 243 H243 RES A 444 10.47704 11.99021 17.92352 H_ 1 0 0.05269
+HETATM 244 H244 RES A 444 10.96097 12.49402 16.29011 H_ 1 0 0.05269
+HETATM 245 H245 RES A 444 12.19388 12.27752 17.55780 H_ 1 0 0.05269
+HETATM 246 H246 RES A 444 11.62997 14.46572 17.15437 H___A 1 0 0.20964
+HETATM 247 C247 RES A 444 13.59375 17.68257 6.60725 C_3 4 0 0.03193
+HETATM 248 O248 RES A 444 14.41796 18.19915 5.56896 O_3 2 2 -0.39965
+HETATM 249 H249 RES A 444 12.56750 17.59958 6.25257 H_ 1 0 0.05269
+HETATM 250 H250 RES A 444 13.95140 16.69610 6.90350 H_ 1 0 0.05269
+HETATM 251 H251 RES A 444 13.62441 18.35441 7.46523 H_ 1 0 0.05269
+HETATM 252 H252 RES A 444 15.31701 18.26489 5.96089 H___A 1 0 0.20964
+HETATM 253 C253 RES A 444 5.00550 8.70879 7.93082 C_3 4 0 0.03193
+HETATM 254 O254 RES A 444 5.30633 7.53730 7.17920 O_3 2 2 -0.39965
+HETATM 255 H255 RES A 444 3.92410 8.80228 8.03546 H_ 1 0 0.05269
+HETATM 256 H256 RES A 444 5.45973 8.64206 8.92134 H_ 1 0 0.05269
+HETATM 257 H257 RES A 444 5.39337 9.58812 7.41497 H_ 1 0 0.05269
+HETATM 258 H258 RES A 444 6.28240 7.52607 7.08649 H___A 1 0 0.20964
+HETATM 259 C259 RES A 444 19.22046 1.28969 13.91270 C_3 4 0 0.03193
+HETATM 260 O260 RES A 444 20.08805 2.12898 14.66921 O_3 2 2 -0.39965
+HETATM 261 H261 RES A 444 18.36269 1.87059 13.57299 H_ 1 0 0.05269
+HETATM 262 H262 RES A 444 19.74873 0.89208 13.04541 H_ 1 0 0.05269
+HETATM 263 H263 RES A 444 18.87095 0.46148 14.53042 H_ 1 0 0.05269
+HETATM 264 H264 RES A 444 20.73583 1.52580 15.09558 H___A 1 0 0.20964
+HETATM 265 C265 RES A 444 5.65052 5.42047 10.40141 C_3 4 0 0.03193
+HETATM 266 O266 RES A 444 6.43233 5.15576 11.55959 O_3 2 2 -0.39965
+HETATM 267 H267 RES A 444 4.77591 4.76790 10.40245 H_ 1 0 0.05269
+HETATM 268 H268 RES A 444 5.31750 6.45945 10.40208 H_ 1 0 0.05269
+HETATM 269 H269 RES A 444 6.23775 5.22771 9.50311 H_ 1 0 0.05269
+HETATM 270 H270 RES A 444 7.22334 5.73649 11.49818 H___A 1 0 0.20964
+HETATM 271 C271 RES A 444 13.28289 5.81639 20.26495 C_3 4 0 0.03193
+HETATM 272 O272 RES A 444 14.46108 5.91020 19.47306 O_3 2 2 -0.39965
+HETATM 273 H273 RES A 444 12.54449 6.53149 19.89956 H_ 1 0 0.05269
+HETATM 274 H274 RES A 444 12.86565 4.81041 20.20085 H_ 1 0 0.05269
+HETATM 275 H275 RES A 444 13.51599 6.04282 21.30628 H_ 1 0 0.05269
+HETATM 276 H276 RES A 444 15.06689 5.21681 19.82048 H___A 1 0 0.20964
+HETATM 277 C277 RES A 444 8.93119 18.18764 13.28407 C_3 4 0 0.03193
+HETATM 278 O278 RES A 444 7.83369 17.94987 14.15258 O_3 2 2 -0.39965
+HETATM 279 H279 RES A 444 8.62256 18.85058 12.47662 H_ 1 0 0.05269
+HETATM 280 H280 RES A 444 9.74951 18.65521 13.83984 H_ 1 0 0.05269
+HETATM 281 H281 RES A 444 9.27914 17.24313 12.85839 H_ 1 0 0.05269
+HETATM 282 H282 RES A 444 8.18034 17.33710 14.83873 H___A 1 0 0.20964
+HETATM 283 C283 RES A 444 5.79456 2.19968 17.80701 C_3 4 0 0.03193
+HETATM 284 O284 RES A 444 6.24133 2.96696 16.69489 O_3 2 2 -0.39965
+HETATM 285 H285 RES A 444 5.95925 2.76662 18.72146 H_ 1 0 0.05269
+HETATM 286 H286 RES A 444 4.73133 1.97951 17.70368 H_ 1 0 0.05269
+HETATM 287 H287 RES A 444 6.35360 1.26369 17.85787 H_ 1 0 0.05269
+HETATM 288 H288 RES A 444 6.11167 2.36984 15.93032 H___A 1 0 0.20964
+HETATM 289 C289 RES A 444 7.02257 8.31146 13.32419 C_3 4 0 0.03193
+HETATM 290 O290 RES A 444 6.81830 9.58617 13.92250 O_3 2 2 -0.39965
+HETATM 291 H291 RES A 444 6.70351 7.53159 14.01772 H_ 1 0 0.05269
+HETATM 292 H292 RES A 444 6.43819 8.23664 12.40602 H_ 1 0 0.05269
+HETATM 293 H293 RES A 444 8.08019 8.17829 13.09255 H_ 1 0 0.05269
+HETATM 294 H294 RES A 444 7.15181 10.23194 13.26245 H___A 1 0 0.20964
+HETATM 295 C295 RES A 444 14.02631 3.46938 16.96774 C_3 4 0 0.03193
+HETATM 296 O296 RES A 444 13.54366 2.24600 17.51611 O_3 2 2 -0.39965
+HETATM 297 H297 RES A 444 13.77498 3.53066 15.91013 H_ 1 0 0.05269
+HETATM 298 H298 RES A 444 13.56595 4.30739 17.48900 H_ 1 0 0.05269
+HETATM 299 H299 RES A 444 15.10861 3.52592 17.07904 H_ 1 0 0.05269
+HETATM 300 H300 RES A 444 13.94305 2.20406 18.41525 H___A 1 0 0.20964
+HETATM 301 C301 RES A 444 1.20831 18.57486 2.95108 C_3 4 0 0.03193
+HETATM 302 O302 RES A 444 1.22576 19.81993 2.26075 O_3 2 2 -0.39965
+HETATM 303 H303 RES A 444 0.55458 18.64320 3.82147 H_ 1 0 0.05269
+HETATM 304 H304 RES A 444 0.84728 17.78646 2.28798 H_ 1 0 0.05269
+HETATM 305 H305 RES A 444 2.21813 18.32995 3.28130 H_ 1 0 0.05269
+HETATM 306 H306 RES A 444 0.30364 19.97372 1.97883 H___A 1 0 0.20964
+HETATM 307 C307 RES A 444 13.27354 18.56828 10.67719 C_3 4 0 0.03193
+HETATM 308 O308 RES A 444 12.48821 17.54334 10.07841 O_3 2 2 -0.39965
+HETATM 309 H309 RES A 444 12.67535 19.47728 10.75867 H_ 1 0 0.05269
+HETATM 310 H310 RES A 444 13.59103 18.25289 11.67155 H_ 1 0 0.05269
+HETATM 311 H311 RES A 444 14.15208 18.77184 10.06448 H_ 1 0 0.05269
+HETATM 312 H312 RES A 444 13.09935 16.78781 9.93641 H___A 1 0 0.20964
+HETATM 313 C313 RES A 444 6.36730 14.29234 8.10345 C_3 4 0 0.03193
+HETATM 314 O314 RES A 444 6.40678 13.98673 6.71535 O_3 2 2 -0.39965
+HETATM 315 H315 RES A 444 5.36805 14.09806 8.49177 H_ 1 0 0.05269
+HETATM 316 H316 RES A 444 7.08832 13.66856 8.63166 H_ 1 0 0.05269
+HETATM 317 H317 RES A 444 6.61905 15.34196 8.25886 H_ 1 0 0.05269
+HETATM 318 H318 RES A 444 5.76587 14.60457 6.30951 H___A 1 0 0.20964
+HETATM 319 C319 RES A 444 2.65328 9.08063 11.58358 C_3 4 0 0.03193
+HETATM 320 O320 RES A 444 2.00217 9.04988 10.31818 O_3 2 2 -0.39965
+HETATM 321 H321 RES A 444 2.77179 8.06201 11.95511 H_ 1 0 0.05269
+HETATM 322 H322 RES A 444 3.63556 9.54427 11.48302 H_ 1 0 0.05269
+HETATM 323 H323 RES A 444 2.05382 9.65342 12.29226 H_ 1 0 0.05269
+HETATM 324 H324 RES A 444 1.90245 9.98881 10.05330 H___A 1 0 0.20964
+HETATM 325 C325 RES A 444 16.09537 13.47946 18.75299 C_3 4 0 0.03193
+HETATM 326 O326 RES A 444 15.35647 12.29789 19.02596 O_3 2 2 -0.39965
+HETATM 327 H327 RES A 444 15.44738 14.34606 18.88103 H_ 1 0 0.05269
+HETATM 328 H328 RES A 444 16.93959 13.54850 19.44072 H_ 1 0 0.05269
+HETATM 329 H329 RES A 444 16.46394 13.45617 17.72675 H_ 1 0 0.05269
+HETATM 330 H330 RES A 444 15.94172 11.56097 18.74998 H___A 1 0 0.20964
+HETATM 331 C331 RES A 444 5.36713 6.40841 19.02468 C_3 4 0 0.03193
+HETATM 332 O332 RES A 444 6.23337 6.92207 18.01801 O_3 2 2 -0.39965
+HETATM 333 H333 RES A 444 4.33549 6.65297 18.77623 H_ 1 0 0.05269
+HETATM 334 H334 RES A 444 5.47707 5.32425 19.08654 H_ 1 0 0.05269
+HETATM 335 H335 RES A 444 5.62819 6.85675 19.98559 H_ 1 0 0.05269
+HETATM 336 H336 RES A 444 7.13950 6.67949 18.31120 H___A 1 0 0.20964
+HETATM 337 C337 RES A 444 1.77513 13.81811 9.21198 C_3 4 0 0.03193
+HETATM 338 O338 RES A 444 0.83100 14.28966 10.16552 O_3 2 2 -0.39965
+HETATM 339 H339 RES A 444 1.29728 13.75593 8.23483 H_ 1 0 0.05269
+HETATM 340 H340 RES A 444 2.62178 14.50388 9.15673 H_ 1 0 0.05269
+HETATM 341 H341 RES A 444 2.12880 12.82836 9.50371 H_ 1 0 0.05269
+HETATM 342 H342 RES A 444 1.30194 14.30478 11.02173 H___A 1 0 0.20964
+HETATM 343 C343 RES A 444 21.59943 4.06368 17.75073 C_3 4 0 0.03193
+HETATM 344 O344 RES A 444 21.85233 3.04768 18.71336 O_3 2 2 -0.39965
+HETATM 345 H345 RES A 444 22.11092 3.81498 16.82008 H_ 1 0 0.05269
+HETATM 346 H346 RES A 444 20.52800 4.13659 17.56408 H_ 1 0 0.05269
+HETATM 347 H347 RES A 444 21.97071 5.01986 18.11886 H_ 1 0 0.05269
+HETATM 348 H348 RES A 444 21.40074 3.34325 19.53474 H___A 1 0 0.20964
+HETATM 349 C349 RES A 444 16.52622 4.73908 13.63762 C_3 4 0 0.03193
+HETATM 350 O350 RES A 444 15.55282 5.45454 14.38889 O_3 2 2 -0.39965
+HETATM 351 H351 RES A 444 16.03370 3.96708 13.04616 H_ 1 0 0.05269
+HETATM 352 H352 RES A 444 17.05262 5.42291 12.96909 H_ 1 0 0.05269
+HETATM 353 H353 RES A 444 17.24076 4.27126 14.31456 H_ 1 0 0.05269
+HETATM 354 H354 RES A 444 16.06701 6.07053 14.95693 H___A 1 0 0.20964
+HETATM 355 C355 RES A 444 20.20141 14.20302 18.50889 C_3 4 0 0.03193
+HETATM 356 O356 RES A 444 21.44729 13.78288 19.04009 O_3 2 2 -0.39965
+HETATM 357 H357 RES A 444 20.32931 15.13613 17.95996 H_ 1 0 0.05269
+HETATM 358 H358 RES A 444 19.81275 13.43791 17.83324 H_ 1 0 0.05269
+HETATM 359 H359 RES A 444 19.48848 14.36395 19.32079 H_ 1 0 0.05269
+HETATM 360 H360 RES A 444 21.25026 12.96615 19.54627 H___A 1 0 0.20964
+HETATM 361 C361 RES A 444 3.32298 14.94425 16.50422 C_3 4 0 0.03193
+HETATM 362 O362 RES A 444 4.38694 14.00670 16.37303 O_3 2 2 -0.39965
+HETATM 363 H363 RES A 444 3.54498 15.83135 15.91086 H_ 1 0 0.05269
+HETATM 364 H364 RES A 444 2.39143 14.50263 16.15017 H_ 1 0 0.05269
+HETATM 365 H365 RES A 444 3.21366 15.23418 17.54978 H_ 1 0 0.05269
+HETATM 366 H366 RES A 444 4.09659 13.20452 16.85511 H___A 1 0 0.20964
+HETATM 367 C367 RES A 444 10.00891 1.19780 16.80998 C_3 4 0 0.03193
+HETATM 368 O368 RES A 444 10.58951 1.67540 18.01757 O_3 2 2 -0.39965
+HETATM 369 H369 RES A 444 8.95573 0.97837 16.97853 H_ 1 0 0.05269
+HETATM 370 H370 RES A 444 10.09279 1.95889 16.03422 H_ 1 0 0.05269
+HETATM 371 H371 RES A 444 10.51430 0.28729 16.48583 H_ 1 0 0.05269
+HETATM 372 H372 RES A 444 11.54632 1.78202 17.83462 H___A 1 0 0.20964
+HETATM 373 C373 RES A 444 1.31776 5.21190 2.64974 C_3 4 0 0.03193
+HETATM 374 O374 RES A 444 0.78156 4.20400 1.79964 O_3 2 2 -0.39965
+HETATM 375 H375 RES A 444 2.00060 5.84322 2.08036 H_ 1 0 0.05269
+HETATM 376 H376 RES A 444 0.50993 5.82499 3.05018 H_ 1 0 0.05269
+HETATM 377 H377 RES A 444 1.85905 4.74873 3.47448 H_ 1 0 0.05269
+HETATM 378 H378 RES A 444 0.20631 3.65922 2.38482 H___A 1 0 0.20964
+HETATM 379 C379 RES A 444 5.74906 1.64126 13.27894 C_3 4 0 0.03193
+HETATM 380 O380 RES A 444 5.74933 0.96366 14.53304 O_3 2 2 -0.39965
+HETATM 381 H381 RES A 444 5.05775 2.48272 13.31880 H_ 1 0 0.05269
+HETATM 382 H382 RES A 444 6.74849 2.01315 13.05234 H_ 1 0 0.05269
+HETATM 383 H383 RES A 444 5.43187 0.95557 12.49248 H_ 1 0 0.05269
+HETATM 384 H384 RES A 444 6.42516 0.25912 14.43537 H___A 1 0 0.20964
+FORMAT CONECT (a6,12i6)
+CONECT 1 2 3 4 5
+CONECT 2 1 6
+CONECT 3 1
+CONECT 4 1
+CONECT 5 1
+CONECT 6 2
+CONECT 7 8 9 10 11
+CONECT 8 7 12
+CONECT 9 7
+CONECT 10 7
+CONECT 11 7
+CONECT 12 8
+CONECT 13 14 15 16 17
+CONECT 14 13 18
+CONECT 15 13
+CONECT 16 13
+CONECT 17 13
+CONECT 18 14
+CONECT 19 20 21 22 23
+CONECT 20 19 24
+CONECT 21 19
+CONECT 22 19
+CONECT 23 19
+CONECT 24 20
+CONECT 25 26 27 28 29
+CONECT 26 25 30
+CONECT 27 25
+CONECT 28 25
+CONECT 29 25
+CONECT 30 26
+CONECT 31 32 33 34 35
+CONECT 32 31 36
+CONECT 33 31
+CONECT 34 31
+CONECT 35 31
+CONECT 36 32
+CONECT 37 38 39 40 41
+CONECT 38 37 42
+CONECT 39 37
+CONECT 40 37
+CONECT 41 37
+CONECT 42 38
+CONECT 43 44 45 46 47
+CONECT 44 43 48
+CONECT 45 43
+CONECT 46 43
+CONECT 47 43
+CONECT 48 44
+CONECT 49 50 51 52 53
+CONECT 50 49 54
+CONECT 51 49
+CONECT 52 49
+CONECT 53 49
+CONECT 54 50
+CONECT 55 56 57 58 59
+CONECT 56 55 60
+CONECT 57 55
+CONECT 58 55
+CONECT 59 55
+CONECT 60 56
+CONECT 61 62 63 64 65
+CONECT 62 61 66
+CONECT 63 61
+CONECT 64 61
+CONECT 65 61
+CONECT 66 62
+CONECT 67 68 69 70 71
+CONECT 68 67 72
+CONECT 69 67
+CONECT 70 67
+CONECT 71 67
+CONECT 72 68
+CONECT 73 74 75 76 77
+CONECT 74 73 78
+CONECT 75 73
+CONECT 76 73
+CONECT 77 73
+CONECT 78 74
+CONECT 79 80 81 82 83
+CONECT 80 79 84
+CONECT 81 79
+CONECT 82 79
+CONECT 83 79
+CONECT 84 80
+CONECT 85 86 87 88 89
+CONECT 86 85 90
+CONECT 87 85
+CONECT 88 85
+CONECT 89 85
+CONECT 90 86
+CONECT 91 92 93 94 95
+CONECT 92 91 96
+CONECT 93 91
+CONECT 94 91
+CONECT 95 91
+CONECT 96 92
+CONECT 97 98 99 100 101
+CONECT 98 97 102
+CONECT 99 97
+CONECT 100 97
+CONECT 101 97
+CONECT 102 98
+CONECT 103 104 105 106 107
+CONECT 104 103 108
+CONECT 105 103
+CONECT 106 103
+CONECT 107 103
+CONECT 108 104
+CONECT 109 110 111 112 113
+CONECT 110 109 114
+CONECT 111 109
+CONECT 112 109
+CONECT 113 109
+CONECT 114 110
+CONECT 115 116 117 118 119
+CONECT 116 115 120
+CONECT 117 115
+CONECT 118 115
+CONECT 119 115
+CONECT 120 116
+CONECT 121 122 123 124 125
+CONECT 122 121 126
+CONECT 123 121
+CONECT 124 121
+CONECT 125 121
+CONECT 126 122
+CONECT 127 128 129 130 131
+CONECT 128 127 132
+CONECT 129 127
+CONECT 130 127
+CONECT 131 127
+CONECT 132 128
+CONECT 133 134 135 136 137
+CONECT 134 133 138
+CONECT 135 133
+CONECT 136 133
+CONECT 137 133
+CONECT 138 134
+CONECT 139 140 141 142 143
+CONECT 140 139 144
+CONECT 141 139
+CONECT 142 139
+CONECT 143 139
+CONECT 144 140
+CONECT 145 146 147 148 149
+CONECT 146 145 150
+CONECT 147 145
+CONECT 148 145
+CONECT 149 145
+CONECT 150 146
+CONECT 151 152 153 154 155
+CONECT 152 151 156
+CONECT 153 151
+CONECT 154 151
+CONECT 155 151
+CONECT 156 152
+CONECT 157 158 159 160 161
+CONECT 158 157 162
+CONECT 159 157
+CONECT 160 157
+CONECT 161 157
+CONECT 162 158
+CONECT 163 164 165 166 167
+CONECT 164 163 168
+CONECT 165 163
+CONECT 166 163
+CONECT 167 163
+CONECT 168 164
+CONECT 169 170 171 172 173
+CONECT 170 169 174
+CONECT 171 169
+CONECT 172 169
+CONECT 173 169
+CONECT 174 170
+CONECT 175 176 177 178 179
+CONECT 176 175 180
+CONECT 177 175
+CONECT 178 175
+CONECT 179 175
+CONECT 180 176
+CONECT 181 182 183 184 185
+CONECT 182 181 186
+CONECT 183 181
+CONECT 184 181
+CONECT 185 181
+CONECT 186 182
+CONECT 187 188 189 190 191
+CONECT 188 187 192
+CONECT 189 187
+CONECT 190 187
+CONECT 191 187
+CONECT 192 188
+CONECT 193 194 195 196 197
+CONECT 194 193 198
+CONECT 195 193
+CONECT 196 193
+CONECT 197 193
+CONECT 198 194
+CONECT 199 200 201 202 203
+CONECT 200 199 204
+CONECT 201 199
+CONECT 202 199
+CONECT 203 199
+CONECT 204 200
+CONECT 205 206 207 208 209
+CONECT 206 205 210
+CONECT 207 205
+CONECT 208 205
+CONECT 209 205
+CONECT 210 206
+CONECT 211 212 213 214 215
+CONECT 212 211 216
+CONECT 213 211
+CONECT 214 211
+CONECT 215 211
+CONECT 216 212
+CONECT 217 218 219 220 221
+CONECT 218 217 222
+CONECT 219 217
+CONECT 220 217
+CONECT 221 217
+CONECT 222 218
+CONECT 223 224 225 226 227
+CONECT 224 223 228
+CONECT 225 223
+CONECT 226 223
+CONECT 227 223
+CONECT 228 224
+CONECT 229 230 231 232 233
+CONECT 230 229 234
+CONECT 231 229
+CONECT 232 229
+CONECT 233 229
+CONECT 234 230
+CONECT 235 236 237 238 239
+CONECT 236 235 240
+CONECT 237 235
+CONECT 238 235
+CONECT 239 235
+CONECT 240 236
+CONECT 241 242 243 244 245
+CONECT 242 241 246
+CONECT 243 241
+CONECT 244 241
+CONECT 245 241
+CONECT 246 242
+CONECT 247 248 249 250 251
+CONECT 248 247 252
+CONECT 249 247
+CONECT 250 247
+CONECT 251 247
+CONECT 252 248
+CONECT 253 254 255 256 257
+CONECT 254 253 258
+CONECT 255 253
+CONECT 256 253
+CONECT 257 253
+CONECT 258 254
+CONECT 259 260 261 262 263
+CONECT 260 259 264
+CONECT 261 259
+CONECT 262 259
+CONECT 263 259
+CONECT 264 260
+CONECT 265 266 267 268 269
+CONECT 266 265 270
+CONECT 267 265
+CONECT 268 265
+CONECT 269 265
+CONECT 270 266
+CONECT 271 272 273 274 275
+CONECT 272 271 276
+CONECT 273 271
+CONECT 274 271
+CONECT 275 271
+CONECT 276 272
+CONECT 277 278 279 280 281
+CONECT 278 277 282
+CONECT 279 277
+CONECT 280 277
+CONECT 281 277
+CONECT 282 278
+CONECT 283 284 285 286 287
+CONECT 284 283 288
+CONECT 285 283
+CONECT 286 283
+CONECT 287 283
+CONECT 288 284
+CONECT 289 290 291 292 293
+CONECT 290 289 294
+CONECT 291 289
+CONECT 292 289
+CONECT 293 289
+CONECT 294 290
+CONECT 295 296 297 298 299
+CONECT 296 295 300
+CONECT 297 295
+CONECT 298 295
+CONECT 299 295
+CONECT 300 296
+CONECT 301 302 303 304 305
+CONECT 302 301 306
+CONECT 303 301
+CONECT 304 301
+CONECT 305 301
+CONECT 306 302
+CONECT 307 308 309 310 311
+CONECT 308 307 312
+CONECT 309 307
+CONECT 310 307
+CONECT 311 307
+CONECT 312 308
+CONECT 313 314 315 316 317
+CONECT 314 313 318
+CONECT 315 313
+CONECT 316 313
+CONECT 317 313
+CONECT 318 314
+CONECT 319 320 321 322 323
+CONECT 320 319 324
+CONECT 321 319
+CONECT 322 319
+CONECT 323 319
+CONECT 324 320
+CONECT 325 326 327 328 329
+CONECT 326 325 330
+CONECT 327 325
+CONECT 328 325
+CONECT 329 325
+CONECT 330 326
+CONECT 331 332 333 334 335
+CONECT 332 331 336
+CONECT 333 331
+CONECT 334 331
+CONECT 335 331
+CONECT 336 332
+CONECT 337 338 339 340 341
+CONECT 338 337 342
+CONECT 339 337
+CONECT 340 337
+CONECT 341 337
+CONECT 342 338
+CONECT 343 344 345 346 347
+CONECT 344 343 348
+CONECT 345 343
+CONECT 346 343
+CONECT 347 343
+CONECT 348 344
+CONECT 349 350 351 352 353
+CONECT 350 349 354
+CONECT 351 349
+CONECT 352 349
+CONECT 353 349
+CONECT 354 350
+CONECT 355 356 357 358 359
+CONECT 356 355 360
+CONECT 357 355
+CONECT 358 355
+CONECT 359 355
+CONECT 360 356
+CONECT 361 362 363 364 365
+CONECT 362 361 366
+CONECT 363 361
+CONECT 364 361
+CONECT 365 361
+CONECT 366 362
+CONECT 367 368 369 370 371
+CONECT 368 367 372
+CONECT 369 367
+CONECT 370 367
+CONECT 371 367
+CONECT 372 368
+CONECT 373 374 375 376 377
+CONECT 374 373 378
+CONECT 375 373
+CONECT 376 373
+CONECT 377 373
+CONECT 378 374
+CONECT 379 380 381 382 383
+CONECT 380 379 384
+CONECT 381 379
+CONECT 382 379
+CONECT 383 379
+CONECT 384 380
+END
diff --git a/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat
new file mode 100644
index 0000000000..b856598735
--- /dev/null
+++ b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat
@@ -0,0 +1,56 @@
+Energy expression created for 3D-periodic boundary conditions.
+ Cell information:
+ Density (g/cc): 0.4573
+ Volume (A**3): 7447.2363
+ A: 19.9969 Alpha: 90.0000
+ B: 19.1282 Beta : 90.0000
+ C: 19.4697 Gamma: 90.0000
+
+ Summary of the energy expression:
+ Movable atoms : 384 Fixed atoms : 0
+ Polar atoms : 0
+ Bonds : 320 Angles : 448
+ Torsions : 192 Inversions : 0
+ Urey-Bradley : 0 Bend-bend : 0
+ Stretch-stretch : 0 Sep-stretch-stretch : 0
+ Stretch-bend-stretch : 0 Torsion-stretch : 0
+ Torsion-bend-bend : 0 Stretch-torsion-stretch: 0
+ Bend-torsion-bend : 0
+ Hydrogen-bond acceptors: 64 Hydrogen-bond donors : 64
+ Nonbond exclusions : 768 Polar-polar exclusions : 0
+
+ Total charge : -0.001 Movable atoms only : -0.001
+ Total mass : 2050.688 Movable atoms only : 2050.688
+
+Automatically calculating Ewald parameters for Coulomb sum.
+
+Summary of Non-bond set up :-
+ Non-bond list cutoff radius : 13.530 (A)
+ Number of non-bond terms in list : 101788
+ This has been updated 1 times since the energy expression was created.
+
+ Using Ewald sums for Coulomb terms with:
+ Eta=3.932, Rcut=11.530, Kcut=0.298, Acc.=0.001
+
+VDW terms truncated at : 8.500 (A)
+
+Diagonal VdW parameters combined using the arithmetic combination rule.
+
+Summary of H-bond set up using a h-bond list.
+
+There are 604 interactions within hbond cutoffs of
+ Donor-acceptor distances less than 6.500 (A) and
+ Donor-h-acceptor angles greater than 90.000 (degrees)
+
+************************************************************************
+ Energy Decomposition
+ Valence Terms Nonbond Terms
+ Bonds : 0.535675 Van der Waals : -56.0592
+ Angles : 1.28188 Electrostatic : 234.036
+ Torsions : 1.23250 Hydrogen Bonds: -68.7337
+ Inversions : 0.000000E+00 Restraints : 0.000000E+00
+ Urey-Bradley : 0.000000E+00 3-Body : 0.000000E+00
+ Cross-Terms : 0.000000E+00
+ Total Energy : 112.293
+************************************************************************
+
diff --git a/examples/dreiding/data.dreiding b/examples/dreiding/data.dreiding
new file mode 100644
index 0000000000..f6d9bcf22d
--- /dev/null
+++ b/examples/dreiding/data.dreiding
@@ -0,0 +1,1400 @@
+Created on Mon Oct 3 10:06:14 2011
+
+ 384 atoms
+ 320 bonds
+ 448 angles
+ 192 dihedrals
+ 0 impropers
+
+ 4 atom types
+ 3 bond types
+ 2 angle types
+ 1 dihedral types
+ 0 improper types
+
+ 0.000000 19.996890 xlo xhi
+ 0.000000 19.128160 ylo yhi
+ 0.000000 19.469710 zlo zhi
+
+Masses
+
+ 1 1.0080 # H_
+ 2 1.0080 # H___A
+ 3 12.0110 # C_3
+ 4 15.9994 # O_3
+
+
+Bond Coeffs
+
+ 1 350 1.42 # O_3 C_3
+ 2 350 0.98 # O_3 H___A
+ 3 350 1.09 # C_3 H_
+
+Angle Coeffs
+
+ 1 50 104.51 # X O_3 X
+ 2 50 109.471 # X C_3 X
+
+Dihedral Coeffs
+
+ 1 0.333333 1 3 # X O_3 C_3 X
+
+Atoms
+
+ 1 444 3 0.03193 9.75768 9.43603 9.44978 0 0 0
+ 2 444 4 -0.39965 9.07001 9.89252 10.61030 0 0 0
+ 3 444 1 0.05269 9.56169 8.37372 9.30573 0 0 0
+ 4 444 1 0.05269 9.40633 9.98872 8.57739 0 0 0
+ 5 444 1 0.05269 10.83081 9.58873 9.56849 0 0 0
+ 6 444 2 0.20964 9.28861 10.84826 10.67569 0 0 0
+ 7 444 3 0.03193 7.87790 6.57305 4.37926 0 0 0
+ 8 444 4 -0.39965 9.21046 6.55811 3.88167 0 0 0
+ 9 444 1 0.05269 7.42565 7.54437 4.17519 0 0 0
+ 10 444 1 0.05269 7.28908 5.79550 3.89029 0 0 0
+ 11 444 1 0.05269 7.88159 6.39628 5.45605 0 0 0
+ 12 444 2 0.20964 9.55621 5.66386 4.09964 0 0 0
+ 13 444 3 0.03193 19.38728 8.01844 0.29841 0 0 0
+ 14 444 4 -0.39965 18.30059 8.67235 0.94403 0 0 0
+ 15 444 1 0.05269 20.09420 7.66052 1.04704 0 0 0
+ 16 444 1 0.05269 19.01558 7.17130 -0.27928 0 0 0
+ 17 444 1 0.05269 19.89453 8.71684 -0.36839 0 0 0
+ 18 444 2 0.20964 17.72537 8.98355 0.21436 0 0 0
+ 19 444 3 0.03193 3.43963 14.29741 12.62221 0 0 0
+ 20 444 4 -0.39965 3.07671 15.61822 12.23631 0 0 0
+ 21 444 1 0.05269 4.27302 14.34187 13.32349 0 0 0
+ 22 444 1 0.05269 2.59308 13.81008 13.10508 0 0 0
+ 23 444 1 0.05269 3.73991 13.72415 11.74356 0 0 0
+ 24 444 2 0.20964 2.32966 15.52033 11.61130 0 0 0
+ 25 444 3 0.03193 16.06751 17.84957 14.39706 0 0 0
+ 26 444 4 -0.39965 15.98970 19.07282 15.11734 0 0 0
+ 27 444 1 0.05269 16.77526 17.18402 14.89204 0 0 0
+ 28 444 1 0.05269 15.08510 17.37867 14.36938 0 0 0
+ 29 444 1 0.05269 16.40684 18.04085 13.37809 0 0 0
+ 30 444 2 0.20964 15.35997 19.62900 14.61094 0 0 0
+ 31 444 3 0.03193 5.61540 13.90261 0.28024 0 0 0
+ 32 444 4 -0.39965 6.96329 14.33980 0.39819 0 0 0
+ 33 444 1 0.05269 5.39381 13.18200 1.06831 0 0 0
+ 34 444 1 0.05269 4.93854 14.75467 0.36989 0 0 0
+ 35 444 1 0.05269 5.46825 13.42632 -0.68848 0 0 0
+ 36 444 2 0.20964 7.08381 14.99923 -0.31851 0 0 0
+ 37 444 3 0.03193 10.38444 13.74977 1.74423 0 0 0
+ 38 444 4 -0.39965 10.34865 13.00890 2.96031 0 0 0
+ 39 444 1 0.05269 11.31498 14.30998 1.68756 0 0 0
+ 40 444 1 0.05269 10.32135 13.06875 0.89580 0 0 0
+ 41 444 1 0.05269 9.54190 14.44190 1.71309 0 0 0
+ 42 444 2 0.20964 9.45315 12.60486 2.98815 0 0 0
+ 43 444 3 0.03193 2.71877 -0.19852 13.91482 0 0 0
+ 44 444 4 -0.39965 2.55981 1.00656 13.16980 0 0 0
+ 45 444 1 0.05269 3.42887 -0.85053 13.40421 0 0 0
+ 46 444 1 0.05269 3.09835 0.02977 14.91227 0 0 0
+ 47 444 1 0.05269 1.76062 -0.71177 13.99933 0 0 0
+ 48 444 2 0.20964 1.92580 1.55260 13.68058 0 0 0
+ 49 444 3 0.03193 12.86271 12.87291 9.10254 0 0 0
+ 50 444 4 -0.39965 12.72964 12.19590 7.85730 0 0 0
+ 51 444 1 0.05269 11.91715 12.83126 9.64447 0 0 0
+ 52 444 1 0.05269 13.63913 12.39659 9.70188 0 0 0
+ 53 444 1 0.05269 13.12955 13.91577 8.92585 0 0 0
+ 54 444 2 0.20964 13.60640 12.28637 7.42000 0 0 0
+ 55 444 3 0.03193 0.91345 1.84436 7.21758 0 0 0
+ 56 444 4 -0.39965 0.16704 0.83109 7.88260 0 0 0
+ 57 444 1 0.05269 1.73149 1.39473 6.65448 0 0 0
+ 58 444 1 0.05269 0.25949 2.38287 6.53090 0 0 0
+ 59 444 1 0.05269 1.31674 2.54212 7.95173 0 0 0
+ 60 444 2 0.20964 0.79209 0.41480 8.51642 0 0 0
+ 61 444 3 0.03193 3.28235 16.40235 6.34784 0 0 0
+ 62 444 4 -0.39965 4.40446 15.86811 5.64397 0 0 0
+ 63 444 1 0.05269 3.52775 16.47384 7.40940 0 0 0
+ 64 444 1 0.05269 3.04852 17.39543 5.96551 0 0 0
+ 65 444 1 0.05269 2.41989 15.75077 6.22278 0 0 0
+ 66 444 2 0.20964 4.15040 15.88018 4.69552 0 0 0
+ 67 444 3 0.03193 14.28685 11.84833 2.69644 0 0 0
+ 68 444 4 -0.39965 14.47540 12.00775 4.09802 0 0 0
+ 69 444 1 0.05269 15.22519 11.52503 2.24449 0 0 0
+ 70 444 1 0.05269 13.51978 11.09713 2.50925 0 0 0
+ 71 444 1 0.05269 13.98187 12.79680 2.25228 0 0 0
+ 72 444 2 0.20964 13.60420 12.29868 4.44979 0 0 0
+ 73 444 3 0.03193 3.74650 0.37490 9.28202 0 0 0
+ 74 444 4 -0.39965 4.68624 1.26369 8.68537 0 0 0
+ 75 444 1 0.05269 4.28178 -0.38700 9.84868 0 0 0
+ 76 444 1 0.05269 3.08874 0.92642 9.95440 0 0 0
+ 77 444 1 0.05269 3.15691 -0.10643 8.50276 0 0 0
+ 78 444 2 0.20964 4.15269 1.92251 8.18619 0 0 0
+ 79 444 3 0.03193 17.93191 1.98830 17.28592 0 0 0
+ 80 444 4 -0.39965 16.68990 1.36769 17.60090 0 0 0
+ 81 444 1 0.05269 18.23740 2.63433 18.10865 0 0 0
+ 82 444 1 0.05269 18.69345 1.22519 17.12938 0 0 0
+ 83 444 1 0.05269 17.82727 2.59026 16.38313 0 0 0
+ 84 444 2 0.20964 16.45659 0.83462 16.81232 0 0 0
+ 85 444 3 0.03193 4.61466 10.52979 17.10957 0 0 0
+ 86 444 4 -0.39965 3.62035 11.42538 17.60198 0 0 0
+ 87 444 1 0.05269 5.60177 10.98718 17.19552 0 0 0
+ 88 444 1 0.05269 4.60514 9.60666 17.68872 0 0 0
+ 89 444 1 0.05269 4.42040 10.30112 16.06086 0 0 0
+ 90 444 2 0.20964 2.76200 10.96432 17.46823 0 0 0
+ 91 444 3 0.03193 4.21479 2.76452 1.93621 0 0 0
+ 92 444 4 -0.39965 3.45640 2.43822 3.09183 0 0 0
+ 93 444 1 0.05269 5.15561 3.22498 2.23935 0 0 0
+ 94 444 1 0.05269 4.42333 1.85922 1.36296 0 0 0
+ 95 444 1 0.05269 3.65868 3.46500 1.31342 0 0 0
+ 96 444 2 0.20964 2.68968 1.92747 2.75853 0 0 0
+ 97 444 3 0.03193 2.10781 10.76856 1.36312 0 0 0
+ 98 444 4 -0.39965 0.80698 11.27394 1.07892 0 0 0
+ 99 444 1 0.05269 2.85114 11.53660 1.14272 0 0 0
+ 100 444 1 0.05269 2.17873 10.49350 2.41651 0 0 0
+ 101 444 1 0.05269 2.31220 9.89096 0.74802 0 0 0
+ 102 444 2 0.20964 0.18009 10.55168 1.30975 0 0 0
+ 103 444 3 0.03193 16.26093 8.92927 6.57643 0 0 0
+ 104 444 4 -0.39965 15.77968 8.06983 7.60177 0 0 0
+ 105 444 1 0.05269 17.30509 9.17300 6.76897 0 0 0
+ 106 444 1 0.05269 16.18069 8.42876 5.61195 0 0 0
+ 107 444 1 0.05269 15.67380 9.84869 6.55835 0 0 0
+ 108 444 2 0.20964 14.84042 7.91008 7.37720 0 0 0
+ 109 444 3 0.03193 17.80004 2.06792 1.87371 0 0 0
+ 110 444 4 -0.39965 18.48862 0.99081 1.24012 0 0 0
+ 111 444 1 0.05269 18.23871 2.25534 2.85453 0 0 0
+ 112 444 1 0.05269 17.87937 2.96817 1.26859 0 0 0
+ 113 444 1 0.05269 16.74643 1.80633 1.99693 0 0 0
+ 114 444 2 0.20964 18.02202 0.85350 0.38356 0 0 0
+ 115 444 3 0.03193 13.75521 14.57173 15.42181 0 0 0
+ 116 444 4 -0.39965 12.73183 15.48504 15.80455 0 0 0
+ 117 444 1 0.05269 14.51862 14.53760 16.20019 0 0 0
+ 118 444 1 0.05269 13.33164 13.57618 15.29114 0 0 0
+ 119 444 1 0.05269 14.21175 14.89091 14.48437 0 0 0
+ 120 444 2 0.20964 12.11746 15.52768 15.03694 0 0 0
+ 121 444 3 0.03193 6.22569 16.46321 11.49168 0 0 0
+ 122 444 4 -0.39965 7.37834 15.65849 11.27192 0 0 0
+ 123 444 1 0.05269 6.47325 17.50688 11.31115 0 0 0
+ 124 444 1 0.05269 5.42639 16.16714 10.80967 0 0 0
+ 125 444 1 0.05269 5.88670 16.35324 12.52283 0 0 0
+ 126 444 2 0.20964 7.09224 14.73066 11.41776 0 0 0
+ 127 444 3 0.03193 20.01012 9.33317 4.86657 0 0 0
+ 128 444 4 -0.39965 19.63827 8.14994 5.56401 0 0 0
+ 129 444 1 0.05269 20.82510 9.82112 5.40128 0 0 0
+ 130 444 1 0.05269 20.34186 9.07963 3.85908 0 0 0
+ 131 444 1 0.05269 19.16051 10.01349 4.80673 0 0 0
+ 132 444 2 0.20964 18.86130 7.79949 5.07585 0 0 0
+ 133 444 3 0.03193 5.99486 1.97634 5.72513 0 0 0
+ 134 444 4 -0.39965 6.74021 3.13466 6.08586 0 0 0
+ 135 444 1 0.05269 4.92875 2.19578 5.79288 0 0 0
+ 136 444 1 0.05269 6.23376 1.68432 4.70221 0 0 0
+ 137 444 1 0.05269 6.23815 1.15441 6.40034 0 0 0
+ 138 444 2 0.20964 7.67684 2.83917 6.07790 0 0 0
+ 139 444 3 0.03193 13.03835 7.12913 5.28770 0 0 0
+ 140 444 4 -0.39965 13.02644 7.55487 6.64544 0 0 0
+ 141 444 1 0.05269 12.06949 6.70203 5.02747 0 0 0
+ 142 444 1 0.05269 13.24117 7.98172 4.63978 0 0 0
+ 143 444 1 0.05269 13.81531 6.37647 5.14697 0 0 0
+ 144 444 2 0.20964 12.38966 8.29858 6.65964 0 0 0
+ 145 444 3 0.03193 10.64649 1.42163 6.99575 0 0 0
+ 146 444 4 -0.39965 11.32932 1.55767 8.23581 0 0 0
+ 147 444 1 0.05269 9.77461 0.78340 7.13967 0 0 0
+ 148 444 1 0.05269 10.32031 2.40213 6.64261 0 0 0
+ 149 444 1 0.05269 11.30461 0.96891 6.25436 0 0 0
+ 150 444 2 0.20964 12.13048 2.09412 8.04749 0 0 0
+ 151 444 3 0.03193 7.70974 10.56643 0.43745 0 0 0
+ 152 444 4 -0.39965 6.69643 10.25499 1.38817 0 0 0
+ 153 444 1 0.05269 8.59868 10.91732 0.96199 0 0 0
+ 154 444 1 0.05269 7.96121 9.67471 -0.13665 0 0 0
+ 155 444 1 0.05269 7.36428 11.34806 -0.24011 0 0 0
+ 156 444 2 0.20964 5.94241 9.89154 0.87302 0 0 0
+ 157 444 3 0.03193 12.78344 1.18067 14.16301 0 0 0
+ 158 444 4 -0.39965 14.01647 1.62010 13.60417 0 0 0
+ 159 444 1 0.05269 12.98217 0.47776 14.97222 0 0 0
+ 160 444 1 0.05269 12.23227 2.03435 14.55662 0 0 0
+ 161 444 1 0.05269 12.18352 0.68832 13.39874 0 0 0
+ 162 444 2 0.20964 13.77530 2.26070 12.89474 0 0 0
+ 163 444 3 0.03193 16.94139 17.42253 1.05686 0 0 0
+ 164 444 4 -0.39965 16.08424 16.29569 1.04946 0 0 0
+ 165 444 1 0.05269 17.18791 17.69368 0.02960 0 0 0
+ 166 444 1 0.05269 16.43795 18.25970 1.54236 0 0 0
+ 167 444 1 0.05269 17.85566 17.18021 1.60025 0 0 0
+ 168 444 2 0.20964 15.85827 16.14412 1.99459 0 0 0
+ 169 444 3 0.03193 12.48878 18.07306 2.58158 0 0 0
+ 170 444 4 -0.39965 13.76343 18.70451 2.65479 0 0 0
+ 171 444 1 0.05269 12.02971 18.30966 1.62310 0 0 0
+ 172 444 1 0.05269 12.61189 16.99304 2.67149 0 0 0
+ 173 444 1 0.05269 11.85062 18.43623 3.38623 0 0 0
+ 174 444 2 0.20964 14.05960 18.54980 3.57438 0 0 0
+ 175 444 3 0.03193 19.92937 14.32320 3.09954 0 0 0
+ 176 444 4 -0.39965 20.47921 14.98239 4.23349 0 0 0
+ 177 444 1 0.05269 19.06424 14.88021 2.74247 0 0 0
+ 178 444 1 0.05269 20.67424 14.26863 2.30532 0 0 0
+ 179 444 1 0.05269 19.62003 13.31457 3.37662 0 0 0
+ 180 444 2 0.20964 21.24382 14.42340 4.50083 0 0 0
+ 181 444 3 0.03193 10.63009 10.62036 5.48247 0 0 0
+ 182 444 4 -0.39965 11.32080 9.96459 6.53930 0 0 0
+ 183 444 1 0.05269 9.97896 9.90801 4.97371 0 0 0
+ 184 444 1 0.05269 10.02580 11.43533 5.88411 0 0 0
+ 185 444 1 0.05269 11.34799 11.02578 4.76860 0 0 0
+ 186 444 2 0.20964 11.85790 10.67095 6.95281 0 0 0
+ 187 444 3 0.03193 15.65699 9.09727 17.99408 0 0 0
+ 188 444 4 -0.39965 16.90142 9.78939 17.98916 0 0 0
+ 189 444 1 0.05269 15.04412 9.44428 18.82685 0 0 0
+ 190 444 1 0.05269 15.12611 9.28242 17.05809 0 0 0
+ 191 444 1 0.05269 15.82887 8.02576 18.10423 0 0 0
+ 192 444 2 0.20964 17.40700 9.38003 17.24481 0 0 0
+ 193 444 3 0.03193 17.18063 5.09511 5.97377 0 0 0
+ 194 444 4 -0.39965 17.00699 3.69621 6.16625 0 0 0
+ 195 444 1 0.05269 16.80087 5.38050 4.99222 0 0 0
+ 196 444 1 0.05269 16.63290 5.63866 6.74297 0 0 0
+ 197 444 1 0.05269 18.23947 5.34654 6.03632 0 0 0
+ 198 444 2 0.20964 17.37922 3.51369 7.05728 0 0 0
+ 199 444 3 0.03193 9.27176 16.96360 18.60348 0 0 0
+ 200 444 4 -0.39965 10.16048 17.88001 19.23027 0 0 0
+ 201 444 1 0.05269 8.24372 17.25233 18.82182 0 0 0
+ 202 444 1 0.05269 9.42846 16.97594 17.52377 0 0 0
+ 203 444 1 0.05269 9.45162 15.95835 18.98512 0 0 0
+ 204 444 2 0.20964 11.05433 17.57777 18.98374 0 0 0
+ 205 444 3 0.03193 19.02698 11.32629 8.74382 0 0 0
+ 206 444 4 -0.39965 19.55395 11.57496 7.44476 0 0 0
+ 207 444 1 0.05269 19.84306 11.28874 9.46486 0 0 0
+ 208 444 1 0.05269 18.34041 12.12651 9.02172 0 0 0
+ 209 444 1 0.05269 18.49941 10.37268 8.75573 0 0 0
+ 210 444 2 0.20964 18.77484 11.55877 6.84653 0 0 0
+ 211 444 3 0.03193 13.70984 17.91381 18.18096 0 0 0
+ 212 444 4 -0.39965 12.78082 16.86629 18.42949 0 0 0
+ 213 444 1 0.05269 14.65264 17.49419 17.82801 0 0 0
+ 214 444 1 0.05269 13.30579 18.58561 17.42320 0 0 0
+ 215 444 1 0.05269 13.88737 18.47185 19.10049 0 0 0
+ 216 444 2 0.20964 12.70938 16.39241 17.57615 0 0 0
+ 217 444 3 0.03193 7.96084 1.88854 9.90132 0 0 0
+ 218 444 4 -0.39965 7.16836 0.76877 10.27166 0 0 0
+ 219 444 1 0.05269 8.08701 1.90679 8.82000 0 0 0
+ 220 444 1 0.05269 7.47244 2.80930 10.22050 0 0 0
+ 221 444 1 0.05269 8.93667 1.81039 10.37952 0 0 0
+ 222 444 2 0.20964 6.33219 0.87991 9.77220 0 0 0
+ 223 444 3 0.03193 8.67989 16.70958 5.83790 0 0 0
+ 224 444 4 -0.39965 8.12024 17.60224 6.79460 0 0 0
+ 225 444 1 0.05269 8.09228 16.75013 4.91967 0 0 0
+ 226 444 1 0.05269 9.70728 17.00048 5.62151 0 0 0
+ 227 444 1 0.05269 8.66415 15.69153 6.22812 0 0 0
+ 228 444 2 0.20964 8.61953 17.44038 7.62546 0 0 0
+ 229 444 3 0.03193 8.92912 4.00904 0.50900 0 0 0
+ 230 444 4 -0.39965 8.96759 5.27857 -0.13058 0 0 0
+ 231 444 1 0.05269 8.33969 4.08141 1.42278 0 0 0
+ 232 444 1 0.05269 8.47682 3.27429 -0.15833 0 0 0
+ 233 444 1 0.05269 9.94193 3.69036 0.75961 0 0 0
+ 234 444 2 0.20964 9.53405 5.14064 -0.92363 0 0 0
+ 235 444 3 0.03193 14.12006 6.78048 11.59632 0 0 0
+ 236 444 4 -0.39965 13.07688 7.13628 10.69542 0 0 0
+ 237 444 1 0.05269 14.86068 7.57932 11.63302 0 0 0
+ 238 444 1 0.05269 13.70582 6.62813 12.59405 0 0 0
+ 239 444 1 0.05269 14.60290 5.86276 11.26001 0 0 0
+ 240 444 2 0.20964 12.46641 6.36815 10.68540 0 0 0
+ 241 444 3 0.03193 11.17366 12.60541 17.35410 0 0 0
+ 242 444 4 -0.39965 11.02139 13.96786 17.73395 0 0 0
+ 243 444 1 0.05269 10.47704 11.99021 17.92352 0 0 0
+ 244 444 1 0.05269 10.96097 12.49402 16.29011 0 0 0
+ 245 444 1 0.05269 12.19388 12.27752 17.55780 0 0 0
+ 246 444 2 0.20964 11.62997 14.46572 17.15437 0 0 0
+ 247 444 3 0.03193 13.59375 17.68257 6.60725 0 0 0
+ 248 444 4 -0.39965 14.41796 18.19915 5.56896 0 0 0
+ 249 444 1 0.05269 12.56750 17.59958 6.25257 0 0 0
+ 250 444 1 0.05269 13.95140 16.69610 6.90350 0 0 0
+ 251 444 1 0.05269 13.62441 18.35441 7.46523 0 0 0
+ 252 444 2 0.20964 15.31701 18.26489 5.96089 0 0 0
+ 253 444 3 0.03193 5.00550 8.70879 7.93082 0 0 0
+ 254 444 4 -0.39965 5.30633 7.53730 7.17920 0 0 0
+ 255 444 1 0.05269 3.92410 8.80228 8.03546 0 0 0
+ 256 444 1 0.05269 5.45973 8.64206 8.92134 0 0 0
+ 257 444 1 0.05269 5.39337 9.58812 7.41497 0 0 0
+ 258 444 2 0.20964 6.28240 7.52607 7.08649 0 0 0
+ 259 444 3 0.03193 19.22046 1.28969 13.91270 0 0 0
+ 260 444 4 -0.39965 20.08805 2.12898 14.66921 0 0 0
+ 261 444 1 0.05269 18.36269 1.87059 13.57299 0 0 0
+ 262 444 1 0.05269 19.74873 0.89208 13.04541 0 0 0
+ 263 444 1 0.05269 18.87095 0.46148 14.53042 0 0 0
+ 264 444 2 0.20964 20.73583 1.52580 15.09558 0 0 0
+ 265 444 3 0.03193 5.65052 5.42047 10.40141 0 0 0
+ 266 444 4 -0.39965 6.43233 5.15576 11.55959 0 0 0
+ 267 444 1 0.05269 4.77591 4.76790 10.40245 0 0 0
+ 268 444 1 0.05269 5.31750 6.45945 10.40208 0 0 0
+ 269 444 1 0.05269 6.23775 5.22771 9.50311 0 0 0
+ 270 444 2 0.20964 7.22334 5.73649 11.49818 0 0 0
+ 271 444 3 0.03193 13.28289 5.81639 20.26495 0 0 0
+ 272 444 4 -0.39965 14.46108 5.91020 19.47306 0 0 0
+ 273 444 1 0.05269 12.54449 6.53149 19.89956 0 0 0
+ 274 444 1 0.05269 12.86565 4.81041 20.20085 0 0 0
+ 275 444 1 0.05269 13.51599 6.04282 21.30628 0 0 0
+ 276 444 2 0.20964 15.06689 5.21681 19.82048 0 0 0
+ 277 444 3 0.03193 8.93119 18.18764 13.28407 0 0 0
+ 278 444 4 -0.39965 7.83369 17.94987 14.15258 0 0 0
+ 279 444 1 0.05269 8.62256 18.85058 12.47662 0 0 0
+ 280 444 1 0.05269 9.74951 18.65521 13.83984 0 0 0
+ 281 444 1 0.05269 9.27914 17.24313 12.85839 0 0 0
+ 282 444 2 0.20964 8.18034 17.33710 14.83873 0 0 0
+ 283 444 3 0.03193 5.79456 2.19968 17.80701 0 0 0
+ 284 444 4 -0.39965 6.24133 2.96696 16.69489 0 0 0
+ 285 444 1 0.05269 5.95925 2.76662 18.72146 0 0 0
+ 286 444 1 0.05269 4.73133 1.97951 17.70368 0 0 0
+ 287 444 1 0.05269 6.35360 1.26369 17.85787 0 0 0
+ 288 444 2 0.20964 6.11167 2.36984 15.93032 0 0 0
+ 289 444 3 0.03193 7.02257 8.31146 13.32419 0 0 0
+ 290 444 4 -0.39965 6.81830 9.58617 13.92250 0 0 0
+ 291 444 1 0.05269 6.70351 7.53159 14.01772 0 0 0
+ 292 444 1 0.05269 6.43819 8.23664 12.40602 0 0 0
+ 293 444 1 0.05269 8.08019 8.17829 13.09255 0 0 0
+ 294 444 2 0.20964 7.15181 10.23194 13.26245 0 0 0
+ 295 444 3 0.03193 14.02631 3.46938 16.96774 0 0 0
+ 296 444 4 -0.39965 13.54366 2.24600 17.51611 0 0 0
+ 297 444 1 0.05269 13.77498 3.53066 15.91013 0 0 0
+ 298 444 1 0.05269 13.56595 4.30739 17.48900 0 0 0
+ 299 444 1 0.05269 15.10861 3.52592 17.07904 0 0 0
+ 300 444 2 0.20964 13.94305 2.20406 18.41525 0 0 0
+ 301 444 3 0.03193 1.20831 18.57486 2.95108 0 0 0
+ 302 444 4 -0.39965 1.22576 19.81993 2.26075 0 0 0
+ 303 444 1 0.05269 0.55458 18.64320 3.82147 0 0 0
+ 304 444 1 0.05269 0.84728 17.78646 2.28798 0 0 0
+ 305 444 1 0.05269 2.21813 18.32995 3.28130 0 0 0
+ 306 444 2 0.20964 0.30364 19.97372 1.97883 0 0 0
+ 307 444 3 0.03193 13.27354 18.56828 10.67719 0 0 0
+ 308 444 4 -0.39965 12.48821 17.54334 10.07841 0 0 0
+ 309 444 1 0.05269 12.67535 19.47728 10.75867 0 0 0
+ 310 444 1 0.05269 13.59103 18.25289 11.67155 0 0 0
+ 311 444 1 0.05269 14.15208 18.77184 10.06448 0 0 0
+ 312 444 2 0.20964 13.09935 16.78781 9.93641 0 0 0
+ 313 444 3 0.03193 6.36730 14.29234 8.10345 0 0 0
+ 314 444 4 -0.39965 6.40678 13.98673 6.71535 0 0 0
+ 315 444 1 0.05269 5.36805 14.09806 8.49177 0 0 0
+ 316 444 1 0.05269 7.08832 13.66856 8.63166 0 0 0
+ 317 444 1 0.05269 6.61905 15.34196 8.25886 0 0 0
+ 318 444 2 0.20964 5.76587 14.60457 6.30951 0 0 0
+ 319 444 3 0.03193 2.65328 9.08063 11.58358 0 0 0
+ 320 444 4 -0.39965 2.00217 9.04988 10.31818 0 0 0
+ 321 444 1 0.05269 2.77179 8.06201 11.95511 0 0 0
+ 322 444 1 0.05269 3.63556 9.54427 11.48302 0 0 0
+ 323 444 1 0.05269 2.05382 9.65342 12.29226 0 0 0
+ 324 444 2 0.20964 1.90245 9.98881 10.05330 0 0 0
+ 325 444 3 0.03193 16.09537 13.47946 18.75299 0 0 0
+ 326 444 4 -0.39965 15.35647 12.29789 19.02596 0 0 0
+ 327 444 1 0.05269 15.44738 14.34606 18.88103 0 0 0
+ 328 444 1 0.05269 16.93959 13.54850 19.44072 0 0 0
+ 329 444 1 0.05269 16.46394 13.45617 17.72675 0 0 0
+ 330 444 2 0.20964 15.94172 11.56097 18.74998 0 0 0
+ 331 444 3 0.03193 5.36713 6.40841 19.02468 0 0 0
+ 332 444 4 -0.39965 6.23337 6.92207 18.01801 0 0 0
+ 333 444 1 0.05269 4.33549 6.65297 18.77623 0 0 0
+ 334 444 1 0.05269 5.47707 5.32425 19.08654 0 0 0
+ 335 444 1 0.05269 5.62819 6.85675 19.98559 0 0 0
+ 336 444 2 0.20964 7.13950 6.67949 18.31120 0 0 0
+ 337 444 3 0.03193 1.77513 13.81811 9.21198 0 0 0
+ 338 444 4 -0.39965 0.83100 14.28966 10.16552 0 0 0
+ 339 444 1 0.05269 1.29728 13.75593 8.23483 0 0 0
+ 340 444 1 0.05269 2.62178 14.50388 9.15673 0 0 0
+ 341 444 1 0.05269 2.12880 12.82836 9.50371 0 0 0
+ 342 444 2 0.20964 1.30194 14.30478 11.02173 0 0 0
+ 343 444 3 0.03193 21.59943 4.06368 17.75073 0 0 0
+ 344 444 4 -0.39965 21.85233 3.04768 18.71336 0 0 0
+ 345 444 1 0.05269 22.11092 3.81498 16.82008 0 0 0
+ 346 444 1 0.05269 20.52800 4.13659 17.56408 0 0 0
+ 347 444 1 0.05269 21.97071 5.01986 18.11886 0 0 0
+ 348 444 2 0.20964 21.40074 3.34325 19.53474 0 0 0
+ 349 444 3 0.03193 16.52622 4.73908 13.63762 0 0 0
+ 350 444 4 -0.39965 15.55282 5.45454 14.38889 0 0 0
+ 351 444 1 0.05269 16.03370 3.96708 13.04616 0 0 0
+ 352 444 1 0.05269 17.05262 5.42291 12.96909 0 0 0
+ 353 444 1 0.05269 17.24076 4.27126 14.31456 0 0 0
+ 354 444 2 0.20964 16.06701 6.07053 14.95693 0 0 0
+ 355 444 3 0.03193 20.20141 14.20302 18.50889 0 0 0
+ 356 444 4 -0.39965 21.44729 13.78288 19.04009 0 0 0
+ 357 444 1 0.05269 20.32931 15.13613 17.95996 0 0 0
+ 358 444 1 0.05269 19.81275 13.43791 17.83324 0 0 0
+ 359 444 1 0.05269 19.48848 14.36395 19.32079 0 0 0
+ 360 444 2 0.20964 21.25026 12.96615 19.54627 0 0 0
+ 361 444 3 0.03193 3.32298 14.94425 16.50422 0 0 0
+ 362 444 4 -0.39965 4.38694 14.00670 16.37303 0 0 0
+ 363 444 1 0.05269 3.54498 15.83135 15.91086 0 0 0
+ 364 444 1 0.05269 2.39143 14.50263 16.15017 0 0 0
+ 365 444 1 0.05269 3.21366 15.23418 17.54978 0 0 0
+ 366 444 2 0.20964 4.09659 13.20452 16.85511 0 0 0
+ 367 444 3 0.03193 10.00891 1.19780 16.80998 0 0 0
+ 368 444 4 -0.39965 10.58951 1.67540 18.01757 0 0 0
+ 369 444 1 0.05269 8.95573 0.97837 16.97853 0 0 0
+ 370 444 1 0.05269 10.09279 1.95889 16.03422 0 0 0
+ 371 444 1 0.05269 10.51430 0.28729 16.48583 0 0 0
+ 372 444 2 0.20964 11.54632 1.78202 17.83462 0 0 0
+ 373 444 3 0.03193 1.31776 5.21190 2.64974 0 0 0
+ 374 444 4 -0.39965 0.78156 4.20400 1.79964 0 0 0
+ 375 444 1 0.05269 2.00060 5.84322 2.08036 0 0 0
+ 376 444 1 0.05269 0.50993 5.82499 3.05018 0 0 0
+ 377 444 1 0.05269 1.85905 4.74873 3.47448 0 0 0
+ 378 444 2 0.20964 0.20631 3.65922 2.38482 0 0 0
+ 379 444 3 0.03193 5.74906 1.64126 13.27894 0 0 0
+ 380 444 4 -0.39965 5.74933 0.96366 14.53304 0 0 0
+ 381 444 1 0.05269 5.05775 2.48272 13.31880 0 0 0
+ 382 444 1 0.05269 6.74849 2.01315 13.05234 0 0 0
+ 383 444 1 0.05269 5.43187 0.95557 12.49248 0 0 0
+ 384 444 2 0.20964 6.42516 0.25912 14.43537 0 0 0
+
+
+Bonds
+
+ 1 1 1 2
+ 2 3 1 3
+ 3 3 1 4
+ 4 3 1 5
+ 5 2 2 6
+ 6 1 7 8
+ 7 3 7 9
+ 8 3 7 10
+ 9 3 7 11
+ 10 2 8 12
+ 11 1 13 14
+ 12 3 13 15
+ 13 3 13 16
+ 14 3 13 17
+ 15 2 14 18
+ 16 1 19 20
+ 17 3 19 21
+ 18 3 19 22
+ 19 3 19 23
+ 20 2 20 24
+ 21 1 25 26
+ 22 3 25 27
+ 23 3 25 28
+ 24 3 25 29
+ 25 2 26 30
+ 26 1 31 32
+ 27 3 31 33
+ 28 3 31 34
+ 29 3 31 35
+ 30 2 32 36
+ 31 1 37 38
+ 32 3 37 39
+ 33 3 37 40
+ 34 3 37 41
+ 35 2 38 42
+ 36 1 43 44
+ 37 3 43 45
+ 38 3 43 46
+ 39 3 43 47
+ 40 2 44 48
+ 41 1 49 50
+ 42 3 49 51
+ 43 3 49 52
+ 44 3 49 53
+ 45 2 50 54
+ 46 1 55 56
+ 47 3 55 57
+ 48 3 55 58
+ 49 3 55 59
+ 50 2 56 60
+ 51 1 61 62
+ 52 3 61 63
+ 53 3 61 64
+ 54 3 61 65
+ 55 2 62 66
+ 56 1 67 68
+ 57 3 67 69
+ 58 3 67 70
+ 59 3 67 71
+ 60 2 68 72
+ 61 1 73 74
+ 62 3 73 75
+ 63 3 73 76
+ 64 3 73 77
+ 65 2 74 78
+ 66 1 79 80
+ 67 3 79 81
+ 68 3 79 82
+ 69 3 79 83
+ 70 2 80 84
+ 71 1 85 86
+ 72 3 85 87
+ 73 3 85 88
+ 74 3 85 89
+ 75 2 86 90
+ 76 1 91 92
+ 77 3 91 93
+ 78 3 91 94
+ 79 3 91 95
+ 80 2 92 96
+ 81 1 97 98
+ 82 3 97 99
+ 83 3 97 100
+ 84 3 97 101
+ 85 2 98 102
+ 86 1 103 104
+ 87 3 103 105
+ 88 3 103 106
+ 89 3 103 107
+ 90 2 104 108
+ 91 1 109 110
+ 92 3 109 111
+ 93 3 109 112
+ 94 3 109 113
+ 95 2 110 114
+ 96 1 115 116
+ 97 3 115 117
+ 98 3 115 118
+ 99 3 115 119
+ 100 2 116 120
+ 101 1 121 122
+ 102 3 121 123
+ 103 3 121 124
+ 104 3 121 125
+ 105 2 122 126
+ 106 1 127 128
+ 107 3 127 129
+ 108 3 127 130
+ 109 3 127 131
+ 110 2 128 132
+ 111 1 133 134
+ 112 3 133 135
+ 113 3 133 136
+ 114 3 133 137
+ 115 2 134 138
+ 116 1 139 140
+ 117 3 139 141
+ 118 3 139 142
+ 119 3 139 143
+ 120 2 140 144
+ 121 1 145 146
+ 122 3 145 147
+ 123 3 145 148
+ 124 3 145 149
+ 125 2 146 150
+ 126 1 151 152
+ 127 3 151 153
+ 128 3 151 154
+ 129 3 151 155
+ 130 2 152 156
+ 131 1 157 158
+ 132 3 157 159
+ 133 3 157 160
+ 134 3 157 161
+ 135 2 158 162
+ 136 1 163 164
+ 137 3 163 165
+ 138 3 163 166
+ 139 3 163 167
+ 140 2 164 168
+ 141 1 169 170
+ 142 3 169 171
+ 143 3 169 172
+ 144 3 169 173
+ 145 2 170 174
+ 146 1 175 176
+ 147 3 175 177
+ 148 3 175 178
+ 149 3 175 179
+ 150 2 176 180
+ 151 1 181 182
+ 152 3 181 183
+ 153 3 181 184
+ 154 3 181 185
+ 155 2 182 186
+ 156 1 187 188
+ 157 3 187 189
+ 158 3 187 190
+ 159 3 187 191
+ 160 2 188 192
+ 161 1 193 194
+ 162 3 193 195
+ 163 3 193 196
+ 164 3 193 197
+ 165 2 194 198
+ 166 1 199 200
+ 167 3 199 201
+ 168 3 199 202
+ 169 3 199 203
+ 170 2 200 204
+ 171 1 205 206
+ 172 3 205 207
+ 173 3 205 208
+ 174 3 205 209
+ 175 2 206 210
+ 176 1 211 212
+ 177 3 211 213
+ 178 3 211 214
+ 179 3 211 215
+ 180 2 212 216
+ 181 1 217 218
+ 182 3 217 219
+ 183 3 217 220
+ 184 3 217 221
+ 185 2 218 222
+ 186 1 223 224
+ 187 3 223 225
+ 188 3 223 226
+ 189 3 223 227
+ 190 2 224 228
+ 191 1 229 230
+ 192 3 229 231
+ 193 3 229 232
+ 194 3 229 233
+ 195 2 230 234
+ 196 1 235 236
+ 197 3 235 237
+ 198 3 235 238
+ 199 3 235 239
+ 200 2 236 240
+ 201 1 241 242
+ 202 3 241 243
+ 203 3 241 244
+ 204 3 241 245
+ 205 2 242 246
+ 206 1 247 248
+ 207 3 247 249
+ 208 3 247 250
+ 209 3 247 251
+ 210 2 248 252
+ 211 1 253 254
+ 212 3 253 255
+ 213 3 253 256
+ 214 3 253 257
+ 215 2 254 258
+ 216 1 259 260
+ 217 3 259 261
+ 218 3 259 262
+ 219 3 259 263
+ 220 2 260 264
+ 221 1 265 266
+ 222 3 265 267
+ 223 3 265 268
+ 224 3 265 269
+ 225 2 266 270
+ 226 1 271 272
+ 227 3 271 273
+ 228 3 271 274
+ 229 3 271 275
+ 230 2 272 276
+ 231 1 277 278
+ 232 3 277 279
+ 233 3 277 280
+ 234 3 277 281
+ 235 2 278 282
+ 236 1 283 284
+ 237 3 283 285
+ 238 3 283 286
+ 239 3 283 287
+ 240 2 284 288
+ 241 1 289 290
+ 242 3 289 291
+ 243 3 289 292
+ 244 3 289 293
+ 245 2 290 294
+ 246 1 295 296
+ 247 3 295 297
+ 248 3 295 298
+ 249 3 295 299
+ 250 2 296 300
+ 251 1 301 302
+ 252 3 301 303
+ 253 3 301 304
+ 254 3 301 305
+ 255 2 302 306
+ 256 1 307 308
+ 257 3 307 309
+ 258 3 307 310
+ 259 3 307 311
+ 260 2 308 312
+ 261 1 313 314
+ 262 3 313 315
+ 263 3 313 316
+ 264 3 313 317
+ 265 2 314 318
+ 266 1 319 320
+ 267 3 319 321
+ 268 3 319 322
+ 269 3 319 323
+ 270 2 320 324
+ 271 1 325 326
+ 272 3 325 327
+ 273 3 325 328
+ 274 3 325 329
+ 275 2 326 330
+ 276 1 331 332
+ 277 3 331 333
+ 278 3 331 334
+ 279 3 331 335
+ 280 2 332 336
+ 281 1 337 338
+ 282 3 337 339
+ 283 3 337 340
+ 284 3 337 341
+ 285 2 338 342
+ 286 1 343 344
+ 287 3 343 345
+ 288 3 343 346
+ 289 3 343 347
+ 290 2 344 348
+ 291 1 349 350
+ 292 3 349 351
+ 293 3 349 352
+ 294 3 349 353
+ 295 2 350 354
+ 296 1 355 356
+ 297 3 355 357
+ 298 3 355 358
+ 299 3 355 359
+ 300 2 356 360
+ 301 1 361 362
+ 302 3 361 363
+ 303 3 361 364
+ 304 3 361 365
+ 305 2 362 366
+ 306 1 367 368
+ 307 3 367 369
+ 308 3 367 370
+ 309 3 367 371
+ 310 2 368 372
+ 311 1 373 374
+ 312 3 373 375
+ 313 3 373 376
+ 314 3 373 377
+ 315 2 374 378
+ 316 1 379 380
+ 317 3 379 381
+ 318 3 379 382
+ 319 3 379 383
+ 320 2 380 384
+
+Angles
+
+ 1 2 3 1 2
+ 2 2 4 1 2
+ 3 2 4 1 3
+ 4 2 5 1 2
+ 5 2 5 1 3
+ 6 2 5 1 4
+ 7 1 6 2 1
+ 8 1 7 8 12
+ 9 2 8 7 10
+ 10 2 8 7 11
+ 11 2 9 7 8
+ 12 2 9 7 10
+ 13 2 9 7 11
+ 14 2 11 7 10
+ 15 2 15 13 14
+ 16 2 16 13 14
+ 17 2 16 13 15
+ 18 2 17 13 14
+ 19 2 17 13 15
+ 20 2 17 13 16
+ 21 1 18 14 13
+ 22 2 21 19 20
+ 23 2 22 19 20
+ 24 2 22 19 21
+ 25 2 23 19 20
+ 26 2 23 19 21
+ 27 2 23 19 22
+ 28 1 24 20 19
+ 29 2 27 25 26
+ 30 2 28 25 26
+ 31 2 28 25 27
+ 32 2 29 25 26
+ 33 2 29 25 27
+ 34 2 29 25 28
+ 35 1 30 26 25
+ 36 2 33 31 32
+ 37 2 34 31 32
+ 38 2 34 31 33
+ 39 2 35 31 32
+ 40 2 35 31 33
+ 41 2 35 31 34
+ 42 1 36 32 31
+ 43 2 39 37 38
+ 44 2 40 37 38
+ 45 2 40 37 39
+ 46 2 41 37 38
+ 47 2 41 37 39
+ 48 2 41 37 40
+ 49 1 42 38 37
+ 50 2 45 43 44
+ 51 2 46 43 44
+ 52 2 46 43 45
+ 53 2 47 43 44
+ 54 2 47 43 45
+ 55 2 47 43 46
+ 56 1 48 44 43
+ 57 2 51 49 50
+ 58 2 52 49 50
+ 59 2 52 49 51
+ 60 2 53 49 50
+ 61 2 53 49 51
+ 62 2 53 49 52
+ 63 1 54 50 49
+ 64 2 57 55 56
+ 65 2 58 55 56
+ 66 2 58 55 57
+ 67 2 59 55 56
+ 68 2 59 55 57
+ 69 2 59 55 58
+ 70 1 60 56 55
+ 71 2 63 61 62
+ 72 2 64 61 62
+ 73 2 64 61 63
+ 74 2 65 61 62
+ 75 2 65 61 63
+ 76 2 65 61 64
+ 77 1 66 62 61
+ 78 2 69 67 68
+ 79 2 70 67 68
+ 80 2 70 67 69
+ 81 2 71 67 68
+ 82 2 71 67 69
+ 83 2 71 67 70
+ 84 1 72 68 67
+ 85 2 75 73 74
+ 86 2 76 73 74
+ 87 2 76 73 75
+ 88 2 77 73 74
+ 89 2 77 73 75
+ 90 2 77 73 76
+ 91 1 78 74 73
+ 92 2 81 79 80
+ 93 2 82 79 80
+ 94 2 82 79 81
+ 95 2 83 79 80
+ 96 2 83 79 81
+ 97 2 83 79 82
+ 98 1 84 80 79
+ 99 2 87 85 86
+ 100 2 88 85 86
+ 101 2 88 85 87
+ 102 2 89 85 86
+ 103 2 89 85 87
+ 104 2 89 85 88
+ 105 1 90 86 85
+ 106 2 93 91 92
+ 107 2 94 91 92
+ 108 2 94 91 93
+ 109 2 95 91 92
+ 110 2 95 91 93
+ 111 2 95 91 94
+ 112 1 96 92 91
+ 113 1 97 98 102
+ 114 2 98 97 100
+ 115 2 98 97 101
+ 116 2 99 97 98
+ 117 2 99 97 100
+ 118 2 99 97 101
+ 119 2 101 97 100
+ 120 2 105 103 104
+ 121 2 106 103 104
+ 122 2 106 103 105
+ 123 2 107 103 104
+ 124 2 107 103 105
+ 125 2 107 103 106
+ 126 1 108 104 103
+ 127 2 111 109 110
+ 128 2 112 109 110
+ 129 2 112 109 111
+ 130 2 113 109 110
+ 131 2 113 109 111
+ 132 2 113 109 112
+ 133 1 114 110 109
+ 134 2 117 115 116
+ 135 2 118 115 116
+ 136 2 118 115 117
+ 137 2 119 115 116
+ 138 2 119 115 117
+ 139 2 119 115 118
+ 140 1 120 116 115
+ 141 2 123 121 122
+ 142 2 124 121 122
+ 143 2 124 121 123
+ 144 2 125 121 122
+ 145 2 125 121 123
+ 146 2 125 121 124
+ 147 1 126 122 121
+ 148 2 129 127 128
+ 149 2 130 127 128
+ 150 2 130 127 129
+ 151 2 131 127 128
+ 152 2 131 127 129
+ 153 2 131 127 130
+ 154 1 132 128 127
+ 155 2 135 133 134
+ 156 2 136 133 134
+ 157 2 136 133 135
+ 158 2 137 133 134
+ 159 2 137 133 135
+ 160 2 137 133 136
+ 161 1 138 134 133
+ 162 2 141 139 140
+ 163 2 142 139 140
+ 164 2 142 139 141
+ 165 2 143 139 140
+ 166 2 143 139 141
+ 167 2 143 139 142
+ 168 1 144 140 139
+ 169 2 147 145 146
+ 170 2 148 145 146
+ 171 2 148 145 147
+ 172 2 149 145 146
+ 173 2 149 145 147
+ 174 2 149 145 148
+ 175 1 150 146 145
+ 176 2 153 151 152
+ 177 2 154 151 152
+ 178 2 154 151 153
+ 179 2 155 151 152
+ 180 2 155 151 153
+ 181 2 155 151 154
+ 182 1 156 152 151
+ 183 2 159 157 158
+ 184 2 160 157 158
+ 185 2 160 157 159
+ 186 2 161 157 158
+ 187 2 161 157 159
+ 188 2 161 157 160
+ 189 1 162 158 157
+ 190 2 165 163 164
+ 191 2 166 163 164
+ 192 2 166 163 165
+ 193 2 167 163 164
+ 194 2 167 163 165
+ 195 2 167 163 166
+ 196 1 168 164 163
+ 197 2 171 169 170
+ 198 2 172 169 170
+ 199 2 172 169 171
+ 200 2 173 169 170
+ 201 2 173 169 171
+ 202 2 173 169 172
+ 203 1 174 170 169
+ 204 2 177 175 176
+ 205 2 178 175 176
+ 206 2 178 175 177
+ 207 2 179 175 176
+ 208 2 179 175 177
+ 209 2 179 175 178
+ 210 1 180 176 175
+ 211 2 183 181 182
+ 212 2 184 181 182
+ 213 2 184 181 183
+ 214 2 185 181 182
+ 215 2 185 181 183
+ 216 2 185 181 184
+ 217 1 186 182 181
+ 218 2 189 187 188
+ 219 2 190 187 188
+ 220 2 190 187 189
+ 221 2 191 187 188
+ 222 2 191 187 189
+ 223 2 191 187 190
+ 224 1 192 188 187
+ 225 2 195 193 194
+ 226 2 196 193 194
+ 227 2 196 193 195
+ 228 2 197 193 194
+ 229 2 197 193 195
+ 230 2 197 193 196
+ 231 1 198 194 193
+ 232 2 201 199 200
+ 233 2 202 199 200
+ 234 2 202 199 201
+ 235 2 203 199 200
+ 236 2 203 199 201
+ 237 2 203 199 202
+ 238 1 204 200 199
+ 239 2 207 205 206
+ 240 2 208 205 206
+ 241 2 208 205 207
+ 242 2 209 205 206
+ 243 2 209 205 207
+ 244 2 209 205 208
+ 245 1 210 206 205
+ 246 2 213 211 212
+ 247 2 214 211 212
+ 248 2 214 211 213
+ 249 2 215 211 212
+ 250 2 215 211 213
+ 251 2 215 211 214
+ 252 1 216 212 211
+ 253 2 219 217 218
+ 254 2 220 217 218
+ 255 2 220 217 219
+ 256 2 221 217 218
+ 257 2 221 217 219
+ 258 2 221 217 220
+ 259 1 222 218 217
+ 260 2 225 223 224
+ 261 2 226 223 224
+ 262 2 226 223 225
+ 263 2 227 223 224
+ 264 2 227 223 225
+ 265 2 227 223 226
+ 266 1 228 224 223
+ 267 2 231 229 230
+ 268 2 232 229 230
+ 269 2 232 229 231
+ 270 2 233 229 230
+ 271 2 233 229 231
+ 272 2 233 229 232
+ 273 1 234 230 229
+ 274 2 237 235 236
+ 275 2 238 235 236
+ 276 2 238 235 237
+ 277 2 239 235 236
+ 278 2 239 235 237
+ 279 2 239 235 238
+ 280 1 240 236 235
+ 281 2 243 241 242
+ 282 2 244 241 242
+ 283 2 244 241 243
+ 284 2 245 241 242
+ 285 2 245 241 243
+ 286 2 245 241 244
+ 287 1 246 242 241
+ 288 2 249 247 248
+ 289 2 250 247 248
+ 290 2 250 247 249
+ 291 2 251 247 248
+ 292 2 251 247 249
+ 293 2 251 247 250
+ 294 1 252 248 247
+ 295 2 255 253 254
+ 296 2 256 253 254
+ 297 2 256 253 255
+ 298 2 257 253 254
+ 299 2 257 253 255
+ 300 2 257 253 256
+ 301 1 258 254 253
+ 302 2 261 259 260
+ 303 2 262 259 260
+ 304 2 262 259 261
+ 305 2 263 259 260
+ 306 2 263 259 261
+ 307 2 263 259 262
+ 308 1 264 260 259
+ 309 2 267 265 266
+ 310 2 268 265 266
+ 311 2 268 265 267
+ 312 2 269 265 266
+ 313 2 269 265 267
+ 314 2 269 265 268
+ 315 1 270 266 265
+ 316 2 273 271 272
+ 317 2 274 271 272
+ 318 2 274 271 273
+ 319 2 275 271 272
+ 320 2 275 271 273
+ 321 2 275 271 274
+ 322 1 276 272 271
+ 323 2 279 277 278
+ 324 2 280 277 278
+ 325 2 280 277 279
+ 326 2 281 277 278
+ 327 2 281 277 279
+ 328 2 281 277 280
+ 329 1 282 278 277
+ 330 2 285 283 284
+ 331 2 286 283 284
+ 332 2 286 283 285
+ 333 2 287 283 284
+ 334 2 287 283 285
+ 335 2 287 283 286
+ 336 1 288 284 283
+ 337 2 291 289 290
+ 338 2 292 289 290
+ 339 2 292 289 291
+ 340 2 293 289 290
+ 341 2 293 289 291
+ 342 2 293 289 292
+ 343 1 294 290 289
+ 344 2 297 295 296
+ 345 2 298 295 296
+ 346 2 298 295 297
+ 347 2 299 295 296
+ 348 2 299 295 297
+ 349 2 299 295 298
+ 350 1 300 296 295
+ 351 2 303 301 302
+ 352 2 304 301 302
+ 353 2 304 301 303
+ 354 2 305 301 302
+ 355 2 305 301 303
+ 356 2 305 301 304
+ 357 1 306 302 301
+ 358 2 309 307 308
+ 359 2 310 307 308
+ 360 2 310 307 309
+ 361 2 311 307 308
+ 362 2 311 307 309
+ 363 2 311 307 310
+ 364 1 312 308 307
+ 365 2 315 313 314
+ 366 2 316 313 314
+ 367 2 316 313 315
+ 368 2 317 313 314
+ 369 2 317 313 315
+ 370 2 317 313 316
+ 371 1 318 314 313
+ 372 2 321 319 320
+ 373 2 322 319 320
+ 374 2 322 319 321
+ 375 2 323 319 320
+ 376 2 323 319 321
+ 377 2 323 319 322
+ 378 1 324 320 319
+ 379 2 327 325 326
+ 380 2 328 325 326
+ 381 2 328 325 327
+ 382 2 329 325 326
+ 383 2 329 325 327
+ 384 2 329 325 328
+ 385 1 330 326 325
+ 386 2 333 331 332
+ 387 2 334 331 332
+ 388 2 334 331 333
+ 389 2 335 331 332
+ 390 2 335 331 333
+ 391 2 335 331 334
+ 392 1 336 332 331
+ 393 2 339 337 338
+ 394 2 340 337 338
+ 395 2 340 337 339
+ 396 2 341 337 338
+ 397 2 341 337 339
+ 398 2 341 337 340
+ 399 1 342 338 337
+ 400 2 345 343 344
+ 401 2 346 343 344
+ 402 2 346 343 345
+ 403 2 347 343 344
+ 404 2 347 343 345
+ 405 2 347 343 346
+ 406 1 348 344 343
+ 407 2 351 349 350
+ 408 2 352 349 350
+ 409 2 352 349 351
+ 410 2 353 349 350
+ 411 2 353 349 351
+ 412 2 353 349 352
+ 413 1 354 350 349
+ 414 2 357 355 356
+ 415 2 358 355 356
+ 416 2 358 355 357
+ 417 2 359 355 356
+ 418 2 359 355 357
+ 419 2 359 355 358
+ 420 1 360 356 355
+ 421 2 363 361 362
+ 422 2 364 361 362
+ 423 2 364 361 363
+ 424 2 365 361 362
+ 425 2 365 361 363
+ 426 2 365 361 364
+ 427 1 366 362 361
+ 428 2 369 367 368
+ 429 2 370 367 368
+ 430 2 370 367 369
+ 431 2 371 367 368
+ 432 2 371 367 369
+ 433 2 371 367 370
+ 434 1 372 368 367
+ 435 2 375 373 374
+ 436 2 376 373 374
+ 437 2 376 373 375
+ 438 2 377 373 374
+ 439 2 377 373 375
+ 440 2 377 373 376
+ 441 1 378 374 373
+ 442 2 381 379 380
+ 443 2 382 379 380
+ 444 2 382 379 381
+ 445 2 383 379 380
+ 446 2 383 379 381
+ 447 2 383 379 382
+ 448 1 384 380 379
+
+Dihedrals
+
+ 1 1 6 2 1 3
+ 2 1 6 2 1 4
+ 3 1 6 2 1 5
+ 4 1 9 7 8 12
+ 5 1 12 8 7 10
+ 6 1 12 8 7 11
+ 7 1 18 14 13 15
+ 8 1 18 14 13 16
+ 9 1 18 14 13 17
+ 10 1 24 20 19 21
+ 11 1 24 20 19 22
+ 12 1 24 20 19 23
+ 13 1 30 26 25 27
+ 14 1 30 26 25 28
+ 15 1 30 26 25 29
+ 16 1 36 32 31 33
+ 17 1 36 32 31 34
+ 18 1 36 32 31 35
+ 19 1 42 38 37 39
+ 20 1 42 38 37 40
+ 21 1 42 38 37 41
+ 22 1 48 44 43 45
+ 23 1 48 44 43 46
+ 24 1 48 44 43 47
+ 25 1 54 50 49 51
+ 26 1 54 50 49 52
+ 27 1 54 50 49 53
+ 28 1 60 56 55 57
+ 29 1 60 56 55 58
+ 30 1 60 56 55 59
+ 31 1 66 62 61 63
+ 32 1 66 62 61 64
+ 33 1 66 62 61 65
+ 34 1 72 68 67 69
+ 35 1 72 68 67 70
+ 36 1 72 68 67 71
+ 37 1 78 74 73 75
+ 38 1 78 74 73 76
+ 39 1 78 74 73 77
+ 40 1 84 80 79 81
+ 41 1 84 80 79 82
+ 42 1 84 80 79 83
+ 43 1 90 86 85 87
+ 44 1 90 86 85 88
+ 45 1 90 86 85 89
+ 46 1 96 92 91 93
+ 47 1 96 92 91 94
+ 48 1 96 92 91 95
+ 49 1 99 97 98 102
+ 50 1 102 98 97 100
+ 51 1 102 98 97 101
+ 52 1 108 104 103 105
+ 53 1 108 104 103 106
+ 54 1 108 104 103 107
+ 55 1 114 110 109 111
+ 56 1 114 110 109 112
+ 57 1 114 110 109 113
+ 58 1 120 116 115 117
+ 59 1 120 116 115 118
+ 60 1 120 116 115 119
+ 61 1 126 122 121 123
+ 62 1 126 122 121 124
+ 63 1 126 122 121 125
+ 64 1 132 128 127 129
+ 65 1 132 128 127 130
+ 66 1 132 128 127 131
+ 67 1 138 134 133 135
+ 68 1 138 134 133 136
+ 69 1 138 134 133 137
+ 70 1 144 140 139 141
+ 71 1 144 140 139 142
+ 72 1 144 140 139 143
+ 73 1 150 146 145 147
+ 74 1 150 146 145 148
+ 75 1 150 146 145 149
+ 76 1 156 152 151 153
+ 77 1 156 152 151 154
+ 78 1 156 152 151 155
+ 79 1 162 158 157 159
+ 80 1 162 158 157 160
+ 81 1 162 158 157 161
+ 82 1 168 164 163 165
+ 83 1 168 164 163 166
+ 84 1 168 164 163 167
+ 85 1 174 170 169 171
+ 86 1 174 170 169 172
+ 87 1 174 170 169 173
+ 88 1 180 176 175 177
+ 89 1 180 176 175 178
+ 90 1 180 176 175 179
+ 91 1 186 182 181 183
+ 92 1 186 182 181 184
+ 93 1 186 182 181 185
+ 94 1 192 188 187 189
+ 95 1 192 188 187 190
+ 96 1 192 188 187 191
+ 97 1 198 194 193 195
+ 98 1 198 194 193 196
+ 99 1 198 194 193 197
+ 100 1 204 200 199 201
+ 101 1 204 200 199 202
+ 102 1 204 200 199 203
+ 103 1 210 206 205 207
+ 104 1 210 206 205 208
+ 105 1 210 206 205 209
+ 106 1 216 212 211 213
+ 107 1 216 212 211 214
+ 108 1 216 212 211 215
+ 109 1 222 218 217 219
+ 110 1 222 218 217 220
+ 111 1 222 218 217 221
+ 112 1 228 224 223 225
+ 113 1 228 224 223 226
+ 114 1 228 224 223 227
+ 115 1 234 230 229 231
+ 116 1 234 230 229 232
+ 117 1 234 230 229 233
+ 118 1 240 236 235 237
+ 119 1 240 236 235 238
+ 120 1 240 236 235 239
+ 121 1 246 242 241 243
+ 122 1 246 242 241 244
+ 123 1 246 242 241 245
+ 124 1 252 248 247 249
+ 125 1 252 248 247 250
+ 126 1 252 248 247 251
+ 127 1 258 254 253 255
+ 128 1 258 254 253 256
+ 129 1 258 254 253 257
+ 130 1 264 260 259 261
+ 131 1 264 260 259 262
+ 132 1 264 260 259 263
+ 133 1 270 266 265 267
+ 134 1 270 266 265 268
+ 135 1 270 266 265 269
+ 136 1 276 272 271 273
+ 137 1 276 272 271 274
+ 138 1 276 272 271 275
+ 139 1 282 278 277 279
+ 140 1 282 278 277 280
+ 141 1 282 278 277 281
+ 142 1 288 284 283 285
+ 143 1 288 284 283 286
+ 144 1 288 284 283 287
+ 145 1 294 290 289 291
+ 146 1 294 290 289 292
+ 147 1 294 290 289 293
+ 148 1 300 296 295 297
+ 149 1 300 296 295 298
+ 150 1 300 296 295 299
+ 151 1 306 302 301 303
+ 152 1 306 302 301 304
+ 153 1 306 302 301 305
+ 154 1 312 308 307 309
+ 155 1 312 308 307 310
+ 156 1 312 308 307 311
+ 157 1 318 314 313 315
+ 158 1 318 314 313 316
+ 159 1 318 314 313 317
+ 160 1 324 320 319 321
+ 161 1 324 320 319 322
+ 162 1 324 320 319 323
+ 163 1 330 326 325 327
+ 164 1 330 326 325 328
+ 165 1 330 326 325 329
+ 166 1 336 332 331 333
+ 167 1 336 332 331 334
+ 168 1 336 332 331 335
+ 169 1 342 338 337 339
+ 170 1 342 338 337 340
+ 171 1 342 338 337 341
+ 172 1 348 344 343 345
+ 173 1 348 344 343 346
+ 174 1 348 344 343 347
+ 175 1 354 350 349 351
+ 176 1 354 350 349 352
+ 177 1 354 350 349 353
+ 178 1 360 356 355 357
+ 179 1 360 356 355 358
+ 180 1 360 356 355 359
+ 181 1 366 362 361 363
+ 182 1 366 362 361 364
+ 183 1 366 362 361 365
+ 184 1 372 368 367 369
+ 185 1 372 368 367 370
+ 186 1 372 368 367 371
+ 187 1 378 374 373 375
+ 188 1 378 374 373 376
+ 189 1 378 374 373 377
+ 190 1 384 380 379 381
+ 191 1 384 380 379 382
+ 192 1 384 380 379 383
+
+Impropers
+
diff --git a/examples/dreiding/in.dreiding b/examples/dreiding/in.dreiding
new file mode 100644
index 0000000000..4b811248d4
--- /dev/null
+++ b/examples/dreiding/in.dreiding
@@ -0,0 +1,39 @@
+units real
+atom_style full
+boundary p p p
+dielectric 1
+special_bonds lj/coul 0.0 0.0 1.0
+
+pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5
+bond_style harmonic
+angle_style harmonic
+dihedral_style harmonic
+improper_style none
+kspace_style pppm 0.001
+
+read_data data.dreiding
+
+pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478
+pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478
+pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677
+pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103
+pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478
+pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677
+pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103
+pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877
+pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302
+pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727
+pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4
+pair_modify mix arithmetic
+neighbor 2.0 multi
+neigh_modify every 2 delay 4 check yes
+variable input index in.ch3oh.box.dreiding
+variable sname index ch3oh.box.dreiding
+
+compute hb all pair hbond/dreiding/lj
+variable C_hbond equal c_hb[1] #number hbonds
+variable E_hbond equal c_hb[2] #hbond energy
+thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol
+thermo_modify line multi format float %14.6f
+
+run 0
diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.1 b/examples/dreiding/log.dreiding.11Oct11.linux.1
new file mode 100644
index 0000000000..74267f98cc
--- /dev/null
+++ b/examples/dreiding/log.dreiding.11Oct11.linux.1
@@ -0,0 +1,97 @@
+LAMMPS (10 Oct 2011)
+units real
+atom_style full
+boundary p p p
+dielectric 1
+special_bonds lj/coul 0.0 0.0 1.0
+
+pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5
+bond_style harmonic
+angle_style harmonic
+dihedral_style harmonic
+improper_style none
+kspace_style pppm 0.001
+
+read_data data.dreiding
+ 4 = max bonds/atom
+ 6 = max angles/atom
+ 3 = max dihedrals/atom
+ 0 = max impropers/atom
+ orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697)
+ 1 by 1 by 1 processor grid
+ 384 atoms
+ 320 bonds
+ 448 angles
+ 192 dihedrals
+ 0 impropers
+ 4 = max # of 1-2 neighbors
+ 3 = max # of 1-3 neighbors
+ 5 = max # of special neighbors
+
+pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478
+pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478
+pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677
+pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103
+pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478
+pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677
+pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103
+pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877
+pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302
+pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727
+pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4
+pair_modify mix arithmetic
+neighbor 2.0 multi
+neigh_modify every 2 delay 4 check yes
+variable input index in.ch3oh.box.dreiding
+variable sname index ch3oh.box.dreiding
+
+compute hb all pair hbond/dreiding/lj
+variable C_hbond equal c_hb[1] #number hbonds
+variable E_hbond equal c_hb[2] #hbond energy
+thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol
+thermo_modify line multi format float %14.6f
+
+run 0
+WARNING: No fixes defined, atoms won't move (verlet.cpp:52)
+PPPM initialization ...
+WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204)
+ G vector = 0.142075
+ grid = 3 3 3
+ stencil order = 5
+ RMS precision = 0.000329493
+ using double precision FFTs
+ brick FFT buffer size/proc = 512 27 576
+Memory usage per processor = 7.9487 Mbytes
+---------------- Step 0 ----- CPU = 0.0000 (sec) ----------------
+TotEng = 113.723443 KinEng = 0.000000 Temp = 0.000000
+PotEng = 113.723443 E_bond = 0.535673 E_angle = 1.281880
+E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324
+E_coul = 597.224193 E_long = -361.169476 E_hbond = -69.322152
+C_hbond = 235.000000 Press = -847.552598 Volume = 7447.236335
+Loop time of 0 on 1 procs for 0 steps with 384 atoms
+
+Pair time (%) = 0 (0)
+Bond time (%) = 0 (0)
+Kspce time (%) = 0 (0)
+Neigh time (%) = 0 (0)
+Comm time (%) = 0 (0)
+Outpt time (%) = 0 (0)
+Other time (%) = 0 (0)
+
+FFT time (% of Kspce) = 0 (0)
+FFT Gflps 3d (1d only) = 0 0
+
+Nlocal: 384 ave 384 max 384 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 4637 ave 4637 max 4637 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 101854 ave 101854 max 101854 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+FullNghs: 203708 ave 203708 max 203708 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 203708
+Ave neighs/atom = 530.49
+Ave special neighs/atom = 4
+Neighbor list builds = 0
+Dangerous builds = 0
diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.4 b/examples/dreiding/log.dreiding.11Oct11.linux.4
new file mode 100644
index 0000000000..3f0ac1c40d
--- /dev/null
+++ b/examples/dreiding/log.dreiding.11Oct11.linux.4
@@ -0,0 +1,121 @@
+LAMMPS (10 Oct 2011)
+units real
+atom_style full
+boundary p p p
+dielectric 1
+special_bonds lj/coul 0.0 0.0 1.0
+
+pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5
+bond_style harmonic
+angle_style harmonic
+dihedral_style harmonic
+improper_style none
+kspace_style pppm 0.001
+
+read_data data.dreiding
+ 4 = max bonds/atom
+ 6 = max angles/atom
+ 3 = max dihedrals/atom
+ 0 = max impropers/atom
+ orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697)
+ 2 by 1 by 2 processor grid
+ 384 atoms
+ 320 bonds
+ 448 angles
+ 192 dihedrals
+ 0 impropers
+ 4 = max # of 1-2 neighbors
+ 3 = max # of 1-3 neighbors
+ 5 = max # of special neighbors
+
+pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478
+pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478
+pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677
+pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103
+pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478
+pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677
+pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103
+pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877
+pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302
+pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727
+pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4
+pair_modify mix arithmetic
+neighbor 2.0 multi
+neigh_modify every 2 delay 4 check yes
+variable input index in.ch3oh.box.dreiding
+variable sname index ch3oh.box.dreiding
+
+compute hb all pair hbond/dreiding/lj
+variable C_hbond equal c_hb[1] #number hbonds
+variable E_hbond equal c_hb[2] #hbond energy
+thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol
+thermo_modify line multi format float %14.6f
+
+run 0
+WARNING: No fixes defined, atoms won't move (verlet.cpp:52)
+PPPM initialization ...
+WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204)
+ G vector = 0.142075
+ grid = 3 3 3
+ stencil order = 5
+ RMS precision = 0.000329493
+ using double precision FFTs
+WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216)
+ G vector = 0.143211
+ grid = 3 3 3
+ stencil order = 4
+ RMS precision = 0.000315601
+ using double precision FFTs
+WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216)
+ G vector = 0.140124
+ grid = 3 3 3
+ stencil order = 3
+ RMS precision = 0.000354326
+ using double precision FFTs
+WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216)
+ G vector = 0.127333
+ grid = 3 3 3
+ stencil order = 2
+ RMS precision = 0.00055716
+ using double precision FFTs
+WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216)
+ G vector = 0.113516
+ grid = 9 9 9
+ stencil order = 1
+ RMS precision = 0.000864991
+ using double precision FFTs
+ brick FFT buffer size/proc = 360 243 360
+Memory usage per processor = 6.52575 Mbytes
+---------------- Step 0 ----- CPU = 0.0000 (sec) ----------------
+TotEng = 118.484313 KinEng = 0.000000 Temp = 0.000000
+PotEng = 118.484313 E_bond = 0.535673 E_angle = 1.281880
+E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324
+E_coul = 529.430008 E_long = -288.614421 E_hbond = -69.322152
+C_hbond = 235.000000 Press = -803.848888 Volume = 7447.236335
+Loop time of 1.43051e-06 on 4 procs for 0 steps with 384 atoms
+
+Pair time (%) = 0 (0)
+Bond time (%) = 0 (0)
+Kspce time (%) = 0 (0)
+Neigh time (%) = 0 (0)
+Comm time (%) = 0 (0)
+Outpt time (%) = 0 (0)
+Other time (%) = 1.43051e-06 (100)
+
+FFT time (% of Kspce) = 0 (0)
+FFT Gflps 3d (1d only) = 0 0
+
+Nlocal: 96 ave 104 max 87 min
+Histogram: 1 1 0 0 0 0 0 0 0 2
+Nghost: 3063.25 ave 3108 max 3024 min
+Histogram: 1 0 1 0 0 0 1 0 0 1
+Neighs: 25463.5 ave 28799 max 22471 min
+Histogram: 1 0 0 1 0 1 0 0 0 1
+FullNghs: 50927 ave 55516 max 46073 min
+Histogram: 1 1 0 0 0 0 0 0 0 2
+
+Total # of neighbors = 203708
+Ave neighs/atom = 530.49
+Ave special neighs/atom = 4
+Neighbor list builds = 0
+Dangerous builds = 0
From 2e2abb3a7271f245fdd267d89dee1781bafc2c30 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 16:36:40 +0000
Subject: [PATCH 11/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7063
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/version.h b/src/version.h
index 9da39c4204..4fc791ad6b 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "10 Oct 2011"
+#define LAMMPS_VERSION "11 Oct 2011"
From e6a0e39b5070a1d0417bf986550d6dea840e4163 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:03:52 +0000
Subject: [PATCH 12/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7065
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/KSPACE/pppm.cpp | 24 +++++++-------
src/KSPACE/pppm.h | 1 -
src/KSPACE/pppm_cg.cpp | 9 ++++--
src/MANYBODY/pair_tersoff.cpp | 34 ++++---------------
src/MANYBODY/pair_tersoff.h | 54 +++++++++++++++++++++++--------
src/MANYBODY/pair_tersoff_zbl.cpp | 6 ++--
src/USER-EWALDN/math_vector.h | 1 +
7 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp
index cc92e1719f..221778e6ee 100644
--- a/src/KSPACE/pppm.cpp
+++ b/src/KSPACE/pppm.cpp
@@ -35,7 +35,10 @@
#include "memory.h"
#include "error.h"
+#include "math_const.h"
+
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXORDER 7
#define OFFSET 16384
@@ -58,7 +61,6 @@ PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
if (narg < 1) error->all(FLERR,"Illegal kspace_style pppm command");
precision = atof(arg[0]);
- PI = 4.0*atan(1.0);
nfactors = 3;
factors = new int[nfactors];
@@ -520,9 +522,9 @@ void PPPM::setup()
delvolinv = delxinv*delyinv*delzinv;
- double unitkx = (2.0*PI/xprd);
- double unitky = (2.0*PI/yprd);
- double unitkz = (2.0*PI/zprd_slab);
+ double unitkx = (2.0*MY_PI/xprd);
+ double unitky = (2.0*MY_PI/yprd);
+ double unitkz = (2.0*MY_PI/zprd_slab);
// fkx,fky,fkz for my FFT grid pts
@@ -581,11 +583,11 @@ void PPPM::setup()
double sum1,dot1,dot2;
double numerator,denominator;
- int nbx = static_cast ((g_ewald*xprd/(PI*nx_pppm)) *
+ int nbx = static_cast ((g_ewald*xprd/(MY_PI*nx_pppm)) *
pow(-log(EPS_HOC),0.25));
- int nby = static_cast ((g_ewald*yprd/(PI*ny_pppm)) *
+ int nby = static_cast ((g_ewald*yprd/(MY_PI*ny_pppm)) *
pow(-log(EPS_HOC),0.25));
- int nbz = static_cast ((g_ewald*zprd_slab/(PI*nz_pppm)) *
+ int nbz = static_cast ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) *
pow(-log(EPS_HOC),0.25));
double form = 1.0;
@@ -708,7 +710,7 @@ void PPPM::compute(int eflag, int vflag)
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e*scale;
}
@@ -1027,7 +1029,7 @@ double PPPM::rms(double h, double prd, bigint natoms,
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);
+ sqrt(g_ewald*prd*sqrt(2.0*MY_PI)*sum/natoms) / (prd*prd);
return value;
}
@@ -1873,13 +1875,13 @@ void PPPM::slabcorr(int eflag)
// compute corrections
- double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume;
+ double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
if (eflag) energy += qqrd2e*scale * e_slabcorr;
// add on force corrections
- double ffact = -4.0*PI*dipole_all/volume;
+ double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact;
diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h
index 982b8f7c9e..e2a58e8804 100644
--- a/src/KSPACE/pppm.h
+++ b/src/KSPACE/pppm.h
@@ -47,7 +47,6 @@ class PPPM : public KSpace {
protected:
int me,nprocs;
- double PI;
double precision;
int nfactors;
int *factors;
diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp
index 12860f7aed..5f57715f9f 100644
--- a/src/KSPACE/pppm_cg.cpp
+++ b/src/KSPACE/pppm_cg.cpp
@@ -26,7 +26,10 @@
#include "memory.h"
#include "pppm_cg.h"
+#include "math_const.h"
+
using namespace LAMMPS_NS;
+using namespace MathConst;
#define OFFSET 16384
#define SMALLQ 0.00001
@@ -176,7 +179,7 @@ void PPPMCG::compute(int eflag, int vflag)
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e*scale;
}
@@ -372,13 +375,13 @@ void PPPMCG::slabcorr(int eflag)
// compute corrections
- double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume;
+ double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
if (eflag) energy += qqrd2e*scale * e_slabcorr;
// add on force corrections
- double ffact = -4.0*PI*dipole_all/volume * qqrd2e * scale;
+ double ffact = -4.0*MY_PI*dipole_all/volume * qqrd2e * scale;
double **f = atom->f;
for (int j = 0; j < num_charged; j++) {
diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp
index bd50ec9bd3..7771bb1982 100755
--- a/src/MANYBODY/pair_tersoff.cpp
+++ b/src/MANYBODY/pair_tersoff.cpp
@@ -29,7 +29,10 @@
#include "memory.h"
#include "error.h"
+#include "math_const.h"
+
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXLINE 1024
#define DELTA 4
@@ -41,10 +44,6 @@ PairTersoff::PairTersoff(LAMMPS *lmp) : Pair(lmp)
single_enable = 0;
one_coeff = 1;
- PI = 4.0*atan(1.0);
- PI2 = 2.0*atan(1.0);
- PI4 = atan(1.0);
-
nelements = 0;
elements = NULL;
nparams = maxparam = 0;
@@ -634,7 +633,7 @@ double PairTersoff::ters_fc(double r, Param *param)
if (r < ters_R-ters_D) return 1.0;
if (r > ters_R+ters_D) return 0.0;
- return 0.5*(1.0 - sin(PI2*(r - ters_R)/ters_D));
+ return 0.5*(1.0 - sin(MY_PI2*(r - ters_R)/ters_D));
}
/* ---------------------------------------------------------------------- */
@@ -646,7 +645,7 @@ double PairTersoff::ters_fc_d(double r, Param *param)
if (r < ters_R-ters_D) return 0.0;
if (r > ters_R+ters_D) return 0.0;
- return -(PI4/ters_D) * cos(PI2*(r - ters_R)/ters_D);
+ return -(MY_PI4/ters_D) * cos(MY_PI2*(r - ters_R)/ters_D);
}
/* ---------------------------------------------------------------------- */
@@ -700,27 +699,6 @@ double PairTersoff::ters_bij_d(double zeta, Param *param)
/* ---------------------------------------------------------------------- */
-double PairTersoff::ters_gijk(double costheta, Param *param)
-{
- double ters_c = param->c;
- double ters_d = param->d;
-
- return param->gamma*(1.0 + pow(ters_c/ters_d,2.0) -
- pow(ters_c,2.0) / (pow(ters_d,2.0) + pow(param->h - costheta,2.0)));
-};
-
-/* ---------------------------------------------------------------------- */
-
-double PairTersoff::ters_gijk_d(double costheta, Param *param)
-{
- double numerator = -2.0 * pow(param->c,2) * (param->h - costheta);
- double denominator = pow(pow(param->d,2.0) +
- pow(param->h - costheta,2.0),2.0);
- return param->gamma*numerator/denominator;
-}
-
-/* ---------------------------------------------------------------------- */
-
void PairTersoff::ters_zetaterm_d(double prefactor,
double *rij_hat, double rij,
double *rik_hat, double rik,
@@ -794,4 +772,4 @@ void PairTersoff::costheta_d(double *rij_hat, double rij,
vec3_scale(1.0/rik,drk,drk);
vec3_add(drj,drk,dri);
vec3_scale(-1.0,dri,dri);
-};
+}
diff --git a/src/MANYBODY/pair_tersoff.h b/src/MANYBODY/pair_tersoff.h
index 49d3079286..92dbe635bd 100755
--- a/src/MANYBODY/pair_tersoff.h
+++ b/src/MANYBODY/pair_tersoff.h
@@ -28,7 +28,7 @@ class PairTersoff : public Pair {
public:
PairTersoff(class LAMMPS *);
virtual ~PairTersoff();
- void compute(int, int);
+ virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
void init_style();
@@ -49,22 +49,22 @@ class PairTersoff : public Pair {
double ZBLcut,ZBLexpscale;
};
- double PI,PI2,PI4;
- double cutmax; // max cutoff for all elements
- int nelements; // # of unique elements
+ Param *params; // parameter set for an I-J-K interaction
char **elements; // names of unique elements
int ***elem2param; // mapping from element triplets to parameters
int *map; // mapping from atom types to elements
+ double cutmax; // max cutoff for all elements
+ int nelements; // # of unique elements
int nparams; // # of stored parameter sets
int maxparam; // max # of parameter sets
- Param *params; // parameter set for an I-J-K interaction
void allocate();
virtual void read_file(char *);
void setup();
virtual void repulsive(Param *, double, double &, int, double &);
double zeta(Param *, double, double, double *, double *);
- void force_zeta(Param *, double, double, double &, double &, int, double &);
+ virtual void force_zeta(Param *, double, double, double &,
+ double &, int, double &);
void attractive(Param *, double, double, double, double *, double *,
double *, double *, double *);
@@ -74,26 +74,52 @@ class PairTersoff : public Pair {
virtual double ters_fa_d(double, Param *);
double ters_bij(double, Param *);
double ters_bij_d(double, Param *);
- double ters_gijk(double, Param *);
- double ters_gijk_d(double, Param *);
+
void ters_zetaterm_d(double, double *, double, double *, double,
double *, double *, double *, Param *);
void costheta_d(double *, double, double *, double,
double *, double *, double *);
- // vector functions, inline for efficiency
+ // inlined functions for efficiency
- inline double vec3_dot(double *x, double *y) {
+ inline double ters_gijk(const double costheta,
+ const Param * const param) const {
+ const double ters_c = param->c * param->c;
+ const double ters_d = param->d * param->d;
+ const double hcth = param->h - costheta;
+
+ return param->gamma*(1.0 + ters_c/ters_d - ters_c / (ters_d + hcth*hcth));
+ }
+
+ inline double ters_gijk_d(const double costheta,
+ const Param * const param) const {
+ const double ters_c = param->c * param->c;
+ const double ters_d = param->d * param->d;
+ const double hcth = param->h - costheta;
+ const double numerator = -2.0 * ters_c * hcth;
+ const double denominator = 1.0/(ters_d + hcth*hcth);
+ return param->gamma*numerator*denominator*denominator;
+ }
+
+ inline double vec3_dot(const double x[3], const double y[3]) const {
return x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
}
- inline void vec3_add(double *x, double *y, double *z) {
+
+ inline void vec3_add(const double x[3], const double y[3],
+ double * const z) const {
z[0] = x[0]+y[0]; z[1] = x[1]+y[1]; z[2] = x[2]+y[2];
}
- inline void vec3_scale(double k, double *x, double *y) {
+
+ inline void vec3_scale(const double k, const double x[3],
+ double y[3]) const {
y[0] = k*x[0]; y[1] = k*x[1]; y[2] = k*x[2];
}
- inline void vec3_scaleadd(double k, double *x, double *y, double *z) {
- z[0] = k*x[0]+y[0]; z[1] = k*x[1]+y[1]; z[2] = k*x[2]+y[2];
+
+ inline void vec3_scaleadd(const double k, const double x[3],
+ const double y[3], double * const z) const {
+ z[0] = k*x[0]+y[0];
+ z[1] = k*x[1]+y[1];
+ z[2] = k*x[2]+y[2];
}
};
diff --git a/src/MANYBODY/pair_tersoff_zbl.cpp b/src/MANYBODY/pair_tersoff_zbl.cpp
index 90ccfd9c11..a4f6ee3edd 100644
--- a/src/MANYBODY/pair_tersoff_zbl.cpp
+++ b/src/MANYBODY/pair_tersoff_zbl.cpp
@@ -31,7 +31,9 @@
#include "memory.h"
#include "error.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXLINE 1024
#define DELTA 4
@@ -224,7 +226,7 @@ void PairTersoffZBL::repulsive(Param *param, double rsq, double &fforce,
double esq = pow(global_e,2.0);
double a_ij = (0.8854*global_a_0) /
(pow(param->Z_i,0.23) + pow(param->Z_j,0.23));
- double premult = (param->Z_i * param->Z_j * esq)/(4.0*PI*global_epsilon_0);
+ double premult = (param->Z_i * param->Z_j * esq)/(4.0*MY_PI*global_epsilon_0);
double r_ov_a = r/a_ij;
double phi = 0.1818*exp(-3.2*r_ov_a) + 0.5099*exp(-0.9423*r_ov_a) +
0.2802*exp(-0.4029*r_ov_a) + 0.02817*exp(-0.2016*r_ov_a);
@@ -232,7 +234,7 @@ void PairTersoffZBL::repulsive(Param *param, double rsq, double &fforce,
0.9423*0.5099*exp(-0.9423*r_ov_a) -
0.4029*0.2802*exp(-0.4029*r_ov_a) -
0.2016*0.02817*exp(-0.2016*r_ov_a));
- double fforce_ZBL = premult*-pow(r,-2.0)* phi + premult*pow(r,-1.0)*dphi;
+ double fforce_ZBL = premult*-phi/rsq + premult*dphi/r;
double eng_ZBL = premult*(1.0/r)*phi;
// combine two parts with smoothing by Fermi-like function
diff --git a/src/USER-EWALDN/math_vector.h b/src/USER-EWALDN/math_vector.h
index 90fc7ee464..b7473b5d89 100644
--- a/src/USER-EWALDN/math_vector.h
+++ b/src/USER-EWALDN/math_vector.h
@@ -19,6 +19,7 @@
#define LMP_MATH_VECTOR_H
#include "math.h"
+#include "string.h"
#define VECTOR_NULL {0, 0, 0}
#define SHAPE_NULL {0, 0, 0, 0, 0, 0}
From 90a5d2b322bf384b89d7903647c82005483ec5f9 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:11:58 +0000
Subject: [PATCH 13/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7066
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-OMP/Install.sh | 40 +-
src/USER-OMP/Package.sh | 15 +-
src/USER-OMP/dihedral_charmm_omp.cpp | 328 ++++++++++
src/USER-OMP/dihedral_charmm_omp.h | 48 ++
src/USER-OMP/dihedral_class2_omp.cpp | 532 ++++++++++++++++
src/USER-OMP/dihedral_class2_omp.h | 48 ++
.../dihedral_cosine_shift_exp_omp.cpp | 263 ++++++++
src/USER-OMP/dihedral_cosine_shift_exp_omp.h | 48 ++
src/USER-OMP/dihedral_harmonic_omp.cpp | 270 ++++++++
src/USER-OMP/dihedral_harmonic_omp.h | 48 ++
src/USER-OMP/dihedral_helix_omp.cpp | 280 +++++++++
src/USER-OMP/dihedral_helix_omp.h | 48 ++
src/USER-OMP/dihedral_multi_harmonic_omp.cpp | 269 ++++++++
src/USER-OMP/dihedral_multi_harmonic_omp.h | 48 ++
src/USER-OMP/dihedral_opls_omp.cpp | 286 +++++++++
src/USER-OMP/dihedral_opls_omp.h | 48 ++
src/USER-OMP/fix_gravity_omp.cpp | 114 ++++
src/USER-OMP/fix_gravity_omp.h | 38 ++
src/USER-OMP/fix_nve_sphere_omp.cpp | 140 +++++
src/USER-OMP/fix_nve_sphere_omp.h | 39 ++
src/USER-OMP/fix_qeq_comb_omp.cpp | 166 +++++
src/USER-OMP/fix_qeq_comb_omp.h | 32 +
src/USER-OMP/fix_shear_history_omp.cpp | 150 +++++
src/USER-OMP/fix_shear_history_omp.h | 38 ++
src/USER-OMP/pair_adp_omp.cpp | 404 ++++++++++++
src/USER-OMP/pair_adp_omp.h | 49 ++
src/USER-OMP/pair_born_coul_long_omp.cpp | 199 ++++++
src/USER-OMP/pair_born_coul_long_omp.h | 48 ++
src/USER-OMP/pair_born_omp.cpp | 163 +++++
src/USER-OMP/pair_born_omp.h | 48 ++
src/USER-OMP/pair_buck_coul_cut_omp.cpp | 182 ++++++
src/USER-OMP/pair_buck_coul_cut_omp.h | 48 ++
src/USER-OMP/pair_buck_coul_long_omp.cpp | 198 ++++++
src/USER-OMP/pair_buck_coul_long_omp.h | 48 ++
src/USER-OMP/pair_buck_coul_omp.cpp | 230 +++++++
src/USER-OMP/pair_buck_coul_omp.h | 48 ++
src/USER-OMP/pair_buck_omp.cpp | 165 +++++
src/USER-OMP/pair_buck_omp.h | 48 ++
src/USER-OMP/pair_cdeam_omp.cpp | 545 +++++++++++++++++
src/USER-OMP/pair_cdeam_omp.h | 66 ++
src/USER-OMP/pair_colloid_omp.cpp | 223 +++++++
src/USER-OMP/pair_colloid_omp.h | 48 ++
src/USER-OMP/pair_comb_omp.cpp | 540 ++++++++++++++++
src/USER-OMP/pair_comb_omp.h | 45 ++
src/USER-OMP/pair_coul_cut_omp.cpp | 162 +++++
src/USER-OMP/pair_coul_cut_omp.h | 48 ++
src/USER-OMP/pair_coul_debye_omp.cpp | 163 +++++
src/USER-OMP/pair_coul_debye_omp.h | 48 ++
src/USER-OMP/pair_coul_long_omp.cpp | 201 ++++++
src/USER-OMP/pair_coul_long_omp.h | 48 ++
src/USER-OMP/pair_dipole_cut_omp.cpp | 288 +++++++++
src/USER-OMP/pair_dipole_cut_omp.h | 48 ++
src/USER-OMP/pair_dipole_sf_omp.cpp | 320 ++++++++++
src/USER-OMP/pair_dipole_sf_omp.h | 48 ++
src/USER-OMP/pair_dpd_omp.cpp | 212 +++++++
src/USER-OMP/pair_dpd_omp.h | 52 ++
src/USER-OMP/pair_dpd_tstat_omp.cpp | 214 +++++++
src/USER-OMP/pair_dpd_tstat_omp.h | 52 ++
src/USER-OMP/pair_eam_alloy_omp.cpp | 323 ++++++++++
src/USER-OMP/pair_eam_alloy_omp.h | 43 ++
src/USER-OMP/pair_eam_fs_omp.cpp | 332 ++++++++++
src/USER-OMP/pair_eam_fs_omp.h | 43 ++
src/USER-OMP/pair_eam_omp.cpp | 303 +++++++++
src/USER-OMP/pair_eam_omp.h | 48 ++
src/USER-OMP/pair_edip_omp.cpp | 485 +++++++++++++++
src/USER-OMP/pair_edip_omp.h | 43 ++
src/USER-OMP/pair_eim_omp.cpp | 365 +++++++++++
src/USER-OMP/pair_eim_omp.h | 48 ++
src/USER-OMP/pair_gauss_omp.cpp | 170 ++++++
src/USER-OMP/pair_gauss_omp.h | 48 ++
src/USER-OMP/pair_gayberne_omp.cpp | 227 +++++++
src/USER-OMP/pair_gayberne_omp.h | 48 ++
src/USER-OMP/pair_gran_hertz_history_omp.cpp | 298 +++++++++
src/USER-OMP/pair_gran_hertz_history_omp.h | 48 ++
src/USER-OMP/pair_gran_hooke_history_omp.cpp | 301 +++++++++
src/USER-OMP/pair_gran_hooke_history_omp.h | 48 ++
src/USER-OMP/pair_gran_hooke_omp.cpp | 240 ++++++++
src/USER-OMP/pair_gran_hooke_omp.h | 48 ++
src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp | 299 +++++++++
src/USER-OMP/pair_hbond_dreiding_lj_omp.h | 52 ++
.../pair_hbond_dreiding_morse_omp.cpp | 297 +++++++++
src/USER-OMP/pair_hbond_dreiding_morse_omp.h | 52 ++
src/USER-OMP/pair_lj96_cut_omp.cpp | 162 +++++
src/USER-OMP/pair_lj96_cut_omp.h | 48 ++
...air_lj_charmm_coul_charmm_implicit_omp.cpp | 213 +++++++
.../pair_lj_charmm_coul_charmm_implicit_omp.h | 48 ++
.../pair_lj_charmm_coul_charmm_omp.cpp | 213 +++++++
src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h | 48 ++
src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp | 234 +++++++
src/USER-OMP/pair_lj_charmm_coul_long_omp.h | 48 ++
src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp | 185 ++++++
src/USER-OMP/pair_lj_class2_coul_cut_omp.h | 48 ++
src/USER-OMP/pair_lj_class2_coul_long_omp.cpp | 201 ++++++
src/USER-OMP/pair_lj_class2_coul_long_omp.h | 48 ++
src/USER-OMP/pair_lj_class2_omp.cpp | 162 +++++
src/USER-OMP/pair_lj_class2_omp.h | 48 ++
src/USER-OMP/pair_lj_coul_omp.cpp | 234 +++++++
src/USER-OMP/pair_lj_coul_omp.h | 48 ++
src/USER-OMP/pair_lj_cubic_omp.cpp | 173 ++++++
src/USER-OMP/pair_lj_cubic_omp.h | 48 ++
src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp | 183 ++++++
src/USER-OMP/pair_lj_cut_coul_cut_omp.h | 48 ++
src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp | 186 ++++++
src/USER-OMP/pair_lj_cut_coul_debye_omp.h | 48 ++
src/USER-OMP/pair_lj_cut_coul_long_omp.cpp | 220 +++++++
src/USER-OMP/pair_lj_cut_coul_long_omp.h | 48 ++
.../pair_lj_cut_coul_long_tip4p_omp.cpp | 462 ++++++++++++++
.../pair_lj_cut_coul_long_tip4p_omp.h | 57 ++
src/USER-OMP/pair_lj_cut_omp.cpp | 5 +-
src/USER-OMP/pair_lj_expand_omp.cpp | 164 +++++
src/USER-OMP/pair_lj_expand_omp.h | 48 ++
.../pair_lj_gromacs_coul_gromacs_omp.cpp | 210 +++++++
.../pair_lj_gromacs_coul_gromacs_omp.h | 48 ++
src/USER-OMP/pair_lj_gromacs_omp.cpp | 172 ++++++
src/USER-OMP/pair_lj_gromacs_omp.h | 48 ++
src/USER-OMP/pair_lj_sf_omp.cpp | 163 +++++
src/USER-OMP/pair_lj_sf_omp.h | 48 ++
src/USER-OMP/pair_lj_smooth_omp.cpp | 176 ++++++
src/USER-OMP/pair_lj_smooth_omp.h | 48 ++
src/USER-OMP/pair_lubricate_omp.cpp | 328 ++++++++++
src/USER-OMP/pair_lubricate_omp.h | 52 ++
src/USER-OMP/pair_morse_omp.cpp | 160 +++++
src/USER-OMP/pair_morse_omp.h | 48 ++
src/USER-OMP/pair_peri_lps_omp.cpp | 456 ++++++++++++++
src/USER-OMP/pair_peri_lps_omp.h | 52 ++
src/USER-OMP/pair_peri_pmb_omp.cpp | 312 ++++++++++
src/USER-OMP/pair_peri_pmb_omp.h | 48 ++
src/USER-OMP/pair_rebo_omp.cpp | 33 +
src/USER-OMP/pair_rebo_omp.h | 36 ++
src/USER-OMP/pair_resquared_omp.cpp | 210 +++++++
src/USER-OMP/pair_resquared_omp.h | 48 ++
src/USER-OMP/pair_soft_omp.cpp | 160 +++++
src/USER-OMP/pair_soft_omp.h | 48 ++
src/USER-OMP/pair_sw_omp.cpp | 212 +++++++
src/USER-OMP/pair_sw_omp.h | 48 ++
src/USER-OMP/pair_table_omp.cpp | 202 ++++++
src/USER-OMP/pair_table_omp.h | 48 ++
src/USER-OMP/pair_tersoff_omp.cpp | 252 ++++++++
src/USER-OMP/pair_tersoff_omp.h | 43 ++
src/USER-OMP/pair_tersoff_zbl_omp.cpp | 296 +++++++++
src/USER-OMP/pair_tersoff_zbl_omp.h | 45 ++
src/USER-OMP/pair_yukawa_colloid_omp.cpp | 164 +++++
src/USER-OMP/pair_yukawa_colloid_omp.h | 48 ++
src/USER-OMP/pair_yukawa_omp.cpp | 162 +++++
src/USER-OMP/pair_yukawa_omp.h | 48 ++
src/USER-OMP/thr_omp.cpp | 577 +++++++++++++++---
src/USER-OMP/thr_omp.h | 41 +-
147 files changed, 21457 insertions(+), 105 deletions(-)
create mode 100644 src/USER-OMP/dihedral_charmm_omp.cpp
create mode 100644 src/USER-OMP/dihedral_charmm_omp.h
create mode 100644 src/USER-OMP/dihedral_class2_omp.cpp
create mode 100644 src/USER-OMP/dihedral_class2_omp.h
create mode 100644 src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
create mode 100644 src/USER-OMP/dihedral_cosine_shift_exp_omp.h
create mode 100644 src/USER-OMP/dihedral_harmonic_omp.cpp
create mode 100644 src/USER-OMP/dihedral_harmonic_omp.h
create mode 100644 src/USER-OMP/dihedral_helix_omp.cpp
create mode 100644 src/USER-OMP/dihedral_helix_omp.h
create mode 100644 src/USER-OMP/dihedral_multi_harmonic_omp.cpp
create mode 100644 src/USER-OMP/dihedral_multi_harmonic_omp.h
create mode 100644 src/USER-OMP/dihedral_opls_omp.cpp
create mode 100644 src/USER-OMP/dihedral_opls_omp.h
create mode 100644 src/USER-OMP/fix_gravity_omp.cpp
create mode 100644 src/USER-OMP/fix_gravity_omp.h
create mode 100644 src/USER-OMP/fix_nve_sphere_omp.cpp
create mode 100644 src/USER-OMP/fix_nve_sphere_omp.h
create mode 100644 src/USER-OMP/fix_qeq_comb_omp.cpp
create mode 100644 src/USER-OMP/fix_qeq_comb_omp.h
create mode 100644 src/USER-OMP/fix_shear_history_omp.cpp
create mode 100644 src/USER-OMP/fix_shear_history_omp.h
create mode 100644 src/USER-OMP/pair_adp_omp.cpp
create mode 100644 src/USER-OMP/pair_adp_omp.h
create mode 100644 src/USER-OMP/pair_born_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_born_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_born_omp.cpp
create mode 100644 src/USER-OMP/pair_born_omp.h
create mode 100644 src/USER-OMP/pair_buck_coul_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_buck_coul_cut_omp.h
create mode 100644 src/USER-OMP/pair_buck_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_buck_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_buck_coul_omp.cpp
create mode 100644 src/USER-OMP/pair_buck_coul_omp.h
create mode 100644 src/USER-OMP/pair_buck_omp.cpp
create mode 100644 src/USER-OMP/pair_buck_omp.h
create mode 100644 src/USER-OMP/pair_cdeam_omp.cpp
create mode 100644 src/USER-OMP/pair_cdeam_omp.h
create mode 100644 src/USER-OMP/pair_colloid_omp.cpp
create mode 100644 src/USER-OMP/pair_colloid_omp.h
create mode 100644 src/USER-OMP/pair_comb_omp.cpp
create mode 100644 src/USER-OMP/pair_comb_omp.h
create mode 100644 src/USER-OMP/pair_coul_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_coul_cut_omp.h
create mode 100644 src/USER-OMP/pair_coul_debye_omp.cpp
create mode 100644 src/USER-OMP/pair_coul_debye_omp.h
create mode 100644 src/USER-OMP/pair_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_dipole_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_dipole_cut_omp.h
create mode 100644 src/USER-OMP/pair_dipole_sf_omp.cpp
create mode 100644 src/USER-OMP/pair_dipole_sf_omp.h
create mode 100644 src/USER-OMP/pair_dpd_omp.cpp
create mode 100644 src/USER-OMP/pair_dpd_omp.h
create mode 100644 src/USER-OMP/pair_dpd_tstat_omp.cpp
create mode 100644 src/USER-OMP/pair_dpd_tstat_omp.h
create mode 100644 src/USER-OMP/pair_eam_alloy_omp.cpp
create mode 100644 src/USER-OMP/pair_eam_alloy_omp.h
create mode 100644 src/USER-OMP/pair_eam_fs_omp.cpp
create mode 100644 src/USER-OMP/pair_eam_fs_omp.h
create mode 100644 src/USER-OMP/pair_eam_omp.cpp
create mode 100644 src/USER-OMP/pair_eam_omp.h
create mode 100644 src/USER-OMP/pair_edip_omp.cpp
create mode 100644 src/USER-OMP/pair_edip_omp.h
create mode 100644 src/USER-OMP/pair_eim_omp.cpp
create mode 100644 src/USER-OMP/pair_eim_omp.h
create mode 100644 src/USER-OMP/pair_gauss_omp.cpp
create mode 100644 src/USER-OMP/pair_gauss_omp.h
create mode 100644 src/USER-OMP/pair_gayberne_omp.cpp
create mode 100644 src/USER-OMP/pair_gayberne_omp.h
create mode 100644 src/USER-OMP/pair_gran_hertz_history_omp.cpp
create mode 100644 src/USER-OMP/pair_gran_hertz_history_omp.h
create mode 100644 src/USER-OMP/pair_gran_hooke_history_omp.cpp
create mode 100644 src/USER-OMP/pair_gran_hooke_history_omp.h
create mode 100644 src/USER-OMP/pair_gran_hooke_omp.cpp
create mode 100644 src/USER-OMP/pair_gran_hooke_omp.h
create mode 100644 src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
create mode 100644 src/USER-OMP/pair_hbond_dreiding_lj_omp.h
create mode 100644 src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
create mode 100644 src/USER-OMP/pair_hbond_dreiding_morse_omp.h
create mode 100644 src/USER-OMP/pair_lj96_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_lj96_cut_omp.h
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_charmm_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_class2_coul_cut_omp.h
create mode 100644 src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_class2_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_lj_class2_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_class2_omp.h
create mode 100644 src/USER-OMP/pair_lj_coul_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_coul_omp.h
create mode 100644 src/USER-OMP/pair_lj_cubic_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_cubic_omp.h
create mode 100644 src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_cut_coul_cut_omp.h
create mode 100644 src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_cut_coul_debye_omp.h
create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_omp.h
create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
create mode 100644 src/USER-OMP/pair_lj_expand_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_expand_omp.h
create mode 100644 src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
create mode 100644 src/USER-OMP/pair_lj_gromacs_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_gromacs_omp.h
create mode 100644 src/USER-OMP/pair_lj_sf_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_sf_omp.h
create mode 100644 src/USER-OMP/pair_lj_smooth_omp.cpp
create mode 100644 src/USER-OMP/pair_lj_smooth_omp.h
create mode 100644 src/USER-OMP/pair_lubricate_omp.cpp
create mode 100644 src/USER-OMP/pair_lubricate_omp.h
create mode 100644 src/USER-OMP/pair_morse_omp.cpp
create mode 100644 src/USER-OMP/pair_morse_omp.h
create mode 100644 src/USER-OMP/pair_peri_lps_omp.cpp
create mode 100644 src/USER-OMP/pair_peri_lps_omp.h
create mode 100644 src/USER-OMP/pair_peri_pmb_omp.cpp
create mode 100644 src/USER-OMP/pair_peri_pmb_omp.h
create mode 100644 src/USER-OMP/pair_rebo_omp.cpp
create mode 100644 src/USER-OMP/pair_rebo_omp.h
create mode 100644 src/USER-OMP/pair_resquared_omp.cpp
create mode 100644 src/USER-OMP/pair_resquared_omp.h
create mode 100644 src/USER-OMP/pair_soft_omp.cpp
create mode 100644 src/USER-OMP/pair_soft_omp.h
create mode 100644 src/USER-OMP/pair_sw_omp.cpp
create mode 100644 src/USER-OMP/pair_sw_omp.h
create mode 100644 src/USER-OMP/pair_table_omp.cpp
create mode 100644 src/USER-OMP/pair_table_omp.h
create mode 100644 src/USER-OMP/pair_tersoff_omp.cpp
create mode 100644 src/USER-OMP/pair_tersoff_omp.h
create mode 100644 src/USER-OMP/pair_tersoff_zbl_omp.cpp
create mode 100644 src/USER-OMP/pair_tersoff_zbl_omp.h
create mode 100644 src/USER-OMP/pair_yukawa_colloid_omp.cpp
create mode 100644 src/USER-OMP/pair_yukawa_colloid_omp.h
create mode 100644 src/USER-OMP/pair_yukawa_omp.cpp
create mode 100644 src/USER-OMP/pair_yukawa_omp.h
diff --git a/src/USER-OMP/Install.sh b/src/USER-OMP/Install.sh
index 6af8599524..db0beb5218 100644
--- a/src/USER-OMP/Install.sh
+++ b/src/USER-OMP/Install.sh
@@ -1,32 +1,20 @@
# Install/unInstall package files in LAMMPS
# do not install child files if parent does not exist
-if (test $1 = 1) then
+for file in *_omp.cpp *_omp.h; do
+ # let us see if the "rain man" can count the toothpicks...
+ ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
-# if (test -e ../pair_lj_cut_coul_long.cpp) then
-# cp pair_lj_cut_coul_long_omp.cpp ..
-# cp pair_lj_cut_coul_long_omp.h ..
-# fi
+ if (test $1 = 1) then
+ if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then
+ : # always install those files.
+ elif (test ! -e ../$ofile) then
+ continue
+ fi
- cp pair_lj_cut_omp.cpp ..
-
- cp thr_omp.cpp ..
-
- cp pair_lj_cut_omp.h ..
-
- cp thr_omp.h ..
-
-elif (test $1 = 0) then
-
-# rm -f ../pair_lj_cut_coul_long_omp.cpp
- rm -f ../pair_lj_cut_omp.cpp
-
- rm -f ../thr_omp.cpp
-
-# rm -f ../pair_lj_cut_coul_long_omp.h
- rm -f ../pair_lj_cut_omp.h
-
- rm -f ../thr_omp.h
-
-fi
+ cp $file ..
+ elif (test $1 = 0) then
+ rm -f ../$file
+ fi
+done
diff --git a/src/USER-OMP/Package.sh b/src/USER-OMP/Package.sh
index ecd2ebee10..5a004c9187 100644
--- a/src/USER-OMP/Package.sh
+++ b/src/USER-OMP/Package.sh
@@ -1,15 +1,22 @@
-#/bin/sh
# Update package files in LAMMPS
-# copy package file to src if it doesn't exists or is different
-# do not copy gayberne files if non-GPU version does not exist
+# cp package file to src if doesn't exist or is different
+# do not copy certain files if non-OMP versions do not exist
+# do remove OpenMP style files that have no matching
+# non-OpenMP version installed, e.g. after a package has been removed
+
for file in *_omp.cpp *_omp.h; do
# let us see if the "rain man" can count the toothpicks...
ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then
- : # do check for those files.
+ : # always check for those files.
elif (test ! -e ../$ofile) then
+ if (test -e ../$file) then
+ echo " removing src/$file"
+ rm -f ../$file
+ fi
continue
fi
+
if (test ! -e ../$file) then
echo " creating src/$file"
cp $file ..
diff --git a/src/USER-OMP/dihedral_charmm_omp.cpp b/src/USER-OMP/dihedral_charmm_omp.cpp
new file mode 100644
index 0000000000..63bfc43270
--- /dev/null
+++ b/src/USER-OMP/dihedral_charmm_omp.cpp
@@ -0,0 +1,328 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_charmm_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "pair.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralCharmmOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ // insure pair->ev_tally() will use 1-4 virial contribution
+
+ if (weightflag && vflag_global == 2)
+ force->pair->vflag_either = force->pair->vflag_global = 1;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+
+ // reduce contributions to non-bonded energy terms
+ for (int n = 0; n < nthreads; ++n) {
+ force->pair->eng_vdwl += eng_vdwl_thr[n];
+ force->pair->eng_coul += eng_coul_thr[n];
+ }
+}
+
+template
+void DihedralCharmmOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,i,m,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ 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,sx2,sy2,sz2;
+ int itype,jtype;
+ double delx,dely,delz,rsq,r2inv,r6inv;
+ double forcecoul,forcelj,fpair,ecoul,evdwl;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *atomtype = atom->type;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+ double qqrd2e = force->qqrd2e;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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 = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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) edihedral = 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;
+
+ sx2 = df*dtgx;
+ sy2 = df*dtgy;
+ sz2 = df*dtgz;
+
+ f1[0] = df*dtfx;
+ f1[1] = df*dtfy;
+ f1[2] = df*dtfz;
+
+ f2[0] = sx2 - f1[0];
+ f2[1] = sy2 - f1[1];
+ f2[2] = sz2 - f1[2];
+
+ f4[0] = df*dthx;
+ f4[1] = df*dthy;
+ f4[2] = df*dthz;
+
+ f3[0] = -sx2 - f4[0];
+ f3[1] = -sy2 - f4[1];
+ f3[2] = -sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ // 1-4 LJ and Coulomb interactions
+ // tally energy/virial in pair, using newton_bond as newton flag
+
+ 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 (implicit) 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]);
+ fpair = weight[type] * (forcelj+forcecoul)*r2inv;
+
+ if (EFLAG) {
+ ecoul = weight[type] * forcecoul;
+ evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]);
+ evdwl *= weight[type];
+ }
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fpair;
+ f[i1][1] += dely*fpair;
+ f[i1][2] += delz*fpair;
+ }
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] -= delx*fpair;
+ f[i4][1] -= dely*fpair;
+ f[i4][2] -= delz*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(force->pair,i1,i4,nlocal,NEWTON_BOND,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+}
+
diff --git a/src/USER-OMP/dihedral_charmm_omp.h b/src/USER-OMP/dihedral_charmm_omp.h
new file mode 100644
index 0000000000..a39ad83f7e
--- /dev/null
+++ b/src/USER-OMP/dihedral_charmm_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(charmm/omp,DihedralCharmmOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_CHARMM_OMP_H
+#define LMP_DIHEDRAL_CHARMM_OMP_H
+
+#include "dihedral_charmm.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralCharmmOMP : public DihedralCharmm, public ThrOMP {
+
+ public:
+ DihedralCharmmOMP(class LAMMPS *lmp) :
+ DihedralCharmm(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_class2_omp.cpp b/src/USER-OMP/dihedral_class2_omp.cpp
new file mode 100644
index 0000000000..7348296644
--- /dev/null
+++ b/src/USER-OMP/dihedral_class2_omp.cpp
@@ -0,0 +1,532 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_class2_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.0000001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralClass2OMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralClass2OMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,i,j,k,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral;
+ double r1mag2,r1,r2mag2,r2,r3mag2,r3;
+ double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1;
+ double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c;
+ double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2;
+ double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3;
+ double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2;
+ double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0;
+ double r3_0,dr1,dr2,tk1,tk2,s12,sin2;
+ double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3];
+ double fabcd[4][3];
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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);
+
+ // distances
+
+ r1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
+ r1 = sqrt(r1mag2);
+ r2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
+ r2 = sqrt(r2mag2);
+ r3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
+ r3 = sqrt(r3mag2);
+
+ sb1 = 1.0/r1mag2;
+ rb1 = 1.0/r1;
+ sb2 = 1.0/r2mag2;
+ rb2 = 1.0/r2;
+ sb3 = 1.0/r3mag2;
+ rb3 = 1.0/r3;
+
+ c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
+
+ // angles
+
+ r12c1 = rb1*rb2;
+ r12c2 = rb2*rb3;
+ costh12 = (vb1x*vb2x + vb1y*vb2y + vb1z*vb2z) * r12c1;
+ costh13 = c0;
+ costh23 = (vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z) * r12c2;
+
+ // cos and sin of 2 angles and final c
+
+ sin2 = MAX(1.0 - costh12*costh12,0.0);
+ sc1 = sqrt(sin2);
+ if (sc1 < SMALL) sc1 = SMALL;
+ sc1 = 1.0/sc1;
+
+ sin2 = MAX(1.0 - costh23*costh23,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 + costh12*costh23) * s12;
+
+ // error check
+
+ if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
+ int me;
+ MPI_Comm_rank(world,&me);
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+ me,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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;
+ cosphi = c;
+ phi = acos(c);
+
+ sinphi = sqrt(1.0 - c*c);
+ sinphi = MAX(sinphi,SMALL);
+
+ a11 = -c*sb1*s1;
+ a22 = sb2 * (2.0*costh13*s12 - c*(s1+s2));
+ a33 = -c*sb3*s2;
+ a12 = r12c1 * (costh12*c*s1 + costh23*s12);
+ a13 = rb1*rb3*s12;
+ a23 = r12c2 * (-costh23*c*s2 - costh12*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;
+
+ // set up d(cos(phi))/d(r) and dphi/dr arrays
+
+ dcosphidr[0][0] = -sx1;
+ dcosphidr[0][1] = -sy1;
+ dcosphidr[0][2] = -sz1;
+ dcosphidr[1][0] = sx2 + sx1;
+ dcosphidr[1][1] = sy2 + sy1;
+ dcosphidr[1][2] = sz2 + sz1;
+ dcosphidr[2][0] = sx12 - sx2;
+ dcosphidr[2][1] = sy12 - sy2;
+ dcosphidr[2][2] = sz12 - sz2;
+ dcosphidr[3][0] = -sx12;
+ dcosphidr[3][1] = -sy12;
+ dcosphidr[3][2] = -sz12;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ dphidr[i][j] = -dcosphidr[i][j] / sinphi;
+
+ // energy
+
+ dphi1 = phi - phi1[type];
+ dphi2 = 2.0*phi - phi2[type];
+ dphi3 = 3.0*phi - phi3[type];
+
+ if (EFLAG) edihedral = k1[type]*(1.0 - cos(dphi1)) +
+ k2[type]*(1.0 - cos(dphi2)) +
+ k3[type]*(1.0 - cos(dphi3));
+
+ de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) +
+ 3.0*k3[type]*sin(dphi3);
+
+ // torsion forces on all 4 atoms
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] = de_dihedral*dphidr[i][j];
+
+ // set up d(bond)/d(r) array
+ // dbonddr(i,j,k) = bond i, atom j, coordinate k
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++)
+ dbonddr[i][j][k] = 0.0;
+
+ // bond1
+
+ dbonddr[0][0][0] = vb1x / r1;
+ dbonddr[0][0][1] = vb1y / r1;
+ dbonddr[0][0][2] = vb1z / r1;
+ dbonddr[0][1][0] = -vb1x / r1;
+ dbonddr[0][1][1] = -vb1y / r1;
+ dbonddr[0][1][2] = -vb1z / r1;
+
+ // bond2
+
+ dbonddr[1][1][0] = vb2x / r2;
+ dbonddr[1][1][1] = vb2y / r2;
+ dbonddr[1][1][2] = vb2z / r2;
+ dbonddr[1][2][0] = -vb2x / r2;
+ dbonddr[1][2][1] = -vb2y / r2;
+ dbonddr[1][2][2] = -vb2z / r2;
+
+ // bond3
+
+ dbonddr[2][2][0] = vb3x / r3;
+ dbonddr[2][2][1] = vb3y / r3;
+ dbonddr[2][2][2] = vb3z / r3;
+ dbonddr[2][3][0] = -vb3x / r3;
+ dbonddr[2][3][1] = -vb3y / r3;
+ dbonddr[2][3][2] = -vb3z / r3;
+
+ // set up d(theta)/d(r) array
+ // dthetadr(i,j,k) = angle i, atom j, coordinate k
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++)
+ dthetadr[i][j][k] = 0.0;
+
+ t1 = costh12 / r1mag2;
+ t2 = costh23 / r2mag2;
+ t3 = costh12 / r2mag2;
+ t4 = costh23 / r3mag2;
+
+ // angle12
+
+ dthetadr[0][0][0] = sc1 * ((t1 * vb1x) - (vb2x * r12c1));
+ dthetadr[0][0][1] = sc1 * ((t1 * vb1y) - (vb2y * r12c1));
+ dthetadr[0][0][2] = sc1 * ((t1 * vb1z) - (vb2z * r12c1));
+
+ dthetadr[0][1][0] = sc1 * ((-t1 * vb1x) + (vb2x * r12c1) +
+ (-t3 * vb2x) + (vb1x * r12c1));
+ dthetadr[0][1][1] = sc1 * ((-t1 * vb1y) + (vb2y * r12c1) +
+ (-t3 * vb2y) + (vb1y * r12c1));
+ dthetadr[0][1][2] = sc1 * ((-t1 * vb1z) + (vb2z * r12c1) +
+ (-t3 * vb2z) + (vb1z * r12c1));
+
+ dthetadr[0][2][0] = sc1 * ((t3 * vb2x) - (vb1x * r12c1));
+ dthetadr[0][2][1] = sc1 * ((t3 * vb2y) - (vb1y * r12c1));
+ dthetadr[0][2][2] = sc1 * ((t3 * vb2z) - (vb1z * r12c1));
+
+ // angle23
+
+ dthetadr[1][1][0] = sc2 * ((t2 * vb2x) + (vb3x * r12c2));
+ dthetadr[1][1][1] = sc2 * ((t2 * vb2y) + (vb3y * r12c2));
+ dthetadr[1][1][2] = sc2 * ((t2 * vb2z) + (vb3z * r12c2));
+
+ dthetadr[1][2][0] = sc2 * ((-t2 * vb2x) - (vb3x * r12c2) +
+ (t4 * vb3x) + (vb2x * r12c2));
+ dthetadr[1][2][1] = sc2 * ((-t2 * vb2y) - (vb3y * r12c2) +
+ (t4 * vb3y) + (vb2y * r12c2));
+ dthetadr[1][2][2] = sc2 * ((-t2 * vb2z) - (vb3z * r12c2) +
+ (t4 * vb3z) + (vb2z * r12c2));
+
+ dthetadr[1][3][0] = -sc2 * ((t4 * vb3x) + (vb2x * r12c2));
+ dthetadr[1][3][1] = -sc2 * ((t4 * vb3y) + (vb2y * r12c2));
+ dthetadr[1][3][2] = -sc2 * ((t4 * vb3z) + (vb2z * r12c2));
+
+ // mid-bond/torsion coupling
+ // energy on bond2 (middle bond)
+
+ cos2phi = cos(2.0*phi);
+ cos3phi = cos(3.0*phi);
+
+ bt1 = mbt_f1[type] * cosphi;
+ bt2 = mbt_f2[type] * cos2phi;
+ bt3 = mbt_f3[type] * cos3phi;
+ sumbte = bt1 + bt2 + bt3;
+ db = r2 - mbt_r0[type];
+ if (EFLAG) edihedral += db * sumbte;
+
+ // force on bond2
+
+ bt1 = -mbt_f1[type] * sinphi;
+ bt2 = -2.0 * mbt_f2[type] * sin(2.0*phi);
+ bt3 = -3.0 * mbt_f3[type] * sin(3.0*phi);
+ sumbtf = bt1 + bt2 + bt3;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[1][i][j];
+
+ // end-bond/torsion coupling
+ // energy on bond1 (first bond)
+
+ bt1 = ebt_f1_1[type] * cosphi;
+ bt2 = ebt_f2_1[type] * cos2phi;
+ bt3 = ebt_f3_1[type] * cos3phi;
+ sumbte = bt1 + bt2 + bt3;
+
+ db = r1 - ebt_r0_1[type];
+ if (EFLAG) edihedral += db * (bt1+bt2+bt3);
+
+ // force on bond1
+
+ bt1 = ebt_f1_1[type] * sinphi;
+ bt2 = 2.0 * ebt_f2_1[type] * sin(2.0*phi);
+ bt3 = 3.0 * ebt_f3_1[type] * sin(3.0*phi);
+ sumbtf = bt1 + bt2 + bt3;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] -= db*sumbtf*dphidr[i][j] + sumbte*dbonddr[0][i][j];
+
+ // end-bond/torsion coupling
+ // energy on bond3 (last bond)
+
+ bt1 = ebt_f1_2[type] * cosphi;
+ bt2 = ebt_f2_2[type] * cos2phi;
+ bt3 = ebt_f3_2[type] * cos3phi;
+ sumbte = bt1 + bt2 + bt3;
+
+ db = r3 - ebt_r0_2[type];
+ if (EFLAG) edihedral += db * (bt1+bt2+bt3);
+
+ // force on bond3
+
+ bt1 = -ebt_f1_2[type] * sinphi;
+ bt2 = -2.0 * ebt_f2_2[type] * sin(2.0*phi);
+ bt3 = -3.0 * ebt_f3_2[type] * sin(3.0*phi);
+ sumbtf = bt1 + bt2 + bt3;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[2][i][j];
+
+ // angle/torsion coupling
+ // energy on angle1
+
+ at1 = at_f1_1[type] * cosphi;
+ at2 = at_f2_1[type] * cos2phi;
+ at3 = at_f3_1[type] * cos3phi;
+ sumbte = at1 + at2 + at3;
+
+ da = acos(costh12) - at_theta0_1[type];
+ if (EFLAG) edihedral += da * (at1+at2+at3);
+
+ // force on angle1
+
+ bt1 = at_f1_1[type] * sinphi;
+ bt2 = 2.0 * at_f2_1[type] * sin(2.0*phi);
+ bt3 = 3.0 * at_f3_1[type] * sin(3.0*phi);
+ sumbtf = bt1 + bt2 + bt3;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] -= da*sumbtf*dphidr[i][j] + sumbte*dthetadr[0][i][j];
+
+ // energy on angle2
+
+ at1 = at_f1_2[type] * cosphi;
+ at2 = at_f2_2[type] * cos2phi;
+ at3 = at_f3_2[type] * cos3phi;
+ sumbte = at1 + at2 + at3;
+
+ da = acos(costh23) - at_theta0_2[type];
+ if (EFLAG) edihedral += da * (at1+at2+at3);
+
+ // force on angle2
+
+ bt1 = -at_f1_2[type] * sinphi;
+ bt2 = -2.0 * at_f2_2[type] * sin(2.0*phi);
+ bt3 = -3.0 * at_f3_2[type] * sin(3.0*phi);
+ sumbtf = bt1 + bt2 + bt3;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] += da*sumbtf*dphidr[i][j] + sumbte*dthetadr[1][i][j];
+
+ // angle/angle/torsion coupling
+
+ da1 = acos(costh12) - aat_theta0_1[type];
+ da2 = acos(costh23) - aat_theta0_2[type];
+
+ if (EFLAG) edihedral += aat_k[type]*da1*da2*cosphi;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] -= aat_k[type] *
+ (cosphi * (da2*dthetadr[0][i][j] - da1*dthetadr[1][i][j]) +
+ sinphi * da1*da2*dphidr[i][j]);
+
+ // bond1/bond3 coupling
+
+ if (fabs(bb13t_k[type]) > SMALL) {
+
+ r1_0 = bb13t_r10[type];
+ r3_0 = bb13t_r30[type];
+ dr1 = r1 - r1_0;
+ dr2 = r3 - r3_0;
+ tk1 = -bb13t_k[type] * dr1 / r3;
+ tk2 = -bb13t_k[type] * dr2 / r1;
+
+ if (EFLAG) edihedral += bb13t_k[type]*dr1*dr2;
+
+ fabcd[0][0] += tk2 * vb1x;
+ fabcd[0][1] += tk2 * vb1y;
+ fabcd[0][2] += tk2 * vb1z;
+
+ fabcd[1][0] -= tk2 * vb1x;
+ fabcd[1][1] -= tk2 * vb1y;
+ fabcd[1][2] -= tk2 * vb1z;
+
+ fabcd[2][0] -= tk1 * vb3x;
+ fabcd[2][1] -= tk1 * vb3y;
+ fabcd[2][2] -= tk1 * vb3z;
+
+ fabcd[3][0] += tk1 * vb3x;
+ fabcd[3][1] += tk1 * vb3y;
+ fabcd[3][2] += tk1 * vb3z;
+ }
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += fabcd[0][0];
+ f[i1][1] += fabcd[0][1];
+ f[i1][2] += fabcd[0][2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += fabcd[1][0];
+ f[i2][1] += fabcd[1][1];
+ f[i2][2] += fabcd[1][2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += fabcd[2][0];
+ f[i3][1] += fabcd[2][1];
+ f[i3][2] += fabcd[2][2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += fabcd[3][0];
+ f[i4][1] += fabcd[3][1];
+ f[i4][2] += fabcd[3][2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,
+ fabcd[0],fabcd[2],fabcd[3],
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
+
diff --git a/src/USER-OMP/dihedral_class2_omp.h b/src/USER-OMP/dihedral_class2_omp.h
new file mode 100644
index 0000000000..d26f2f8713
--- /dev/null
+++ b/src/USER-OMP/dihedral_class2_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(class2/omp,DihedralClass2OMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_CLASS2_OMP_H
+#define LMP_DIHEDRAL_CLASS2_OMP_H
+
+#include "dihedral_class2.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralClass2OMP : public DihedralClass2, public ThrOMP {
+
+ public:
+ DihedralClass2OMP(class LAMMPS *lmp) :
+ DihedralClass2(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
new file mode 100644
index 0000000000..a6c027e92d
--- /dev/null
+++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
@@ -0,0 +1,263 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_cosine_shift_exp_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralCosineShiftExpOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralCosineShiftExpOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
+ double df,fg,hg,fga,hgb,gaa,gbb;
+ double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
+ double c,s,sx2,sy2,sz2;
+ double cccpsss,cssmscc,exp2;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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 = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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;
+
+ double aa=a[type];
+ double uumin=umin[type];
+
+ cccpsss = c*cost[type]+s*sint[type];
+ cssmscc = c*sint[type]-s*cost[type];
+
+ if (doExpansion[type]) {
+ // |a|<0.001 so use expansions relative precision <1e-5
+ if (EFLAG) edihedral = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
+ df=0.5*uumin*( cssmscc + 0.5*aa*cccpsss);
+ } else {
+ exp2=exp(0.5*aa*(1+cccpsss));
+ if (EFLAG) edihedral = opt1[type]*(1-exp2);
+ df= 0.5*opt1[type]*aa* ( exp2*cssmscc );
+ }
+
+ 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;
+
+ sx2 = df*dtgx;
+ sy2 = df*dtgy;
+ sz2 = df*dtgz;
+
+ f1[0] = df*dtfx;
+ f1[1] = df*dtfy;
+ f1[2] = df*dtfz;
+
+ f2[0] = sx2 - f1[0];
+ f2[1] = sy2 - f1[1];
+ f2[2] = sz2 - f1[2];
+
+ f4[0] = df*dthx;
+ f4[1] = df*dthy;
+ f4[2] = df*dthz;
+
+ f3[0] = -sx2 - f4[0];
+ f3[1] = -sy2 - f4[1];
+ f3[2] = -sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
+
diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.h b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h
new file mode 100644
index 0000000000..eb906ab953
--- /dev/null
+++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(cosine/shift/exp/omp,DihedralCosineShiftExpOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H
+#define LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H
+
+#include "dihedral_cosine_shift_exp.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralCosineShiftExpOMP : public DihedralCosineShiftExp, public ThrOMP {
+
+ public:
+ DihedralCosineShiftExpOMP(class LAMMPS *lmp) :
+ DihedralCosineShiftExp(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_harmonic_omp.cpp b/src/USER-OMP/dihedral_harmonic_omp.cpp
new file mode 100644
index 0000000000..0fa24090a7
--- /dev/null
+++ b/src/USER-OMP/dihedral_harmonic_omp.cpp
@@ -0,0 +1,270 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_harmonic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralHarmonicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralHarmonicOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,i,m,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ 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,sx2,sy2,sz2;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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 = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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) edihedral = 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;
+
+ sx2 = df*dtgx;
+ sy2 = df*dtgy;
+ sz2 = df*dtgz;
+
+ f1[0] = df*dtfx;
+ f1[1] = df*dtfy;
+ f1[2] = df*dtfz;
+
+ f2[0] = sx2 - f1[0];
+ f2[1] = sy2 - f1[1];
+ f2[2] = sz2 - f1[2];
+
+ f4[0] = df*dthx;
+ f4[1] = df*dthy;
+ f4[2] = df*dthz;
+
+ f3[0] = -sx2 - f4[0];
+ f3[1] = -sy2 - f4[1];
+ f3[2] = -sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
+
diff --git a/src/USER-OMP/dihedral_harmonic_omp.h b/src/USER-OMP/dihedral_harmonic_omp.h
new file mode 100644
index 0000000000..2d7bae64ee
--- /dev/null
+++ b/src/USER-OMP/dihedral_harmonic_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(harmonic/omp,DihedralHarmonicOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_HARMONIC_OMP_H
+#define LMP_DIHEDRAL_HARMONIC_OMP_H
+
+#include "dihedral_harmonic.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralHarmonicOMP : public DihedralHarmonic, public ThrOMP {
+
+ public:
+ DihedralHarmonicOMP(class LAMMPS *lmp) :
+ DihedralHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp
new file mode 100644
index 0000000000..a3ca969ef3
--- /dev/null
+++ b/src/USER-OMP/dihedral_helix_omp.cpp
@@ -0,0 +1,280 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_helix_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+#define SMALLER 0.00001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralHelixOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralHelixOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
+ double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
+ double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
+ double a33,a12,a13,a23,sx2,sy2,sz2;
+ double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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 = comm->me;
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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;
+
+ pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
+ cphi[type]*sin(phi + 0.25*PI)*siinv;
+
+ if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) +
+ cphi[type]*(1.0 + cos(phi + 0.25*PI));
+;
+
+ 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);
+
+ sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
+ sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
+ sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
+
+ f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
+ f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
+ f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
+
+ f2[0] = -sx2 - f1[0];
+ f2[1] = -sy2 - f1[1];
+ f2[2] = -sz2 - f1[2];
+
+ f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
+ f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
+ f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
+
+ f3[0] = sx2 - f4[0];
+ f3[1] = sy2 - f4[1];
+ f3[2] = sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
diff --git a/src/USER-OMP/dihedral_helix_omp.h b/src/USER-OMP/dihedral_helix_omp.h
new file mode 100644
index 0000000000..7923197413
--- /dev/null
+++ b/src/USER-OMP/dihedral_helix_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(helix/omp,DihedralHelixOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_HELIX_OMP_H
+#define LMP_DIHEDRAL_HELIX_OMP_H
+
+#include "dihedral_helix.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralHelixOMP : public DihedralHelix, public ThrOMP {
+
+ public:
+ DihedralHelixOMP(class LAMMPS *lmp) :
+ DihedralHelix(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
new file mode 100644
index 0000000000..bde958984e
--- /dev/null
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
@@ -0,0 +1,269 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_multi_harmonic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralMultiHarmonicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralMultiHarmonicOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
+ double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
+ double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
+ double a33,a12,a13,a23,sx2,sy2,sz2;
+ double s2,sin2;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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)) {
+ int me = comm->me;
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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 = sum (i=1,5) a_i * c**(i-1)
+ // pd = dp/dc
+
+ pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
+
+ if (EFLAG)
+ edihedral = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
+
+ 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);
+
+ sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
+ sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
+ sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
+
+ f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
+ f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
+ f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
+
+ f2[0] = -sx2 - f1[0];
+ f2[1] = -sy2 - f1[1];
+ f2[2] = -sz2 - f1[2];
+
+ f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
+ f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
+ f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
+
+ f3[0] = sx2 - f4[0];
+ f3[1] = sy2 - f4[1];
+ f3[2] = sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.h b/src/USER-OMP/dihedral_multi_harmonic_omp.h
new file mode 100644
index 0000000000..da2322f038
--- /dev/null
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(multi/harmonic/omp,DihedralMultiHarmonicOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H
+#define LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H
+
+#include "dihedral_multi_harmonic.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralMultiHarmonicOMP : public DihedralMultiHarmonic, public ThrOMP {
+
+ public:
+ DihedralMultiHarmonicOMP(class LAMMPS *lmp) :
+ DihedralMultiHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/dihedral_opls_omp.cpp b/src/USER-OMP/dihedral_opls_omp.cpp
new file mode 100644
index 0000000000..9f59e26d26
--- /dev/null
+++ b/src/USER-OMP/dihedral_opls_omp.cpp
@@ -0,0 +1,286 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "dihedral_opls_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+#define SMALLER 0.00001
+
+/* ---------------------------------------------------------------------- */
+
+void DihedralOPLSOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->ndihedrallist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void DihedralOPLSOMP::eval(double **f, int nfrom, int nto, int tid)
+{
+
+ int i1,i2,i3,i4,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
+ double edihedral,f1[3],f2[3],f3[3],f4[3];
+ double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
+ double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
+ double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
+ double a33,a12,a13,a23,sx2,sy2,sz2;
+ double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
+
+ edihedral = 0.0;
+
+ double **x = atom->x;
+ int **dihedrallist = neighbor->dihedrallist;
+ int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = dihedrallist[n][0];
+ i2 = dihedrallist[n][1];
+ i3 = dihedrallist[n][2];
+ i4 = dihedrallist[n][3];
+ type = dihedrallist[n][4];
+
+ // 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 = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,tid,update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ 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 = 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;
+
+ 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) edihedral = 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));
+
+
+ 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);
+
+ sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
+ sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
+ sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
+
+ f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
+ f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
+ f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
+
+ f2[0] = -sx2 - f1[0];
+ f2[1] = -sy2 - f1[1];
+ f2[2] = -sz2 - f1[2];
+
+ f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
+ f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
+ f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
+
+ f3[0] = sx2 - f4[0];
+ f3[1] = sy2 - f4[1];
+ f3[2] = sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ }
+}
+
diff --git a/src/USER-OMP/dihedral_opls_omp.h b/src/USER-OMP/dihedral_opls_omp.h
new file mode 100644
index 0000000000..58b9920538
--- /dev/null
+++ b/src/USER-OMP/dihedral_opls_omp.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef DIHEDRAL_CLASS
+
+DihedralStyle(opls/omp,DihedralOPLSOMP)
+
+#else
+
+#ifndef LMP_DIHEDRAL_OPLS_OMP_H
+#define LMP_DIHEDRAL_OPLS_OMP_H
+
+#include "dihedral_opls.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class DihedralOPLSOMP : public DihedralOPLS, public ThrOMP {
+
+ public:
+ DihedralOPLSOMP(class LAMMPS *lmp) :
+ DihedralOPLS(lmp), ThrOMP(lmp,DIHEDRAL) {};
+
+ virtual void compute(int, int);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_gravity_omp.cpp b/src/USER-OMP/fix_gravity_omp.cpp
new file mode 100644
index 0000000000..c4f4b39b6c
--- /dev/null
+++ b/src/USER-OMP/fix_gravity_omp.cpp
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "fix_gravity_omp.h"
+#include "atom.h"
+#include "update.h"
+#include "domain.h"
+#include "respa.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+enum{CHUTE,SPHERICAL,GRADIENT,VECTOR};
+
+/* ---------------------------------------------------------------------- */
+
+FixGravityOMP::FixGravityOMP(LAMMPS *lmp, int narg, char **arg) :
+ FixGravity(lmp, narg, arg) { }
+
+/* ---------------------------------------------------------------------- */
+
+void FixGravityOMP::post_force(int vflag)
+{
+ // update direction of gravity vector if gradient style
+
+ if (style == GRADIENT) {
+ if (domain->dimension == 3) {
+ double phi_current = degree2rad *
+ (phi + (update->ntimestep - time_origin)*dt*phigrad*360.0);
+ double theta_current = degree2rad *
+ (theta + (update->ntimestep - time_origin)*dt*thetagrad*360.0);
+ xgrav = sin(theta_current) * cos(phi_current);
+ ygrav = sin(theta_current) * sin(phi_current);
+ zgrav = cos(theta_current);
+ } else {
+ double theta_current = degree2rad *
+ (theta + (update->ntimestep - time_origin)*dt*thetagrad*360.0);
+ xgrav = sin(theta_current);
+ ygrav = cos(theta_current);
+ }
+ xacc = magnitude*xgrav;
+ yacc = magnitude*ygrav;
+ zacc = magnitude*zgrav;
+ }
+
+ const double * const * const x = atom->x;
+ double * const * const f = atom->f;
+ double * const rmass = atom->rmass;
+ double * const mass = atom->mass;
+ int * const mask = atom->mask;
+ int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double xacc_thr = xacc;
+ const double yacc_thr = yacc;
+ const double zacc_thr = zacc;
+ double massone;
+
+ int i;
+ eflag = 0;
+ double grav = 0.0;
+
+ if (rmass) {
+#if defined(_OPENMP)
+#pragma omp parallel for private(i,massone) default(none) reduction(-:grav)
+#endif
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ massone = rmass[i];
+ f[i][0] += massone*xacc_thr;
+ f[i][1] += massone*yacc_thr;
+ f[i][2] += massone*zacc_thr;
+ grav -= massone * (xacc_thr*x[i][0] + yacc_thr*x[i][1] + zacc_thr*x[i][2]);
+ }
+ } else {
+#if defined(_OPENMP)
+#pragma omp parallel for private(i,massone) default(none) reduction(-:grav)
+#endif
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ massone = mass[type[i]];
+ f[i][0] += massone*xacc_thr;
+ f[i][1] += massone*yacc_thr;
+ f[i][2] += massone*zacc_thr;
+ grav -= massone * (xacc_thr*x[i][0] + yacc_thr*x[i][1] + zacc_thr*x[i][2]);
+ }
+ }
+ egrav = grav;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixGravityOMP::post_force_respa(int vflag, int ilevel, int iloop)
+{
+ if (ilevel == nlevels_respa-1) post_force(vflag);
+}
+
diff --git a/src/USER-OMP/fix_gravity_omp.h b/src/USER-OMP/fix_gravity_omp.h
new file mode 100644
index 0000000000..dd0144410e
--- /dev/null
+++ b/src/USER-OMP/fix_gravity_omp.h
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(gravity/omp,FixGravityOMP)
+
+#else
+
+#ifndef LMP_FIX_GRAVITY_OMP_H
+#define LMP_FIX_GRAVITY_OMP_H
+
+#include "fix_gravity.h"
+
+namespace LAMMPS_NS {
+
+class FixGravityOMP : public FixGravity {
+
+ public:
+ FixGravityOMP(class LAMMPS *, int, char **);
+ virtual void post_force(int);
+ virtual void post_force_respa(int, int, int);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_nve_sphere_omp.cpp b/src/USER-OMP/fix_nve_sphere_omp.cpp
new file mode 100644
index 0000000000..a642b21f22
--- /dev/null
+++ b/src/USER-OMP/fix_nve_sphere_omp.cpp
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "string.h"
+#include "fix_nve_sphere_omp.h"
+#include "atom.h"
+#include "atom_vec.h"
+#include "update.h"
+#include "respa.h"
+#include "force.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define INERTIA 0.4 // moment of inertia prefactor for sphere
+
+enum{NONE,DIPOLE};
+
+/* ---------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVESphereOMP::initial_integrate(int vflag)
+{
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **omega = atom->omega;
+ double **torque = atom->torque;
+ double *radius = atom->radius;
+ double *rmass = atom->rmass;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ int i;
+
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // set timestep here since dt may have changed or come via rRESPA
+ const double dtfrotate = dtf / INERTIA;
+
+ // update v,x,omega for all particles
+ // d_omega/dt = torque / inertia
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(shared)
+#endif
+ for (i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) {
+ const double dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+ v[i][2] += dtfm * f[i][2];
+ x[i][0] += dtv * v[i][0];
+ x[i][1] += dtv * v[i][1];
+ x[i][2] += dtv * v[i][2];
+
+ const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]);
+ omega[i][0] += dtirotate * torque[i][0];
+ omega[i][1] += dtirotate * torque[i][1];
+ omega[i][2] += dtirotate * torque[i][2];
+ }
+ }
+
+ // update mu for dipoles
+ // d_mu/dt = omega cross mu
+ // renormalize mu to dipole length
+
+ if (extra == DIPOLE) {
+ double **mu = atom->mu;
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(shared)
+#endif
+ for (i = 0; i < nlocal; i++) {
+ double g0,g1,g2,msq,scale;
+ if (mask[i] & groupbit) {
+ if (mu[i][3] > 0.0) {
+ g0 = mu[i][0] + dtv * (omega[i][1]*mu[i][2]-omega[i][2]*mu[i][1]);
+ g1 = mu[i][1] + dtv * (omega[i][2]*mu[i][0]-omega[i][0]*mu[i][2]);
+ g2 = mu[i][2] + dtv * (omega[i][0]*mu[i][1]-omega[i][1]*mu[i][0]);
+ msq = g0*g0 + g1*g1 + g2*g2;
+ scale = mu[i][3]/sqrt(msq);
+ mu[i][0] = g0*scale;
+ mu[i][1] = g1*scale;
+ mu[i][2] = g2*scale;
+ }
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVESphereOMP::final_integrate()
+{
+ double **v = atom->v;
+ double **f = atom->f;
+ double **omega = atom->omega;
+ double **torque = atom->torque;
+ double *rmass = atom->rmass;
+ double *radius = atom->radius;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ int i;
+
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // set timestep here since dt may have changed or come via rRESPA
+
+ const double dtfrotate = dtf / INERTIA;
+
+ // update v,omega for all particles
+ // d_omega/dt = torque / inertia
+
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(shared)
+#endif
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ const double dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+ v[i][2] += dtfm * f[i][2];
+
+ const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]);
+ omega[i][0] += dtirotate * torque[i][0];
+ omega[i][1] += dtirotate * torque[i][1];
+ omega[i][2] += dtirotate * torque[i][2];
+ }
+}
diff --git a/src/USER-OMP/fix_nve_sphere_omp.h b/src/USER-OMP/fix_nve_sphere_omp.h
new file mode 100644
index 0000000000..fe86039b18
--- /dev/null
+++ b/src/USER-OMP/fix_nve_sphere_omp.h
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(nve/sphere/omp,FixNVESphereOMP)
+
+#else
+
+#ifndef LMP_FIX_NVE_SPHERE_OMP_H
+#define LMP_FIX_NVE_SPHERE_OMP_H
+
+#include "fix_nve_sphere.h"
+
+namespace LAMMPS_NS {
+
+class FixNVESphereOMP : public FixNVESphere {
+ public:
+ FixNVESphereOMP(class LAMMPS *lmp, int narg, char **arg) :
+ FixNVESphere(lmp, narg, arg) {};
+
+ virtual void initial_integrate(int);
+ virtual void final_integrate();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_qeq_comb_omp.cpp b/src/USER-OMP/fix_qeq_comb_omp.cpp
new file mode 100644
index 0000000000..175bab8986
--- /dev/null
+++ b/src/USER-OMP/fix_qeq_comb_omp.cpp
@@ -0,0 +1,166 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include
+#include "fix_qeq_comb_omp.h"
+#include "atom.h"
+#include "force.h"
+#include "group.h"
+#include "memory.h"
+#include "error.h"
+#include "respa.h"
+#include "update.h"
+#include "pair_comb_omp.h"
+
+#include
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+FixQEQCombOMP::FixQEQCombOMP(LAMMPS *lmp, int narg, char **arg)
+ : FixQEQComb(lmp, narg, arg)
+{
+ if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb/omp command");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixQEQCombOMP::init()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Fix qeq/comb/omp requires atom attribute q");
+
+ comb = (PairComb *) force->pair_match("comb/omp",1);
+ if (comb == NULL)
+ comb = (PairComb *) force->pair_match("comb",1);
+ if (comb == NULL) error->all(FLERR,"Must use pair_style comb or comb/omp with fix qeq/comb");
+
+ if (strstr(update->integrate_style,"respa"))
+ nlevels_respa = ((Respa *) update->integrate)->nlevels;
+
+ ngroup = group->count(igroup);
+ if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixQEQCombOMP::post_force(int vflag)
+{
+ int i,iloop,loopmax;
+ double heatpq,qmass,dtq,dtq2;
+ double enegchkall,enegmaxall;
+
+ if (update->ntimestep % nevery) return;
+
+ // reallocate work arrays if necessary
+ // qf = charge force
+ // q1 = charge displacement
+ // q2 = tmp storage of charge force for next iteration
+
+ if (atom->nmax > nmax) {
+ memory->destroy(qf);
+ memory->destroy(q1);
+ memory->destroy(q2);
+ nmax = atom->nmax;
+ memory->create(qf,nmax,"qeq:qf");
+ memory->create(q1,nmax,"qeq:q1");
+ memory->create(q2,nmax,"qeq:q2");
+ vector_atom = qf;
+ }
+
+ // more loops for first-time charge equilibrium
+
+ iloop = 0;
+ if (firstflag) loopmax = 5000;
+ else loopmax = 2000;
+
+ // charge-equilibration loop
+
+ if (me == 0 && fp)
+ fprintf(fp,"Charge equilibration on step " BIGINT_FORMAT "\n",
+ update->ntimestep);
+
+ heatpq = 0.05;
+ qmass = 0.000548580;
+ dtq = 0.0006;
+ dtq2 = 0.5*dtq*dtq/qmass;
+
+ double enegchk = 0.0;
+ double enegtot = 0.0;
+ double enegmax = 0.0;
+
+ double *q = atom->q;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (i = 0; i < nlocal; i++)
+ q1[i] = q2[i] = qf[i] = 0.0;
+
+ for (iloop = 0; iloop < loopmax; iloop ++ ) {
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ q1[i] += qf[i]*dtq2 - heatpq*q1[i];
+ q[i] += q1[i];
+ }
+
+ enegtot = comb->yasu_char(qf,igroup);
+ enegtot /= ngroup;
+ enegchk = enegmax = 0.0;
+
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(shared)
+#endif
+ for (i = 0; i < nlocal ; i++)
+ if (mask[i] & groupbit) {
+ q2[i] = enegtot-qf[i];
+ enegmax = MAX(enegmax,fabs(q2[i]));
+ enegchk += fabs(q2[i]);
+ qf[i] = q2[i];
+ }
+
+ MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world);
+ enegchk = enegchkall/ngroup;
+ MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world);
+ enegmax = enegmaxall;
+
+ if (enegchk <= precision && enegmax <= 100.0*precision) break;
+
+ if (me == 0 && fp)
+ fprintf(fp," iteration: %d, enegtot %.6g, "
+ "enegmax %.6g, fq deviation: %.6g\n",
+ iloop,enegtot,enegmax,enegchk);
+
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(shared)
+#endif
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit)
+ q1[i] += qf[i]*dtq2 - heatpq*q1[i];
+ }
+
+ if (me == 0 && fp) {
+ if (iloop == loopmax)
+ fprintf(fp,"Charges did not converge in %d iterations\n",iloop);
+ else
+ fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n",
+ iloop,enegchk);
+ }
+}
+
diff --git a/src/USER-OMP/fix_qeq_comb_omp.h b/src/USER-OMP/fix_qeq_comb_omp.h
new file mode 100644
index 0000000000..0febe6b0aa
--- /dev/null
+++ b/src/USER-OMP/fix_qeq_comb_omp.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(qeq/comb/omp,FixQEQCombOMP)
+
+#else
+
+#ifndef LMP_FIX_QEQ_COMB_OMP_H
+#define LMP_FIX_QEQ_COMB_OMP_H
+
+#include "fix_qeq_comb.h"
+
+namespace LAMMPS_NS {
+
+class FixQEQCombOMP : public FixQEQComb {
+ public:
+ FixQEQCombOMP(class LAMMPS *, int, char **);
+ virtual void init();
+ virtual void post_force(int);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_shear_history_omp.cpp b/src/USER-OMP/fix_shear_history_omp.cpp
new file mode 100644
index 0000000000..40781cb407
--- /dev/null
+++ b/src/USER-OMP/fix_shear_history_omp.cpp
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "string.h"
+#include "stdio.h"
+#include "fix_shear_history_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "force.h"
+#include "pair.h"
+#include "update.h"
+#include "modify.h"
+#include "error.h"
+
+#if defined(_OPENMP)
+#include
+#endif
+
+using namespace LAMMPS_NS;
+
+#define MAXTOUCH 15
+
+/* ----------------------------------------------------------------------
+ copy shear partner info from neighbor lists to atom arrays
+ so can be exchanged with atoms
+------------------------------------------------------------------------- */
+
+void FixShearHistoryOMP::pre_exchange()
+{
+
+ const int nlocal = atom->nlocal;
+ const int nghost = atom->nghost;
+ const int nall = nlocal + nghost;
+ const int nthreads = comm->nthreads;
+
+ int flag = 0;
+#if defined(_OPENMP)
+#pragma omp parallel shared(flag)
+#endif
+ {
+
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ // each thread works on a fixed chunk of local and ghost atoms.
+ const int ldelta = 1 + nlocal/nthreads;
+ const int lfrom = tid*ldelta;
+ const int lmax = lfrom +ldelta;
+ const int lto = (lmax > nlocal) ? nlocal : lmax;
+
+ const int gdelta = 1 + nghost/nthreads;
+ const int gfrom = nlocal + tid*gdelta;
+ const int gmax = gfrom + gdelta;
+ const int gto = (gmax > nall) ? nall : gmax;
+
+
+ int i,j,ii,jj,m,inum,jnum;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int *touch,**firsttouch;
+ double *shear,*allshear,**firstshear;
+
+ // zero npartners for all current atoms
+
+ for (i = lfrom; i < lto; i++) npartner[i] = 0;
+
+ // copy shear info from neighbor list atoms to atom arrays
+
+ int *tag = atom->tag;
+
+ NeighList *list = pair->list;
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ firsttouch = list->listgranhistory->firstneigh;
+ firstshear = list->listgranhistory->firstdouble;
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ jlist = firstneigh[i];
+ allshear = firstshear[i];
+ jnum = numneigh[i];
+ touch = firsttouch[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ if (touch[jj]) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ shear = &allshear[3*jj];
+
+ if ((i >= lfrom) && (i < lto)) {
+ if (npartner[i] < MAXTOUCH) {
+ m = npartner[i];
+ partner[i][m] = tag[j];
+ shearpartner[i][m][0] = shear[0];
+ shearpartner[i][m][1] = shear[1];
+ shearpartner[i][m][2] = shear[2];
+ }
+ npartner[i]++;
+ }
+
+ if ((j >= lfrom) && (j < lto)) {
+ if (npartner[j] < MAXTOUCH) {
+ m = npartner[j];
+ partner[j][m] = tag[i];
+ shearpartner[j][m][0] = -shear[0];
+ shearpartner[j][m][1] = -shear[1];
+ shearpartner[j][m][2] = -shear[2];
+ }
+ npartner[j]++;
+ }
+
+ if ((j >= gfrom) && (j < gto)) {
+ npartner[j]++;
+ }
+ }
+ }
+ }
+
+ // test for too many touching neighbors
+ int myflag = 0;
+ for (i = lfrom; i < lto; i++)
+ if (npartner[i] >= MAXTOUCH) myflag = 1;
+
+ if (myflag)
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ ++flag;
+ }
+
+ int flag_all;
+ MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
+ if (flag_all) error->all(FLERR,"Too many touching neighbors - boost MAXTOUCH");
+}
diff --git a/src/USER-OMP/fix_shear_history_omp.h b/src/USER-OMP/fix_shear_history_omp.h
new file mode 100644
index 0000000000..9a360b7923
--- /dev/null
+++ b/src/USER-OMP/fix_shear_history_omp.h
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(SHEAR_HISTORY/omp,FixShearHistoryOMP)
+
+#else
+
+#ifndef LMP_FIX_SHEAR_HISTORY_OMP_H
+#define LMP_FIX_SHEAR_HISTORY_OMP_H
+
+#include "fix_shear_history.h"
+
+namespace LAMMPS_NS {
+
+class FixShearHistoryOMP : public FixShearHistory {
+
+ public:
+ FixShearHistoryOMP(class LAMMPS *lmp, int narg, char **argv)
+ : FixShearHistory(lmp,narg,argv) {};
+ virtual void pre_exchange();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_adp_omp.cpp b/src/USER-OMP/pair_adp_omp.cpp
new file mode 100644
index 0000000000..e91642e6ba
--- /dev/null
+++ b/src/USER-OMP/pair_adp_omp.cpp
@@ -0,0 +1,404 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "string.h"
+
+#include "pair_adp_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairADPOMP::PairADPOMP(LAMMPS *lmp) :
+ PairADP(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairADPOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow energy and fp arrays if necessary
+ // need to be atom->nmax in length
+
+ if (atom->nmax > nmax) {
+ memory->destroy(rho);
+ memory->destroy(fp);
+ memory->destroy(mu);
+ memory->destroy(lambda);
+ nmax = atom->nmax;
+ memory->create(rho,nthreads*nmax,"pair:rho");
+ memory->create(fp,nmax,"pair:fp");
+ memory->create(mu,nthreads*nmax,3,"pair:mu");
+ memory->create(lambda,nthreads*nmax,6,"pair:lambda");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, *rho_t, **mu_t, **lambda_t;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ if (force->newton_pair) {
+ rho_t = rho + tid*nall;
+ mu_t = mu + tid*nall;
+ lambda_t = lambda + tid*nall;
+ } else {
+ rho_t = rho + tid*atom->nlocal;
+ mu_t = mu + tid*atom->nlocal;
+ lambda_t = lambda + tid*atom->nlocal;
+ }
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ else eval<1,1,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ else eval<1,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ else eval<0,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairADPOMP::eval(double **f, double *rho_t, double **mu_t,
+ double **lambda_t, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,m,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi;
+ double u2,u2p,w2,w2p,nu;
+ double *coeff;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double delmux,delmuy,delmuz,trdelmu,tradellam;
+ double adpx,adpy,adpz,fx,fy,fz;
+ double sumlamxx,sumlamyy,sumlamzz,sumlamyz,sumlamxz,sumlamxy;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // zero out density
+
+ if (NEWTON_PAIR) {
+ memset(rho_t, 0, nall*sizeof(double));
+ memset(&(mu_t[0][0]), 0, 3*nall*sizeof(double));
+ memset(&(lambda_t[0][0]), 0, 6*nall*sizeof(double));
+ } else {
+ memset(rho_t, 0, nlocal*sizeof(double));
+ memset(&(mu_t[0][0]), 0, 3*nlocal*sizeof(double));
+ memset(&(lambda_t[0][0]), 0, 6*nlocal*sizeof(double));
+ }
+
+ // rho = density at each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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);
+ coeff = rhor_spline[type2rhor[jtype][itype]][m];
+ rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coeff = u2r_spline[type2u2r[jtype][itype]][m];
+ u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ mu_t[i][0] += u2*delx;
+ mu_t[i][1] += u2*dely;
+ mu_t[i][2] += u2*delz;
+ coeff = w2r_spline[type2w2r[jtype][itype]][m];
+ w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ lambda_t[i][0] += w2*delx*delx;
+ lambda_t[i][1] += w2*dely*dely;
+ lambda_t[i][2] += w2*delz*delz;
+ lambda_t[i][3] += w2*dely*delz;
+ lambda_t[i][4] += w2*delx*delz;
+ lambda_t[i][5] += w2*delx*dely;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ // verify sign difference for mu and lambda
+ coeff = rhor_spline[type2rhor[itype][jtype]][m];
+ rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coeff = u2r_spline[type2u2r[itype][jtype]][m];
+ u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ mu_t[j][0] -= u2*delx;
+ mu_t[j][1] -= u2*dely;
+ mu_t[j][2] -= u2*delz;
+ coeff = w2r_spline[type2w2r[itype][jtype]][m];
+ w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ lambda_t[j][0] += w2*delx*delx;
+ lambda_t[j][1] += w2*dely*dely;
+ lambda_t[j][2] += w2*delz*delz;
+ lambda_t[j][3] += w2*dely*delz;
+ lambda_t[j][4] += w2*delx*delz;
+ lambda_t[j][5] += w2*delx*dely;
+ }
+ }
+ }
+ }
+
+ // wait until all threads are done with computation
+ sync_threads();
+
+ // communicate and sum densities
+
+ if (NEWTON_PAIR) {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(&(mu[0][0]), nall, comm->nthreads, 3, tid);
+ data_reduce_thr(&(lambda[0][0]), nall, comm->nthreads, 6, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { comm->reverse_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ } else {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(&(mu[0][0]), nlocal, comm->nthreads, 3, tid);
+ data_reduce_thr(&(lambda[0][0]), nlocal, comm->nthreads, 6, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+ // fp = derivative of embedding energy at each atom
+ // phi = embedding energy at each atom
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ p = rho[i]*rdrho + 1.0;
+ m = static_cast (p);
+ m = MAX(1,MIN(m,nrho-1));
+ p -= m;
+ p = MIN(p,1.0);
+ coeff = frho_spline[type2frho[type[i]]][m];
+ fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
+ if (EFLAG) {
+ phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ phi += 0.5*(mu[i][0]*mu[i][0]+mu[i][1]*mu[i][1]+mu[i][2]*mu[i][2]);
+ phi += 0.5*(lambda[i][0]*lambda[i][0]+lambda[i][1]*
+ lambda[i][1]+lambda[i][2]*lambda[i][2]);
+ phi += 1.0*(lambda[i][3]*lambda[i][3]+lambda[i][4]*
+ lambda[i][4]+lambda[i][5]*lambda[i][5]);
+ phi -= 1.0/6.0*(lambda[i][0]+lambda[i][1]+lambda[i][2])*
+ (lambda[i][0]+lambda[i][1]+lambda[i][2]);
+ if (eflag_global) eng_vdwl_thr[tid] += phi;
+ if (eflag_atom) eatom_thr[tid][i] += phi;
+ }
+ }
+
+ // wait until all theads are done with computation
+ sync_threads();
+
+ // communicate derivative of embedding function
+ // MPI communication only on master thread
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { comm->forward_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ // compute forces on each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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
+ // u2 = u
+ // u2p = u'
+ // w2 = w
+ // w2p = w'
+ // 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
+
+ coeff = rhor_spline[type2rhor[itype][jtype]][m];
+ rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = rhor_spline[type2rhor[jtype][itype]][m];
+ rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = z2r_spline[type2z2r[itype][jtype]][m];
+ z2p = (coeff[0]*p + coeff[1])*p + coeff[2];
+ z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coeff = u2r_spline[type2u2r[itype][jtype]][m];
+ u2p = (coeff[0]*p + coeff[1])*p + coeff[2];
+ u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coeff = w2r_spline[type2w2r[itype][jtype]][m];
+ w2p = (coeff[0]*p + coeff[1])*p + coeff[2];
+ w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+
+ recip = 1.0/r;
+ phi = z2*recip;
+ phip = z2p*recip - phi*recip;
+ psip = fp[i]*rhojp + fp[j]*rhoip + phip;
+ fpair = -psip*recip;
+
+ delmux = mu[i][0]-mu[j][0];
+ delmuy = mu[i][1]-mu[j][1];
+ delmuz = mu[i][2]-mu[j][2];
+ trdelmu = delmux*delx+delmuy*dely+delmuz*delz;
+ sumlamxx = lambda[i][0]+lambda[j][0];
+ sumlamyy = lambda[i][1]+lambda[j][1];
+ sumlamzz = lambda[i][2]+lambda[j][2];
+ sumlamyz = lambda[i][3]+lambda[j][3];
+ sumlamxz = lambda[i][4]+lambda[j][4];
+ sumlamxy = lambda[i][5]+lambda[j][5];
+ tradellam = sumlamxx*delx*delx+sumlamyy*dely*dely+
+ sumlamzz*delz*delz+2.0*sumlamxy*delx*dely+
+ 2.0*sumlamxz*delx*delz+2.0*sumlamyz*dely*delz;
+ nu = sumlamxx+sumlamyy+sumlamzz;
+
+ adpx = delmux*u2 + trdelmu*u2p*delx*recip +
+ 2.0*w2*(sumlamxx*delx+sumlamxy*dely+sumlamxz*delz) +
+ w2p*delx*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delx;
+ adpy = delmuy*u2 + trdelmu*u2p*dely*recip +
+ 2.0*w2*(sumlamxy*delx+sumlamyy*dely+sumlamyz*delz) +
+ w2p*dely*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*dely;
+ adpz = delmuz*u2 + trdelmu*u2p*delz*recip +
+ 2.0*w2*(sumlamxz*delx+sumlamyz*dely+sumlamzz*delz) +
+ w2p*delz*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delz;
+ adpx*=-1.0; adpy*=-1.0; adpz*=-1.0;
+
+ fx = delx*fpair+adpx;
+ fy = dely*fpair+adpy;
+ fz = delz*fpair+adpz;
+
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ }
+
+ if (EFLAG) evdwl = phi;
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
+ fx,fy,fz,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairADPOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairADP::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_adp_omp.h b/src/USER-OMP/pair_adp_omp.h
new file mode 100644
index 0000000000..f7d2509cd3
--- /dev/null
+++ b/src/USER-OMP/pair_adp_omp.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(adp/omp,PairADPOMP)
+
+#else
+
+#ifndef LMP_PAIR_ADP_OMP_H
+#define LMP_PAIR_ADP_OMP_H
+
+#include "pair_adp.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairADPOMP : public PairADP, public ThrOMP {
+
+ public:
+ PairADPOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double *rho_t, double **mu_t, double **lambda_t,
+ int iifrom, int iito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_born_coul_long_omp.cpp b/src/USER-OMP/pair_born_coul_long_omp.cpp
new file mode 100644
index 0000000000..c277a080c0
--- /dev/null
+++ b/src/USER-OMP/pair_born_coul_long_omp.cpp
@@ -0,0 +1,199 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_born_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairBornCoulLongOMP::PairBornCoulLongOMP(LAMMPS *lmp) :
+ PairBornCoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBornCoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairBornCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,r,rexp,forcecoul,forceborn,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r = sqrt(rsq);
+
+ if (rsq < cut_coulsq) {
+ 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;
+ rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
+ forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ + born3[itype][jtype]*r2inv*r6inv;
+ } else forceborn = 0.0;
+
+ fpair = (forcecoul + factor_lj*forceborn)*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = prefactor*erfc;
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv
+ + d[itype][jtype]*r6inv*r2inv - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+ } else evdwl = 0.0;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBornCoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBornCoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_born_coul_long_omp.h b/src/USER-OMP/pair_born_coul_long_omp.h
new file mode 100644
index 0000000000..d6ccbfc680
--- /dev/null
+++ b/src/USER-OMP/pair_born_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(born/coul/long/omp,PairBornCoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_BORN_COUL_LONG_OMP_H
+#define LMP_PAIR_BORN_COUL_LONG_OMP_H
+
+#include "pair_born_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBornCoulLongOMP : public PairBornCoulLong, public ThrOMP {
+
+ public:
+ PairBornCoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_born_omp.cpp b/src/USER-OMP/pair_born_omp.cpp
new file mode 100644
index 0000000000..c39d205c97
--- /dev/null
+++ b/src/USER-OMP/pair_born_omp.cpp
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_born_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairBornOMP::PairBornOMP(LAMMPS *lmp) :
+ PairBorn(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBornOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairBornOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,r,rexp,forceborn,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ r = sqrt(rsq);
+ rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
+ forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ + born3[itype][jtype]*r2inv*r6inv;
+ fpair = factor_lj*forceborn*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv
+ + d[itype][jtype]*r6inv*r2inv - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBornOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBorn::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_born_omp.h
new file mode 100644
index 0000000000..b24de4a577
--- /dev/null
+++ b/src/USER-OMP/pair_born_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(born/omp,PairBornOMP)
+
+#else
+
+#ifndef LMP_PAIR_BORN_OMP_H
+#define LMP_PAIR_BORN_OMP_H
+
+#include "pair_born.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBornOMP : public PairBorn, public ThrOMP {
+
+ public:
+ PairBornOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.cpp b/src/USER-OMP/pair_buck_coul_cut_omp.cpp
new file mode 100644
index 0000000000..ac47d478a0
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_cut_omp.cpp
@@ -0,0 +1,182 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_buck_coul_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairBuckCoulCutOMP::PairBuckCoulCutOMP(LAMMPS *lmp) :
+ PairBuckCoulCut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBuckCoulCutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairBuckCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r = sqrt(rsq);
+
+ if (rsq < cut_coulsq[itype][jtype])
+ forcecoul = qqrd2e * qtmp*q[j]/r;
+ else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ rexp = exp(-r*rhoinv[itype][jtype]);
+ forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
+ } else forcebuck = 0.0;
+
+ fpair = (forcecoul + factor_lj*forcebuck)*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype])
+ ecoul = factor_coul * qqrd2e * qtmp*q[j]/r;
+ else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+ } else evdwl = 0.0;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBuckCoulCutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBuckCoulCut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.h b/src/USER-OMP/pair_buck_coul_cut_omp.h
new file mode 100644
index 0000000000..a77f3bad24
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(buck/coul/cut/omp,PairBuckCoulCutOMP)
+
+#else
+
+#ifndef LMP_PAIR_BUCK_COUL_CUT_OMP_H
+#define LMP_PAIR_BUCK_COUL_CUT_OMP_H
+
+#include "pair_buck_coul_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBuckCoulCutOMP : public PairBuckCoulCut, public ThrOMP {
+
+ public:
+ PairBuckCoulCutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.cpp b/src/USER-OMP/pair_buck_coul_long_omp.cpp
new file mode 100644
index 0000000000..6e7398ca44
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_long_omp.cpp
@@ -0,0 +1,198 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_buck_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairBuckCoulLongOMP::PairBuckCoulLongOMP(LAMMPS *lmp) :
+ PairBuckCoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBuckCoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairBuckCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r = sqrt(rsq);
+
+ if (rsq < cut_coulsq) {
+ 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;
+ rexp = exp(-r*rhoinv[itype][jtype]);
+ forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
+ } else forcebuck = 0.0;
+
+ fpair = (forcecoul + factor_lj*forcebuck)*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = prefactor*erfc;
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+ } else evdwl = 0.0;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBuckCoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBuckCoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/pair_buck_coul_long_omp.h
new file mode 100644
index 0000000000..2c87904de8
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+
+#include "pair_buck_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
+
+ public:
+ PairBuckCoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_buck_coul_omp.cpp b/src/USER-OMP/pair_buck_coul_omp.cpp
new file mode 100644
index 0000000000..bd171f628a
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_omp.cpp
@@ -0,0 +1,230 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_buck_coul_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "math_vector.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairBuckCoulOMP::PairBuckCoulOMP(LAMMPS *lmp) :
+ PairBuckCoul(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBuckCoulOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairBuckCoulOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ double evdwl,ecoul,fpair;
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+
+ double *x0 = x[0];
+ double *f0 = f[0], *fi = f0;
+
+ int *ilist = list->ilist;
+
+ // loop over neighbors of my atoms
+
+ int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
+ int *jneigh, *jneighn, typei, typej, ni;
+ double qi, qri, *cutsqi, *cut_bucksqi,
+ *buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti;
+ double r, rsq, r2inv, force_coul, force_buck;
+ double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
+ vector xi, d;
+
+ for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms
+ i = ilist[ii]; fi = f0+3*i;
+ if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants
+ offseti = offset[typei = type[i]];
+ buck1i = buck1[typei]; buck2i = buck2[typei];
+ buckai = buck_a[typei]; buckci = buck_c[typei], rhoinvi = rhoinv[typei];
+ cutsqi = cutsq[typei]; cut_bucksqi = cut_bucksq[typei];
+ memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
+ jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
+
+ for (; jneigh= cutsqi[typej = type[j]]) continue;
+ r2inv = 1.0/rsq;
+ r = sqrt(rsq);
+
+ if (order1 && (rsq < cut_coulsq)) { // coulombic
+ if (!ncoultablebits || rsq <= tabinnersq) { // series real space
+ register double x = g_ewald*r;
+ register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x);
+ if (ni == 0) {
+ s *= g_ewald*exp(-x*x);
+ force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
+ if (EFLAG) ecoul = t;
+ } else { // special case
+ register double f = s*(1.0-special_coul[ni])/r;
+ s *= g_ewald*exp(-x*x);
+ force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-f;
+ if (EFLAG) ecoul = t-f;
+ } // table real space
+ } else {
+ register union_int_float_t t;
+ t.f = rsq;
+ register const int k = (t.i & ncoulmask) >> ncoulshiftbits;
+ register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
+ if (ni == 0) {
+ force_coul = qiqj*(ftable[k]+f*dftable[k]);
+ if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]);
+ }
+ else { // special case
+ t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
+ force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f);
+ if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f);
+ }
+ }
+ } else force_coul = ecoul = 0.0;
+
+ if (rsq < cut_bucksqi[typej]) { // buckingham
+ register double rn = r2inv*r2inv*r2inv,
+ expr = exp(-r*rhoinvi[typej]);
+ if (order6) { // long-range
+ register double x2 = g2*rsq, a2 = 1.0/x2;
+ x2 = a2*exp(-x2)*buckci[typej];
+ if (ni == 0) {
+ force_buck =
+ r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
+ if (EFLAG) evdwl = expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2;
+ } else { // special case
+ register double f = special_lj[ni], t = rn*(1.0-f);
+ force_buck = f*r*expr*buck1i[typej]-
+ g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej];
+ if (EFLAG) evdwl = f*expr*buckai[typej] -
+ g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej];
+ }
+ } else { // cut
+ if (ni == 0) {
+ force_buck = r*expr*buck1i[typej]-rn*buck2i[typej];
+ if (EFLAG) evdwl = expr*buckai[typej] -
+ rn*buckci[typej]-offseti[typej];
+ } else { // special case
+ register double f = special_lj[ni];
+ force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]);
+ if (EFLAG)
+ evdwl = f*(expr*buckai[typej]-rn*buckci[typej]-offseti[typej]);
+ }
+ }
+ } else force_buck = evdwl = 0.0;
+
+ fpair = (force_coul+force_buck)*r2inv;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ register double *fj = f0+(j+(j<<1)), f;
+ fi[0] += f = d[0]*fpair; fj[0] -= f;
+ fi[1] += f = d[1]*fpair; fj[1] -= f;
+ fi[2] += f = d[2]*fpair; fj[2] -= f;
+ } else {
+ fi[0] += d[0]*fpair;
+ fi[1] += d[1]*fpair;
+ fi[2] += d[2]*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,d[0],d[1],d[2],tid);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBuckCoulOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBuckCoul::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_buck_coul_omp.h b/src/USER-OMP/pair_buck_coul_omp.h
new file mode 100644
index 0000000000..dbff9b419a
--- /dev/null
+++ b/src/USER-OMP/pair_buck_coul_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(buck/coul/omp,PairBuckCoulOMP)
+
+#else
+
+#ifndef LMP_PAIR_BUCK_COUL_OMP_H
+#define LMP_PAIR_BUCK_COUL_OMP_H
+
+#include "pair_buck_coul.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBuckCoulOMP : public PairBuckCoul, public ThrOMP {
+
+ public:
+ PairBuckCoulOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_buck_omp.cpp b/src/USER-OMP/pair_buck_omp.cpp
new file mode 100644
index 0000000000..66d8730abd
--- /dev/null
+++ b/src/USER-OMP/pair_buck_omp.cpp
@@ -0,0 +1,165 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_buck_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairBuckOMP::PairBuckOMP(LAMMPS *lmp) :
+ PairBuck(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBuckOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairBuckOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,r,rexp,forcebuck,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ r = sqrt(rsq);
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ r = sqrt(rsq);
+ rexp = exp(-r*rhoinv[itype][jtype]);
+ forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
+ fpair = factor_lj*forcebuck*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBuckOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairBuck::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_buck_omp.h b/src/USER-OMP/pair_buck_omp.h
new file mode 100644
index 0000000000..40b6702e6f
--- /dev/null
+++ b/src/USER-OMP/pair_buck_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(buck/omp,PairBuckOMP)
+
+#else
+
+#ifndef LMP_PAIR_BUCK_OMP_H
+#define LMP_PAIR_BUCK_OMP_H
+
+#include "pair_buck.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairBuckOMP : public PairBuck, public ThrOMP {
+
+ public:
+ PairBuckOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_cdeam_omp.cpp b/src/USER-OMP/pair_cdeam_omp.cpp
new file mode 100644
index 0000000000..01bd5f6eaa
--- /dev/null
+++ b/src/USER-OMP/pair_cdeam_omp.cpp
@@ -0,0 +1,545 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "string.h"
+
+#include "pair_cdeam_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+// This is for debugging purposes. The ASSERT() macro is used in the code to check
+// if everything runs as expected. Change this to #if 0 if you don't need the checking.
+#if 0
+ #define ASSERT(cond) ((!(cond)) ? my_failure(error,__FILE__,__LINE__) : my_noop())
+
+ inline void my_noop() {}
+ inline void my_failure(Error* error, const char* file, int line) {
+ char str[1024];
+ sprintf(str,"Assertion failure: File %s, line %i", file, line);
+ error->one(FLERR,str);
+ }
+#else
+ #define ASSERT(cond)
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+PairCDEAMOMP::PairCDEAMOMP(LAMMPS *lmp, int _cdeamVersion) :
+ PairCDEAM(lmp,_cdeamVersion), PairEAM(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCDEAMOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow energy and fp arrays if necessary
+ // need to be atom->nmax in length
+
+ if (atom->nmax > nmax) {
+ memory->destroy(rho);
+ memory->destroy(rhoB);
+ memory->destroy(D_values);
+ memory->destroy(fp);
+ nmax = atom->nmax;
+ memory->create(rho,nthreads*nmax,"pair:rho");
+ memory->create(rhoB,nthreads*nmax,"pair:mu");
+ memory->create(D_values,nthreads*nmax,"pair:D_values");
+ memory->create(fp,nmax,"pair:fp");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, *rho_t, *rhoB_t, *D_values_t;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ if (force->newton_pair) {
+ rho_t = rho + tid*nall;
+ rhoB_t = rhoB + tid*nall;
+ D_values_t = D_values + tid*nall;
+ } else {
+ rho_t = rho + tid*atom->nlocal;
+ rhoB_t = rhoB + tid*atom->nlocal;
+ D_values_t = D_values + tid*atom->nlocal;
+ }
+
+ switch (cdeamVersion) {
+
+ case 1:
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<1,1,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<1,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<0,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ }
+ break;
+
+ case 2:
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<1,1,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<1,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ else eval<0,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ }
+ break;
+
+ default:
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ error->all(FLERR,"unsupported eam/cd pair style variant");
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairCDEAMOMP::eval(double **f, double *rho_t, double *rhoB_t,
+ double *D_values_t, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,rhoip,rhojp,recip,phi;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // zero out density
+
+ if (NEWTON_PAIR) {
+ memset(rho_t, 0, nall*sizeof(double));
+ memset(rhoB_t, 0, nall*sizeof(double));
+ memset(D_values_t, 0, nall*sizeof(double));
+ } else {
+ memset(rho_t, 0, nlocal*sizeof(double));
+ memset(rhoB_t, 0, nlocal*sizeof(double));
+ memset(D_values_t, 0, nlocal*sizeof(double));
+ }
+
+ // Stage I
+
+ // Compute rho and rhoB at each local atom site.
+ // Additionally calculate the D_i values here if we are using the one-site formulation.
+ // For the two-site formulation we have to calculate the D values in an extra loop (Stage II).
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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];
+ double r = sqrt(rsq);
+ const EAMTableIndex index = radiusToTableIndex(r);
+ double localrho = RhoOfR(index, jtype, itype);
+ rho_t[i] += localrho;
+ if(jtype == speciesB) rhoB_t[i] += localrho;
+ if(NEWTON_PAIR || j < nlocal) {
+ localrho = RhoOfR(index, itype, jtype);
+ rho_t[j] += localrho;
+ if(itype == speciesB) rhoB_t[j] += localrho;
+ }
+
+ if(CDEAMVERSION == 1 && itype != jtype) {
+ // Note: if the i-j interaction is not concentration dependent (because either
+ // i or j are not species A or B) then its contribution to D_i and D_j should
+ // be ignored.
+ // This if-clause is only required for a ternary.
+ if((itype == speciesA && jtype == speciesB)
+ || (jtype == speciesA && itype == speciesB)) {
+ double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r);
+ D_values_t[i] += Phi_AB;
+ if(NEWTON_PAIR || j < nlocal)
+ D_values_t[j] += Phi_AB;
+ }
+ }
+ }
+ }
+ }
+
+ // wait until all threads are done with computation
+ sync_threads();
+
+ // communicate and sum densities
+
+ if (NEWTON_PAIR) {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(&(rhoB[0]), nall, comm->nthreads, 1, tid);
+ if (CDEAMVERSION==1)
+ data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { communicationStage = 1;
+ comm->reverse_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ } else {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(&(rhoB[0]), nlocal, comm->nthreads, 1, tid);
+ if (CDEAMVERSION==1)
+ data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+ // fp = derivative of embedding energy at each atom
+ // phi = embedding energy at each atom
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ EAMTableIndex index = rhoToTableIndex(rho[i]);
+ fp[i] = FPrimeOfRho(index, type[i]);
+ if(EFLAG) {
+ phi = FofRho(index, type[i]);
+ if (eflag_global) eng_vdwl_thr[tid] += phi;
+ if (eflag_atom) eatom_thr[tid][i] += phi;
+ }
+ }
+
+ // wait until all theads are done with computation
+ sync_threads();
+
+ // Communicate derivative of embedding function and densities
+ // and D_values (this for one-site formulation only).
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { communicationStage = 2;
+ comm->forward_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+
+ // The electron densities may not drop to zero because then the concentration would no longer be defined.
+ // But the concentration is not needed anyway if there is no interaction with another atom, which is the case
+ // if the electron density is exactly zero. That's why the following lines have been commented out.
+ //
+ //for(i = 0; i < nlocal + atom->nghost; i++) {
+ // if(rho[i] == 0 && (type[i] == speciesA || type[i] == speciesB))
+ // error->one(FLERR,"CD-EAM potential routine: Detected atom with zero electron density.");
+ //}
+
+ // Stage II
+ // This is only required for the original two-site formulation of the CD-EAM potential.
+
+ if(CDEAMVERSION == 2) {
+ // Compute intermediate value D_i for each atom.
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ // This code line is required for ternary alloys.
+ if(itype != speciesA && itype != speciesB) continue;
+
+ double x_i = rhoB[i] / rho[i]; // Concentration at atom i.
+
+ for(jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+ if(itype == jtype) continue;
+
+ // This code line is required for ternary alloys.
+ if(jtype != speciesA && jtype != speciesB) continue;
+
+ 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) {
+ double r = sqrt(rsq);
+ const EAMTableIndex index = radiusToTableIndex(r);
+
+ // The concentration independent part of the cross pair potential.
+ double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r);
+
+ // Average concentration of two sites
+ double x_ij = 0.5 * (x_i + rhoB[j]/rho[j]);
+
+ // Calculate derivative of h(x_ij) polynomial function.
+ double h_prime = evalHprime(x_ij);
+
+ D_values_t[i] += h_prime * Phi_AB / (2.0 * rho[i] * rho[i]);
+ if(NEWTON_PAIR || j < nlocal)
+ D_values_t[j] += h_prime * Phi_AB / (2.0 * rho[j] * rho[j]);
+ }
+ }
+ }
+
+ if (NEWTON_PAIR) {
+ data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { communicationStage = 3;
+ comm->reverse_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ } else {
+ data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { communicationStage = 4;
+ comm->forward_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+ }
+
+ // Stage III
+
+ // Compute force acting on each atom.
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ // Concentration at site i
+ double x_i = -1.0; // The value -1 indicates: no concentration dependence for all interactions of atom i.
+ // It will be replaced by the concentration at site i if atom i is either A or B.
+
+ double D_i, h_prime_i;
+
+ // This if-clause is only required for ternary alloys.
+ if((itype == speciesA || itype == speciesB) && rho[i] != 0.0) {
+
+ // Compute local concentration at site i.
+ x_i = rhoB[i]/rho[i];
+ ASSERT(x_i >= 0 && x_i<=1.0);
+
+ if(CDEAMVERSION == 1) {
+ // Calculate derivative of h(x_i) polynomial function.
+ h_prime_i = evalHprime(x_i);
+ D_i = D_values[i] * h_prime_i / (2.0 * rho[i] * rho[i]);
+ } else if(CDEAMVERSION == 2) {
+ D_i = D_values[i];
+ } else ASSERT(false);
+ }
+
+ for(jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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];
+ double r = sqrt(rsq);
+ const EAMTableIndex index = radiusToTableIndex(r);
+
+ // rhoip = derivative of (density at atom j due to atom i)
+ // rhojp = derivative of (density at atom i due to atom j)
+ // 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 = RhoPrimeOfR(index, itype, jtype);
+ rhojp = RhoPrimeOfR(index, jtype, itype);
+ fpair = fp[i]*rhojp + fp[j]*rhoip;
+ recip = 1.0/r;
+
+ double x_j = -1; // The value -1 indicates: no concentration dependence for this i-j pair
+ // because atom j is not of species A nor B.
+
+ // This code line is required for ternary alloy.
+ if(jtype == speciesA || jtype == speciesB) {
+ ASSERT(rho[i] != 0.0);
+ ASSERT(rho[j] != 0.0);
+
+ // Compute local concentration at site j.
+ x_j = rhoB[j]/rho[j];
+ ASSERT(x_j >= 0 && x_j<=1.0);
+
+ double D_j;
+ if(CDEAMVERSION == 1) {
+ // Calculate derivative of h(x_j) polynomial function.
+ double h_prime_j = evalHprime(x_j);
+ D_j = D_values[j] * h_prime_j / (2.0 * rho[j] * rho[j]);
+ } else if(CDEAMVERSION == 2) {
+ D_j = D_values[j];
+ } else ASSERT(false);
+
+ double t2 = -rhoB[j];
+ if(itype == speciesB) t2 += rho[j];
+ fpair += D_j * rhoip * t2;
+ }
+
+ // This if-clause is only required for a ternary alloy.
+ // Actually we don't need it at all because D_i should be zero anyway if
+ // atom i has no concentration dependent interactions (because it is not species A or B).
+ if(x_i != -1.0) {
+ double t1 = -rhoB[i];
+ if(jtype == speciesB) t1 += rho[i];
+ fpair += D_i * rhojp * t1;
+ }
+
+ double phip;
+ double phi = PhiOfR(index, itype, jtype, recip, phip);
+ if(itype == jtype || x_i == -1.0 || x_j == -1.0) {
+ // Case of no concentration dependence.
+ fpair += phip;
+ } else {
+ // We have a concentration dependence for the i-j interaction.
+ double h;
+ if(CDEAMVERSION == 1) {
+ // Calculate h(x_i) polynomial function.
+ double h_i = evalH(x_i);
+ // Calculate h(x_j) polynomial function.
+ double h_j = evalH(x_j);
+ h = 0.5 * (h_i + h_j);
+ } else if(CDEAMVERSION == 2) {
+ // Average concentration.
+ double x_ij = 0.5 * (x_i + x_j);
+ // Calculate h(x_ij) polynomial function.
+ h = evalH(x_ij);
+ } else ASSERT(false);
+
+ fpair += h * phip;
+ phi *= h;
+ }
+
+ // Divide by r_ij and negate to get forces from gradient.
+ fpair /= -r;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if(NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if(EFLAG) evdwl = phi;
+ if(EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
+ fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCDEAMOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairCDEAM::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_cdeam_omp.h b/src/USER-OMP/pair_cdeam_omp.h
new file mode 100644
index 0000000000..85b124cb17
--- /dev/null
+++ b/src/USER-OMP/pair_cdeam_omp.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(eam/cd/omp,PairCDEAM_OneSiteOMP)
+PairStyle(eam/cd/old/omp,PairCDEAM_TwoSiteOMP)
+
+#else
+
+#ifndef LMP_PAIR_CDEAM_OMP_H
+#define LMP_PAIR_CDEAM_OMP_H
+
+#include "pair_cdeam.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairCDEAMOMP : public PairCDEAM, public ThrOMP {
+
+ public:
+ PairCDEAMOMP(class LAMMPS *, int);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double *rho_t, double *rhoB_t, double *D_values_t,
+ int iifrom, int iito, int tid);
+};
+
+ /// The one-site concentration formulation of CD-EAM.
+ class PairCDEAM_OneSiteOMP : public PairCDEAMOMP
+ {
+ public:
+ /// Constructor.
+ PairCDEAM_OneSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 1) {}
+ };
+
+ /// The two-site concentration formulation of CD-EAM.
+ class PairCDEAM_TwoSiteOMP : public PairCDEAMOMP
+ {
+ public:
+ /// Constructor.
+ PairCDEAM_TwoSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 2) {}
+ };
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_colloid_omp.cpp b/src/USER-OMP/pair_colloid_omp.cpp
new file mode 100644
index 0000000000..c8bc74407a
--- /dev/null
+++ b/src/USER-OMP/pair_colloid_omp.cpp
@@ -0,0 +1,223 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_colloid_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairColloidOMP::PairColloidOMP(LAMMPS *lmp) :
+ PairColloid(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairColloidOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairColloidOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,r2inv,r6inv,forcelj,factor_lj;
+ double c1,c2,fR,dUR,dUA,K[9],h[4],g[4];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) continue;
+
+ switch(form[itype][jtype]) {
+ case SMALL_SMALL:
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = factor_lj*forcelj*r2inv;
+ if (EFLAG)
+ evdwl = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ break;
+
+ case SMALL_LARGE:
+ c2 = a2[itype][jtype];
+ K[1] = c2*c2;
+ K[2] = rsq;
+ K[0] = K[1] - rsq;
+ K[4] = rsq*rsq;
+ K[3] = K[1] - K[2];
+ K[3] *= K[3]*K[3];
+ K[6] = K[3]*K[3];
+ fR = sigma3[itype][jtype]*a12[itype][jtype]*c2*K[1]/K[3];
+ fpair = 4.0/15.0*fR*factor_lj *
+ (2.0*(K[1]+K[2]) * (K[1]*(5.0*K[1]+22.0*K[2])+5.0*K[4]) *
+ sigma6[itype][jtype]/K[6]-5.0) / K[0];
+ if (EFLAG)
+ evdwl = 2.0/9.0*fR *
+ (1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) *
+ sigma6[itype][jtype]/K[6]) - offset[itype][jtype];
+ if (rsq <= K[1]) error->one(FLERR,"Overlapping small/large in pair colloid");
+ break;
+
+ case LARGE_LARGE:
+ r = sqrt(rsq);
+ c1 = a1[itype][jtype];
+ c2 = a2[itype][jtype];
+ K[0] = c1*c2;
+ K[1] = c1+c2;
+ K[2] = c1-c2;
+ K[3] = K[1]+r;
+ K[4] = K[1]-r;
+ K[5] = K[2]+r;
+ K[6] = K[2]-r;
+ K[7] = 1.0/(K[3]*K[4]);
+ K[8] = 1.0/(K[5]*K[6]);
+ g[0] = pow(K[3],-7.0);
+ g[1] = pow(K[4],-7.0);
+ g[2] = pow(K[5],-7.0);
+ g[3] = pow(K[6],-7.0);
+ h[0] = ((K[3]+5.0*K[1])*K[3]+30.0*K[0])*g[0];
+ h[1] = ((K[4]+5.0*K[1])*K[4]+30.0*K[0])*g[1];
+ h[2] = ((K[5]+5.0*K[2])*K[5]-30.0*K[0])*g[2];
+ h[3] = ((K[6]+5.0*K[2])*K[6]-30.0*K[0])*g[3];
+ g[0] *= 42.0*K[0]/K[3]+6.0*K[1]+K[3];
+ g[1] *= 42.0*K[0]/K[4]+6.0*K[1]+K[4];
+ g[2] *= -42.0*K[0]/K[5]+6.0*K[2]+K[5];
+ g[3] *= -42.0*K[0]/K[6]+6.0*K[2]+K[6];
+
+ fR = a12[itype][jtype]*sigma6[itype][jtype]/r/37800.0;
+ evdwl = fR * (h[0]-h[1]-h[2]+h[3]);
+ dUR = evdwl/r + 5.0*fR*(g[0]+g[1]-g[2]-g[3]);
+ dUA = -a12[itype][jtype]/3.0*r*((2.0*K[0]*K[7]+1.0)*K[7] +
+ (2.0*K[0]*K[8]-1.0)*K[8]);
+ fpair = factor_lj * (dUR+dUA)/r;
+ if (EFLAG)
+ evdwl += a12[itype][jtype]/6.0 *
+ (2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - offset[itype][jtype];
+ if (r <= K[1]) error->one(FLERR,"Overlapping large/large in pair colloid");
+ break;
+ }
+
+ if (EFLAG) evdwl *= factor_lj;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairColloidOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairColloid::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_colloid_omp.h b/src/USER-OMP/pair_colloid_omp.h
new file mode 100644
index 0000000000..a0be13cbb4
--- /dev/null
+++ b/src/USER-OMP/pair_colloid_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(colloid/omp,PairColloidOMP)
+
+#else
+
+#ifndef LMP_PAIR_COLLOID_OMP_H
+#define LMP_PAIR_COLLOID_OMP_H
+
+#include "pair_colloid.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairColloidOMP : public PairColloid, public ThrOMP {
+
+ public:
+ PairColloidOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp
new file mode 100644
index 0000000000..207c122e45
--- /dev/null
+++ b/src/USER-OMP/pair_comb_omp.cpp
@@ -0,0 +1,540 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_comb_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairCombOMP::PairCombOMP(LAMMPS *lmp) :
+ PairComb(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCombOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow coordination array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->destroy(NCo);
+ nmax = atom->nmax;
+ memory->create(NCo,nmax,"pair:NCo");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else eval<0,0,0>(f, ifrom, ito, tid);
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairCombOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,ii,jj,kk,jnum,iparam_i;
+ int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,rsq1,rsq2;
+ double delr1[3],delr2[3],fi[3],fj[3],fk[3];
+ double zeta_ij,prefactor;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int mr1,mr2,mr3;
+ int rsc,inty;
+ double elp_ij,filp[3],fjlp[3],fklp[3];
+ double iq,jq;
+ double yaself;
+ double potal,fac11,fac11e;
+ double vionij,fvionij,sr1,sr2,sr3,Eov,Fov;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ yaself = vionij = fvionij = Eov = Fov = 0.0;
+
+ double fxtmp,fytmp,fztmp;
+ double fjxtmp,fjytmp,fjztmp;
+
+ // self energy correction term: potal
+
+ potal_calc(potal,fac11,fac11e);
+
+ // loop over full neighbor list of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ iq = q[i];
+ NCo[i] = 0;
+ iparam_i = elem2param[itype][itype][itype];
+
+ // self energy, only on i atom
+
+ yaself = self(¶ms[iparam_i],iq,potal);
+
+ if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,yaself,
+ 0.0,0.0,0.0,0.0,0.0,tid);
+
+ // two-body interactions (long and short repulsive)
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
+ // Qj calculates 2-body Coulombic
+
+ jtype = map[type[j]];
+ jq = q[j];
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ // long range q-dependent
+
+ if (rsq > params[iparam_ij].lcutsq) continue;
+
+ inty = intype[itype][jtype];
+
+ // polynomial three-point interpolation
+
+ tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype);
+
+ // 1/r energy and forces
+
+ direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq,
+ potal,fac11,fac11e,vionij,fvionij);
+
+ // field correction to self energy
+
+ field(¶ms[iparam_ij],rsq,iq,jq,vionij,fvionij);
+
+ // polarization field
+ // sums up long range forces
+
+ fxtmp += delx*fvionij;
+ fytmp += dely*fvionij;
+ fztmp += delz*fvionij;
+ f[j][0] -= delx*fvionij;
+ f[j][1] -= dely*fvionij;
+ f[j][2] -= delz*fvionij;
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ 0.0,vionij,fvionij,delx,dely,delz,tid);
+
+ // short range q-independent
+
+ if (rsq > params[iparam_ij].cutsq) continue;
+
+ repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl,iq,jq);
+
+ // repulsion is pure two-body, sums up pair repulsive forces
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+
+ // accumulate coordination number information
+
+ if (cor_flag) {
+ int numcoor = 0;
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ if(params[iparam_ij].hfocor > 0.0 ) {
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = vec3_dot(delr1,delr1);
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+ ++numcoor;
+ }
+ NCo[i] = numcoor;
+ }
+ }
+
+ // three-body interactions
+ // skip immediately if I-J is not within cutoff
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ // this Qj for q-dependent BSi
+
+ jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = vec3_dot(delr1,delr1);
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+
+ // accumulate bondorder zeta for each i-j interaction via loop over k
+
+ fjxtmp = fjytmp = fjztmp = 0.0;
+ zeta_ij = 0.0;
+ cuo_flag1 = 0; cuo_flag2 = 0;
+
+ for (kk = 0; kk < jnum; kk++) {
+ if (jj == kk) continue;
+ k = jlist[kk];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = vec3_dot(delr2,delr2);
+
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
+
+ if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1;
+ if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1;
+ }
+
+ if (cuo_flag1 && cuo_flag2) cuo_flag = 1;
+ else cuo_flag = 0;
+
+ // pairwise force due to zeta
+
+ force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair,
+ prefactor,EFLAG,evdwl,iq,jq);
+
+ // over-coordination correction for HfO2
+
+ if (cor_flag && NCo[i] != 0)
+ Over_cor(¶ms[iparam_ij],rsq1,NCo[i],Eov, Fov);
+ evdwl += Eov;
+ fpair += Fov;
+
+ fxtmp += delr1[0]*fpair;
+ fytmp += delr1[1]*fpair;
+ fztmp += delr1[2]*fpair;
+ fjxtmp -= delr1[0]*fpair;
+ fjytmp -= delr1[1]*fpair;
+ fjztmp -= delr1[2]*fpair;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0,
+ -fpair,-delr1[0],-delr1[1],-delr1[2],tid);
+
+ // attractive term via loop over k (3-body forces)
+
+ for (kk = 0; kk < jnum; kk++) {
+ if (jj == kk) continue;
+ k = jlist[kk];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = vec3_dot(delr2,delr2);
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ for (rsc = 0; rsc < 3; rsc++)
+ fi[rsc] = fj[rsc] = fk[rsc] = 0.0;
+
+ attractive(¶ms[iparam_ijk],prefactor,
+ rsq1,rsq2,delr1,delr2,fi,fj,fk);
+
+ // 3-body LP and BB correction and forces
+
+ elp_ij = elp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
+ flp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp);
+
+ fxtmp += fi[0] + filp[0];
+ fytmp += fi[1] + filp[1];
+ fztmp += fi[2] + filp[2];
+ fjxtmp += fj[0] + fjlp[0];
+ fjytmp += fj[1] + fjlp[1];
+ fjztmp += fj[2] + fjlp[2];
+ f[k][0] += fk[0] + fklp[0];
+ f[k][1] += fk[1] + fklp[1];
+ f[k][2] += fk[2] + fklp[2];
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ elp_ij,0.0,0.0,0.0,0.0,0.0, tid);
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid);
+ }
+ f[j][0] += fjxtmp;
+ f[j][1] += fjytmp;
+ f[j][2] += fjztmp;
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+
+ if (cuo_flag) params[iparam_i].cutsq *= 0.65;
+ }
+ cuo_flag = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCombOMP::yasu_char(double *qf_fix, int &igroup)
+{
+ int ii;
+ double potal,fac11,fac11e;
+
+ const double * const * const x = atom->x;
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+
+ const int inum = list->inum;
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
+
+ const int * const mask = atom->mask;
+ const int groupbit = group->bitmask[igroup];
+
+ qf = qf_fix;
+ for (ii = 0; ii < inum; ii++) {
+ const int i = ilist[ii];
+ if (mask[i] & groupbit)
+ qf[i] = 0.0;
+ }
+
+ // communicating charge force to all nodes, first forward then reverse
+
+ comm->forward_comm_pair(this);
+
+ // self energy correction term: potal
+
+ potal_calc(potal,fac11,fac11e);
+
+ // loop over full neighbor list of my atoms
+#if defined(_OPENMP)
+#pragma omp parallel for private(ii) default(none) shared(potal,fac11e)
+#endif
+ for (ii = 0; ii < inum; ii ++) {
+ double fqi,fqj,fqij,fqji,fqjj,delr1[3],delr2[3];
+ double sr1,sr2,sr3;
+ int mr1,mr2,mr3;
+
+ const int i = ilist[ii];
+
+ if (mask[i] & groupbit) {
+ fqi = fqj = fqij = fqji = fqjj = 0.0; // should not be needed.
+ int itype = map[type[i]];
+ const double xtmp = x[i][0];
+ const double ytmp = x[i][1];
+ const double ztmp = x[i][2];
+ const double iq = q[i];
+ const int iparam_i = elem2param[itype][itype][itype];
+
+ // charge force from self energy
+
+ fqi = qfo_self(¶ms[iparam_i],iq,potal);
+
+ // two-body interactions
+
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ const int j = jlist[jj] & NEIGHMASK;
+ const int jtype = map[type[j]];
+ double jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ double rsq1 = vec3_dot(delr1,delr1);
+
+ const int iparam_ij = elem2param[itype][jtype][jtype];
+
+ // long range q-dependent
+
+ if (rsq1 > params[iparam_ij].lcutsq) continue;
+
+ const int inty = intype[itype][jtype];
+
+ // polynomial three-point interpolation
+
+ tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype);
+
+ // 1/r charge forces
+
+ qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij);
+
+ // field correction to self energy and charge force
+
+ qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqji,fqjj);
+ fqi += jq * fqij + fqji;
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ qf[j] += (iq * fqij + fqjj);
+
+ // polarization field charge force
+ // three-body interactions
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+
+ double zeta_ij = 0.0;
+
+ for (int kk = 0; kk < jnum; kk++) {
+ if (jj == kk) continue;
+ const int k = jlist[kk] & NEIGHMASK;
+ const int ktype = map[type[k]];
+ const int iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ const double rsq2 = vec3_dot(delr2,delr2);
+
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+ zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
+ }
+
+ // charge force in Aij and Bij
+
+ qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj);
+ fqi += fqij;
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ qf[j] += fqjj;
+ }
+
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ qf[i] += fqi;
+
+ }
+ }
+
+ comm->reverse_comm_pair(this);
+
+ // sum charge force on each node and return it
+
+ double eneg = 0.0;
+ for (ii = 0; ii < inum; ii++) {
+ const int i = ilist[ii];
+ if (mask[i] & groupbit)
+ eneg += qf[i];
+ }
+ double enegtot;
+ MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world);
+ return enegtot;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCombOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairComb::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_comb_omp.h b/src/USER-OMP/pair_comb_omp.h
new file mode 100644
index 0000000000..6f020ea9ab
--- /dev/null
+++ b/src/USER-OMP/pair_comb_omp.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(comb/omp,PairCombOMP)
+
+#else
+
+#ifndef LMP_PAIR_COMB_OMP_H
+#define LMP_PAIR_COMB_OMP_H
+
+#include "pair_comb.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairCombOMP : public PairComb, public ThrOMP {
+
+ public:
+ PairCombOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ virtual double yasu_char(double *, int &);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_coul_cut_omp.cpp b/src/USER-OMP/pair_coul_cut_omp.cpp
new file mode 100644
index 0000000000..bb19db3d22
--- /dev/null
+++ b/src/USER-OMP/pair_coul_cut_omp.cpp
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_coul_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulCutOMP::PairCoulCutOMP(LAMMPS *lmp) :
+ PairCoulCut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCoulCutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
+ double rsq,r2inv,rinv,forcecoul,factor_coul;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ rinv = sqrt(r2inv);
+ forcecoul = qqrd2e * scale[itype][jtype] * qtmp*q[j]*rinv;
+ fpair = factor_coul*forcecoul * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG)
+ ecoul = factor_coul * qqrd2e * scale[itype][jtype] * qtmp*q[j]*rinv;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ 0.0,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCoulCutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairCoulCut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_coul_cut_omp.h b/src/USER-OMP/pair_coul_cut_omp.h
new file mode 100644
index 0000000000..eca9958ff2
--- /dev/null
+++ b/src/USER-OMP/pair_coul_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(coul/cut/omp,PairCoulCutOMP)
+
+#else
+
+#ifndef LMP_PAIR_COUL_CUT_OMP_H
+#define LMP_PAIR_COUL_CUT_OMP_H
+
+#include "pair_coul_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairCoulCutOMP : public PairCoulCut, public ThrOMP {
+
+ public:
+ PairCoulCutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_coul_debye_omp.cpp b/src/USER-OMP/pair_coul_debye_omp.cpp
new file mode 100644
index 0000000000..1c2e7b8e07
--- /dev/null
+++ b/src/USER-OMP/pair_coul_debye_omp.cpp
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_coul_debye_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulDebyeOMP::PairCoulDebyeOMP(LAMMPS *lmp) :
+ PairCoulDebye(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCoulDebyeOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
+ double rsq,r2inv,r,rinv,forcecoul,factor_coul,screening;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ screening = exp(-kappa*r);
+ forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv);
+ fpair = factor_coul*forcecoul * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG)
+ ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ 0.0,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+double PairCoulDebyeOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairCoulDebye::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_coul_debye_omp.h b/src/USER-OMP/pair_coul_debye_omp.h
new file mode 100644
index 0000000000..7ad599bb1b
--- /dev/null
+++ b/src/USER-OMP/pair_coul_debye_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(coul/debye/omp,PairCoulDebyeOMP)
+
+#else
+
+#ifndef LMP_PAIR_COUL_DEBYE_OMP_H
+#define LMP_PAIR_COUL_DEBYE_OMP_H
+
+#include "pair_coul_debye.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairCoulDebyeOMP : public PairCoulDebye, public ThrOMP {
+
+ public:
+ PairCoulDebyeOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_coul_long_omp.cpp b/src/USER-OMP/pair_coul_long_omp.cpp
new file mode 100644
index 0000000000..3a2e051591
--- /dev/null
+++ b/src/USER-OMP/pair_coul_long_omp.cpp
@@ -0,0 +1,201 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulLongOMP::PairCoulLongOMP(LAMMPS *lmp) :
+ PairCoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itable,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
+ double fraction,table;
+ double r,r2inv,rsq,forcecoul,factor_coul;
+ double grij,expm2,prefactor,t,erfc;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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_coulsq) {
+ r2inv = 1.0/rsq;
+ 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 = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r;
+ forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else {
+ union_int_float_t rsq_lookup;
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
+ table = ftable[itable] + fraction*dftable[itable];
+ forcecoul = scale[itype][jtype] * qtmp*q[j] * table;
+ if (factor_coul < 1.0) {
+ table = ctable[itable] + fraction*dctable[itable];
+ prefactor = scale[itype][jtype] * qtmp*q[j] * table;
+ forcecoul -= (1.0-factor_coul)*prefactor;
+ }
+ }
+
+ fpair = forcecoul * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ ecoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ ecoul = scale[itype][jtype] * qtmp*q[j] * table;
+ }
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ 0.0,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairCoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_coul_long_omp.h b/src/USER-OMP/pair_coul_long_omp.h
new file mode 100644
index 0000000000..7b63f762f2
--- /dev/null
+++ b/src/USER-OMP/pair_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(coul/long/omp,PairCoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_COUL_LONG_OMP_H
+#define LMP_PAIR_COUL_LONG_OMP_H
+
+#include "pair_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairCoulLongOMP : public PairCoulLong, public ThrOMP {
+
+ public:
+ PairCoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_dipole_cut_omp.cpp b/src/USER-OMP/pair_dipole_cut_omp.cpp
new file mode 100644
index 0000000000..9ba93b19b5
--- /dev/null
+++ b/src/USER-OMP/pair_dipole_cut_omp.cpp
@@ -0,0 +1,288 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_dipole_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairDipoleCutOMP::PairDipoleCutOMP(LAMMPS *lmp) :
+ PairDipoleCut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairDipoleCutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces and torques into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairDipoleCutOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul;
+ double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv,fx,fy,fz;
+ double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz;
+ double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
+ double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
+ double forcelj,factor_coul,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ double **mu = atom->mu;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_coul = special_coul[sbmask(j)];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ rinv = sqrt(r2inv);
+
+ // atom can have both a charge and dipole
+ // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
+
+ forcecoulx = forcecouly = forcecoulz = 0.0;
+ tixcoul = tiycoul = tizcoul = 0.0;
+ tjxcoul = tjycoul = tjzcoul = 0.0;
+
+ if (rsq < cut_coulsq[itype][jtype]) {
+
+ if (qtmp != 0.0 && q[j] != 0.0) {
+ r3inv = r2inv*rinv;
+ pre1 = qtmp*q[j]*r3inv;
+
+ forcecoulx += pre1*delx;
+ forcecouly += pre1*dely;
+ forcecoulz += pre1*delz;
+ }
+
+ if (mu[i][3] > 0.0 && mu[j][3] > 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ r7inv = r5inv*r2inv;
+
+ pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
+ pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
+ pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
+
+ pre1 = 3.0*r5inv*pdotp - 15.0*r7inv*pidotr*pjdotr;
+ pre2 = 3.0*r5inv*pjdotr;
+ pre3 = 3.0*r5inv*pidotr;
+ pre4 = -1.0*r3inv;
+
+ forcecoulx += pre1*delx + pre2*mu[i][0] + pre3*mu[j][0];
+ forcecouly += pre1*dely + pre2*mu[i][1] + pre3*mu[j][1];
+ forcecoulz += pre1*delz + pre2*mu[i][2] + pre3*mu[j][2];
+
+ crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
+ crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
+ crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
+
+ tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
+ tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
+ tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
+ tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
+ tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
+ tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
+ }
+
+ if (mu[i][3] > 0.0 && q[j] != 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
+ pre1 = 3.0*q[j]*r5inv * pidotr;
+ pre2 = q[j]*r3inv;
+
+ forcecoulx += pre2*mu[i][0] - pre1*delx;
+ forcecouly += pre2*mu[i][1] - pre1*dely;
+ forcecoulz += pre2*mu[i][2] - pre1*delz;
+ tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
+ tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
+ tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
+ }
+
+ if (mu[j][3] > 0.0 && qtmp != 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
+ pre1 = 3.0*qtmp*r5inv * pjdotr;
+ pre2 = qtmp*r3inv;
+
+ forcecoulx += pre1*delx - pre2*mu[j][0];
+ forcecouly += pre1*dely - pre2*mu[j][1];
+ forcecoulz += pre1*delz - pre2*mu[j][2];
+ tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
+ tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
+ tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
+ }
+ }
+
+ // LJ interaction
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ forcelj *= factor_lj * r2inv;
+ } else forcelj = 0.0;
+
+ // total force
+
+ fq = factor_coul*qqrd2e;
+ fx = fq*forcecoulx + delx*forcelj;
+ fy = fq*forcecouly + dely*forcelj;
+ fz = fq*forcecoulz + delz*forcelj;
+
+ // force & torque accumulation
+
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+ t1tmp += fq*tixcoul;
+ t2tmp += fq*tiycoul;
+ t3tmp += fq*tizcoul;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ torque[j][0] += fq*tjxcoul;
+ torque[j][1] += fq*tjycoul;
+ torque[j][2] += fq*tjzcoul;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype]) {
+ ecoul = qtmp*q[j]*rinv;
+ if (mu[i][3] > 0.0 && mu[j][3] > 0.0)
+ ecoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr;
+ if (mu[i][3] > 0.0 && q[j] != 0.0)
+ ecoul += -q[j]*r3inv*pidotr;
+ if (mu[j][3] > 0.0 && qtmp != 0.0)
+ ecoul += qtmp*r3inv*pjdotr;
+ ecoul *= factor_coul*qqrd2e;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ torque[i][0] += t1tmp;
+ torque[i][1] += t2tmp;
+ torque[i][2] += t3tmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairDipoleCutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairDipoleCut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_dipole_cut_omp.h b/src/USER-OMP/pair_dipole_cut_omp.h
new file mode 100644
index 0000000000..832bd4d3be
--- /dev/null
+++ b/src/USER-OMP/pair_dipole_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(dipole/cut/omp,PairDipoleCutOMP)
+
+#else
+
+#ifndef LMP_PAIR_DIPOLE_CUT_OMP_H
+#define LMP_PAIR_DIPOLE_CUT_OMP_H
+
+#include "pair_dipole_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairDipoleCutOMP : public PairDipoleCut, public ThrOMP {
+
+ public:
+ PairDipoleCutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_dipole_sf_omp.cpp b/src/USER-OMP/pair_dipole_sf_omp.cpp
new file mode 100644
index 0000000000..9ebc72d414
--- /dev/null
+++ b/src/USER-OMP/pair_dipole_sf_omp.cpp
@@ -0,0 +1,320 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_dipole_sf_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairDipoleSFOMP::PairDipoleSFOMP(LAMMPS *lmp) :
+ PairDipoleSF(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairDipoleSFOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces and torques into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairDipoleSFOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul;
+ double rsq,rinv,r2inv,r6inv,r3inv,r5inv,fx,fy,fz;
+ double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz;
+ double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
+ double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
+ double forcelj,factor_coul,factor_lj;
+ double presf,afac,bfac,pqfac,qpfac,forceljcut,forceljsf;
+ double aforcecoulx,aforcecouly,aforcecoulz;
+ double bforcecoulx,bforcecouly,bforcecoulz;
+ double rcutlj2inv, rcutcoul2inv,rcutlj6inv;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ double **mu = atom->mu;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_coul = special_coul[sbmask(j)];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ rinv = sqrt(r2inv);
+
+ // atom can have both a charge and dipole
+ // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
+ // atom can have both a charge and dipole
+ // i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
+
+ forcecoulx = forcecouly = forcecoulz = 0.0;
+ tixcoul = tiycoul = tizcoul = 0.0;
+ tjxcoul = tjycoul = tjzcoul = 0.0;
+
+ if (rsq < cut_coulsq[itype][jtype]) {
+
+ if (qtmp != 0.0 && q[j] != 0.0) {
+ pre1 = qtmp*q[j]*rinv*(r2inv-1.0/cut_coulsq[itype][jtype]);
+
+ forcecoulx += pre1*delx;
+ forcecouly += pre1*dely;
+ forcecoulz += pre1*delz;
+ }
+
+ if (mu[i][3] > 0.0 && mu[j][3] > 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
+
+ pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
+ pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
+ pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
+
+ afac = 1.0 - rsq*rsq * rcutcoul2inv*rcutcoul2inv;
+ pre1 = afac * ( pdotp - 3.0 * r2inv * pidotr * pjdotr );
+ aforcecoulx = pre1*delx;
+ aforcecouly = pre1*dely;
+ aforcecoulz = pre1*delz;
+
+ bfac = 1.0 - 4.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv) +
+ 3.0*rsq*rsq*rcutcoul2inv*rcutcoul2inv;
+ presf = 2.0 * r2inv * pidotr * pjdotr;
+ bforcecoulx = bfac * (pjdotr*mu[i][0]+pidotr*mu[j][0]-presf*delx);
+ bforcecouly = bfac * (pjdotr*mu[i][1]+pidotr*mu[j][1]-presf*dely);
+ bforcecoulz = bfac * (pjdotr*mu[i][2]+pidotr*mu[j][2]-presf*delz);
+
+ forcecoulx += 3.0 * r5inv * ( aforcecoulx + bforcecoulx );
+ forcecouly += 3.0 * r5inv * ( aforcecouly + bforcecouly );
+ forcecoulz += 3.0 * r5inv * ( aforcecoulz + bforcecoulz );
+
+ pre2 = 3.0 * bfac * r5inv * pjdotr;
+ pre3 = 3.0 * bfac * r5inv * pidotr;
+ pre4 = -bfac * r3inv;
+
+ crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
+ crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
+ crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
+
+ tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
+ tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
+ tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
+ tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
+ tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
+ tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
+ }
+
+ if (mu[i][3] > 0.0 && q[j] != 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
+ rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
+ pre1 = 3.0 * q[j] * r5inv * pidotr * (1-rsq*rcutcoul2inv);
+ pqfac = 1.0 - 3.0*rsq*rcutcoul2inv +
+ 2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv);
+ pre2 = q[j] * r3inv * pqfac;
+
+ forcecoulx += pre2*mu[i][0] - pre1*delx;
+ forcecouly += pre2*mu[i][1] - pre1*dely;
+ forcecoulz += pre2*mu[i][2] - pre1*delz;
+ tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
+ tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
+ tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
+ }
+
+ if (mu[j][3] > 0.0 && qtmp != 0.0) {
+ r3inv = r2inv*rinv;
+ r5inv = r3inv*r2inv;
+ pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
+ rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
+ pre1 = 3.0 * qtmp * r5inv * pjdotr * (1-rsq*rcutcoul2inv);
+ qpfac = 1.0 - 3.0*rsq*rcutcoul2inv +
+ 2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv);
+ pre2 = qtmp * r3inv * qpfac;
+
+ forcecoulx += pre1*delx - pre2*mu[j][0];
+ forcecouly += pre1*dely - pre2*mu[j][1];
+ forcecoulz += pre1*delz - pre2*mu[j][2];
+ tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
+ tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
+ tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
+ }
+ }
+
+ // LJ interaction
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forceljcut = r6inv*(lj1[itype][jtype]*r6inv-lj2[itype][jtype])*r2inv;
+
+ rcutlj2inv = 1.0 / cut_ljsq[itype][jtype];
+ rcutlj6inv = rcutlj2inv * rcutlj2inv * rcutlj2inv;
+ forceljsf = (lj1[itype][jtype]*rcutlj6inv - lj2[itype][jtype]) *
+ rcutlj6inv * rcutlj2inv;
+
+ forcelj = factor_lj * (forceljcut - forceljsf);
+ } else forcelj = 0.0;
+
+ // total force
+
+ fq = factor_coul*qqrd2e;
+ fx = fq*forcecoulx + delx*forcelj;
+ fy = fq*forcecouly + dely*forcelj;
+ fz = fq*forcecoulz + delz*forcelj;
+
+ // force & torque accumulation
+
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+ t1tmp += fq*tixcoul;
+ t2tmp += fq*tiycoul;
+ t3tmp += fq*tizcoul;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ torque[j][0] += fq*tjxcoul;
+ torque[j][1] += fq*tjycoul;
+ torque[j][2] += fq*tjzcoul;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype]) {
+ ecoul = qtmp * q[j] * rinv *
+ pow((1.0-sqrt(rsq)/sqrt(cut_coulsq[itype][jtype])),2);
+ if (mu[i][3] > 0.0 && mu[j][3] > 0.0)
+ ecoul += bfac * (r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr);
+ if (mu[i][3] > 0.0 && q[j] != 0.0)
+ ecoul += -q[j] * r3inv * pqfac * pidotr;
+ if (mu[j][3] > 0.0 && qtmp != 0.0)
+ ecoul += qtmp * r3inv * qpfac * pjdotr;
+ ecoul *= factor_coul*qqrd2e;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])+
+ rcutlj6inv*(6*lj3[itype][jtype]*rcutlj6inv-3*lj4[itype][jtype])*
+ rsq*rcutlj2inv+
+ rcutlj6inv*(-7*lj3[itype][jtype]*rcutlj6inv+4*lj4[itype][jtype]);
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ torque[i][0] += t1tmp;
+ torque[i][1] += t2tmp;
+ torque[i][2] += t3tmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairDipoleSFOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairDipoleSF::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_dipole_sf_omp.h b/src/USER-OMP/pair_dipole_sf_omp.h
new file mode 100644
index 0000000000..e601e2d569
--- /dev/null
+++ b/src/USER-OMP/pair_dipole_sf_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(dipole/sf/omp,PairDipoleSFOMP)
+
+#else
+
+#ifndef LMP_PAIR_DIPOLE_SF_OMP_H
+#define LMP_PAIR_DIPOLE_SF_OMP_H
+
+#include "pair_dipole_sf.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairDipoleSFOMP : public PairDipoleSF, public ThrOMP {
+
+ public:
+ PairDipoleSFOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_dpd_omp.cpp b/src/USER-OMP/pair_dpd_omp.cpp
new file mode 100644
index 0000000000..be1e32f37d
--- /dev/null
+++ b/src/USER-OMP/pair_dpd_omp.cpp
@@ -0,0 +1,212 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_dpd_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "update.h"
+#include "random_mars.h"
+
+using namespace LAMMPS_NS;
+
+#define EPSILON 1.0e-10
+
+/* ---------------------------------------------------------------------- */
+
+PairDPDOMP::PairDPDOMP(LAMMPS *lmp) :
+ PairDPD(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ random_thr = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairDPDOMP::~PairDPDOMP()
+{
+ if (random_thr) {
+ for (int i=1; i < comm->nthreads; ++i)
+ delete random_thr[i];
+
+ delete[] random_thr;
+ random_thr = NULL;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairDPDOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ if (!random_thr)
+ random_thr = new RanMars*[nthreads];
+
+ random_thr[0] = random;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (random_thr && tid > 0)
+ random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me
+ + comm->nprocs*tid);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairDPDOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
+ double rsq,r,rinv,dot,wd,randnum,factor_dpd;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double dtinvsqrt = 1.0/sqrt(update->dt);
+ double fxtmp,fytmp,fztmp;
+ RanMars &rng = *random_thr[tid];
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ vxtmp = v[i][0];
+ vytmp = v[i][1];
+ vztmp = v[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_dpd = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ r = sqrt(rsq);
+ if (r < EPSILON) continue; // r can be 0.0 in DPD systems
+ rinv = 1.0/r;
+ delvx = vxtmp - v[j][0];
+ delvy = vytmp - v[j][1];
+ delvz = vztmp - v[j][2];
+ dot = delx*delvx + dely*delvy + delz*delvz;
+ wd = 1.0 - r/cut[itype][jtype];
+ randnum = rng.gaussian();
+
+ // conservative force = a0 * wd
+ // drag force = -gamma * wd^2 * (delx dot delv) / r
+ // random force = sigma * wd * rnd * dtinvsqrt;
+
+ fpair = a0[itype][jtype]*wd;
+ fpair -= gamma[itype][jtype]*wd*wd*dot*rinv;
+ fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt;
+ fpair *= factor_dpd*rinv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ // unshifted eng of conservative term:
+ // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]);
+ // eng shifted to 0.0 at cutoff
+ evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wd*wd;
+ evdwl *= factor_dpd;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairDPDOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairDPD::memory_usage();
+ bytes += comm->nthreads * sizeof(RanMars*);
+ bytes += comm->nthreads * sizeof(RanMars);
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_dpd_omp.h b/src/USER-OMP/pair_dpd_omp.h
new file mode 100644
index 0000000000..9385e5444f
--- /dev/null
+++ b/src/USER-OMP/pair_dpd_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(dpd/omp,PairDPDOMP)
+
+#else
+
+#ifndef LMP_PAIR_DPD_OMP_H
+#define LMP_PAIR_DPD_OMP_H
+
+#include "pair_dpd.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairDPDOMP : public PairDPD, public ThrOMP {
+
+ public:
+ PairDPDOMP(class LAMMPS *);
+ virtual ~PairDPDOMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ class RanMars **random_thr;
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_dpd_tstat_omp.cpp b/src/USER-OMP/pair_dpd_tstat_omp.cpp
new file mode 100644
index 0000000000..7e3fb8b398
--- /dev/null
+++ b/src/USER-OMP/pair_dpd_tstat_omp.cpp
@@ -0,0 +1,214 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_dpd_tstat_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "update.h"
+#include "random_mars.h"
+
+using namespace LAMMPS_NS;
+
+#define EPSILON 1.0e-10
+
+/* ---------------------------------------------------------------------- */
+
+PairDPDTstatOMP::PairDPDTstatOMP(LAMMPS *lmp) :
+ PairDPDTstat(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ random_thr = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairDPDTstatOMP::~PairDPDTstatOMP()
+{
+ if (random_thr) {
+ for (int i=1; i < comm->nthreads; ++i)
+ delete random_thr[i];
+
+ delete[] random_thr;
+ random_thr = NULL;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairDPDTstatOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ if (!random_thr)
+ random_thr = new RanMars*[nthreads];
+
+ random_thr[0] = random;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (random_thr && tid > 0)
+ random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me
+ + comm->nprocs*tid);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairDPDTstatOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
+ double rsq,r,rinv,dot,wd,randnum,factor_dpd;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double dtinvsqrt = 1.0/sqrt(update->dt);
+ double fxtmp,fytmp,fztmp;
+ RanMars &rng = *random_thr[tid];
+
+ // adjust sigma if target T is changing
+
+ if (t_start != t_stop) {
+ double delta = update->ntimestep - update->beginstep;
+ delta /= update->endstep - update->beginstep;
+ temperature = t_start + delta * (t_stop-t_start);
+ double boltz = force->boltz;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++)
+ sigma[i][j] = sigma[j][i] = sqrt(2.0*boltz*temperature*gamma[i][j]);
+ }
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ vxtmp = v[i][0];
+ vytmp = v[i][1];
+ vztmp = v[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_dpd = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ r = sqrt(rsq);
+ if (r < EPSILON) continue; // r can be 0.0 in DPD systems
+ rinv = 1.0/r;
+ delvx = vxtmp - v[j][0];
+ delvy = vytmp - v[j][1];
+ delvz = vztmp - v[j][2];
+ dot = delx*delvx + dely*delvy + delz*delvz;
+ wd = 1.0 - r/cut[itype][jtype];
+ randnum = rng.gaussian();
+
+ // drag force = -gamma * wd^2 * (delx dot delv) / r
+ // random force = sigma * wd * rnd * dtinvsqrt;
+
+ fpair = -gamma[itype][jtype]*wd*wd*dot*rinv;
+ fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt;
+ fpair *= factor_dpd*rinv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ 0.0,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairDPDTstatOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairDPDTstat::memory_usage();
+ bytes += comm->nthreads * sizeof(RanMars*);
+ bytes += comm->nthreads * sizeof(RanMars);
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_dpd_tstat_omp.h b/src/USER-OMP/pair_dpd_tstat_omp.h
new file mode 100644
index 0000000000..14f640a925
--- /dev/null
+++ b/src/USER-OMP/pair_dpd_tstat_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(dpd/tstat/omp,PairDPDTstatOMP)
+
+#else
+
+#ifndef LMP_PAIR_DPD_TSTAT_OMP_H
+#define LMP_PAIR_DPD_TSTAT_OMP_H
+
+#include "pair_dpd_tstat.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairDPDTstatOMP : public PairDPDTstat, public ThrOMP {
+
+ public:
+ PairDPDTstatOMP(class LAMMPS *);
+ virtual ~PairDPDTstatOMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ class RanMars **random_thr;
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_eam_alloy_omp.cpp b/src/USER-OMP/pair_eam_alloy_omp.cpp
new file mode 100644
index 0000000000..54be571b7f
--- /dev/null
+++ b/src/USER-OMP/pair_eam_alloy_omp.cpp
@@ -0,0 +1,323 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Stephen Foiles (SNL), Murray Daw (SNL)
+------------------------------------------------------------------------- */
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_eam_alloy_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+
+/* ---------------------------------------------------------------------- */
+
+PairEAMAlloyOMP::PairEAMAlloyOMP(LAMMPS *lmp) : PairEAMOMP(lmp)
+{
+ one_coeff = 1;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+ read DYNAMO setfl file
+------------------------------------------------------------------------- */
+
+void PairEAMAlloyOMP::coeff(int narg, char **arg)
+{
+ int i,j;
+
+ if (!allocated) allocate();
+
+ if (narg != 3 + atom->ntypes)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // insure I,J args are * *
+
+ if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // read EAM setfl file
+
+ if (setfl) {
+ for (i = 0; i < setfl->nelements; i++) delete [] setfl->elements[i];
+ delete [] setfl->elements;
+ delete [] setfl->mass;
+ memory->destroy(setfl->frho);
+ memory->destroy(setfl->rhor);
+ memory->destroy(setfl->z2r);
+ delete setfl;
+ }
+ setfl = new Setfl();
+ read_file(arg[2]);
+
+ // read args that map atom types to elements in potential file
+ // map[i] = which element the Ith atom type is, -1 if NULL
+
+ for (i = 3; i < narg; i++) {
+ if (strcmp(arg[i],"NULL") == 0) {
+ map[i-2] = -1;
+ continue;
+ }
+ for (j = 0; j < setfl->nelements; j++)
+ if (strcmp(arg[i],setfl->elements[j]) == 0) break;
+ if (j < setfl->nelements) map[i-2] = j;
+ else error->all(FLERR,"No matching element in EAM potential file");
+ }
+
+ // clear setflag since coeff() called once with I,J = * *
+
+ int n = atom->ntypes;
+ for (i = 1; i <= n; i++)
+ for (j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ // set setflag i,j for type pairs where both are mapped to elements
+ // set mass of atom type if i = j
+
+ int count = 0;
+ for (i = 1; i <= n; i++) {
+ for (j = i; j <= n; j++) {
+ if (map[i] >= 0 && map[j] >= 0) {
+ setflag[i][j] = 1;
+ if (i == j) atom->set_mass(i,setfl->mass[map[i]]);
+ count++;
+ }
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ read a multi-element DYNAMO setfl file
+------------------------------------------------------------------------- */
+
+void PairEAMAlloyOMP::read_file(char *filename)
+{
+ Setfl *file = setfl;
+
+ // open potential file
+
+ int me = comm->me;
+ FILE *fptr;
+ char line[MAXLINE];
+
+ if (me == 0) {
+ fptr = fopen(filename,"r");
+ if (fptr == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open EAM potential file %s",filename);
+ error->one(FLERR,str);
+ }
+ }
+
+ // read and broadcast header
+ // extract element names from nelements line
+
+ int n;
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ n = strlen(line) + 1;
+ }
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ sscanf(line,"%d",&file->nelements);
+ int nwords = atom->count_words(line);
+ if (nwords != file->nelements + 1)
+ error->all(FLERR,"Incorrect element names in EAM potential file");
+
+ char **words = new char*[file->nelements+1];
+ nwords = 0;
+ strtok(line," \t\n\r\f");
+ while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue;
+
+ file->elements = new char*[file->nelements];
+ for (int i = 0; i < file->nelements; i++) {
+ n = strlen(words[i]) + 1;
+ file->elements[i] = new char[n];
+ strcpy(file->elements[i],words[i]);
+ }
+ delete [] words;
+
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ sscanf(line,"%d %lg %d %lg %lg",
+ &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
+ }
+
+ MPI_Bcast(&file->nrho,1,MPI_INT,0,world);
+ MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&file->nr,1,MPI_INT,0,world);
+ MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world);
+
+ file->mass = new double[file->nelements];
+ memory->create(file->frho,file->nelements,file->nrho+1,"pair:frho");
+ memory->create(file->rhor,file->nelements,file->nr+1,"pair:rhor");
+ memory->create(file->z2r,file->nelements,file->nelements,file->nr+1,
+ "pair:z2r");
+
+ int i,j,tmp;
+ for (i = 0; i < file->nelements; i++) {
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ sscanf(line,"%d %lg",&tmp,&file->mass[i]);
+ }
+ MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);
+
+ if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
+ MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world);
+ if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]);
+ MPI_Bcast(&file->rhor[i][1],file->nr,MPI_DOUBLE,0,world);
+ }
+
+ for (i = 0; i < file->nelements; i++)
+ for (j = 0; j <= i; j++) {
+ if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
+ MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world);
+ }
+
+ // close the potential file
+
+ if (me == 0) fclose(fptr);
+}
+
+/* ----------------------------------------------------------------------
+ copy read-in setfl potential to standard array format
+------------------------------------------------------------------------- */
+
+void PairEAMAlloyOMP::file2array()
+{
+ int i,j,m,n;
+ int ntypes = atom->ntypes;
+
+ // set function params directly from setfl file
+
+ nrho = setfl->nrho;
+ nr = setfl->nr;
+ drho = setfl->drho;
+ dr = setfl->dr;
+
+ // ------------------------------------------------------------------
+ // setup frho arrays
+ // ------------------------------------------------------------------
+
+ // allocate frho arrays
+ // nfrho = # of setfl elements + 1 for zero array
+
+ nfrho = setfl->nelements + 1;
+ memory->destroy(frho);
+ memory->create(frho,nfrho,nrho+1,"pair:frho");
+
+ // copy each element's frho to global frho
+
+ for (i = 0; i < setfl->nelements; i++)
+ for (m = 1; m <= nrho; m++) frho[i][m] = setfl->frho[i][m];
+
+ // add extra frho of zeroes for non-EAM types to point to (pair hybrid)
+ // this is necessary b/c fp is still computed for non-EAM atoms
+
+ for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0;
+
+ // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to
+ // if atom type doesn't point to element (non-EAM atom in pair hybrid)
+ // then map it to last frho array of zeroes
+
+ for (i = 1; i <= ntypes; i++)
+ if (map[i] >= 0) type2frho[i] = map[i];
+ else type2frho[i] = nfrho-1;
+
+ // ------------------------------------------------------------------
+ // setup rhor arrays
+ // ------------------------------------------------------------------
+
+ // allocate rhor arrays
+ // nrhor = # of setfl elements
+
+ nrhor = setfl->nelements;
+ memory->destroy(rhor);
+ memory->create(rhor,nrhor,nr+1,"pair:rhor");
+
+ // copy each element's rhor to global rhor
+
+ for (i = 0; i < setfl->nelements; i++)
+ for (m = 1; m <= nr; m++) rhor[i][m] = setfl->rhor[i][m];
+
+ // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to
+ // for setfl files, I,J mapping only depends on I
+ // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used
+
+ for (i = 1; i <= ntypes; i++)
+ for (j = 1; j <= ntypes; j++)
+ type2rhor[i][j] = map[i];
+
+ // ------------------------------------------------------------------
+ // setup z2r arrays
+ // ------------------------------------------------------------------
+
+ // allocate z2r arrays
+ // nz2r = N*(N+1)/2 where N = # of setfl elements
+
+ nz2r = setfl->nelements * (setfl->nelements+1) / 2;
+ memory->destroy(z2r);
+ memory->create(z2r,nz2r,nr+1,"pair:z2r");
+
+ // copy each element pair z2r to global z2r, only for I >= J
+
+ n = 0;
+ for (i = 0; i < setfl->nelements; i++)
+ for (j = 0; j <= i; j++) {
+ for (m = 1; m <= nr; m++) z2r[n][m] = setfl->z2r[i][j][m];
+ n++;
+ }
+
+ // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to
+ // set of z2r arrays only fill lower triangular Nelement matrix
+ // value = n = sum over rows of lower-triangular matrix until reach irow,icol
+ // swap indices when irow < icol to stay lower triangular
+ // if map = -1 (non-EAM atom in pair hybrid):
+ // type2z2r is not used by non-opt
+ // but set type2z2r to 0 since accessed by opt
+
+ int irow,icol;
+ for (i = 1; i <= ntypes; i++) {
+ for (j = 1; j <= ntypes; j++) {
+ irow = map[i];
+ icol = map[j];
+ if (irow == -1 || icol == -1) {
+ type2z2r[i][j] = 0;
+ continue;
+ }
+ if (irow < icol) {
+ irow = map[j];
+ icol = map[i];
+ }
+ n = 0;
+ for (m = 0; m < irow; m++) n += m + 1;
+ n += icol;
+ type2z2r[i][j] = n;
+ }
+ }
+}
diff --git a/src/USER-OMP/pair_eam_alloy_omp.h b/src/USER-OMP/pair_eam_alloy_omp.h
new file mode 100644
index 0000000000..7a71fbc17a
--- /dev/null
+++ b/src/USER-OMP/pair_eam_alloy_omp.h
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(eam/alloy/omp,PairEAMAlloyOMP)
+
+#else
+
+#ifndef LMP_PAIR_EAM_ALLOY_OMP_H
+#define LMP_PAIR_EAM_ALLOY_OMP_H
+
+#include "pair_eam_omp.h"
+
+namespace LAMMPS_NS {
+
+// need virtual public b/c of how eam/alloy/opt inherits from it
+
+class PairEAMAlloyOMP : virtual public PairEAMOMP {
+ public:
+ PairEAMAlloyOMP(class LAMMPS *);
+ virtual ~PairEAMAlloyOMP() {}
+ void coeff(int, char **);
+
+ protected:
+ void read_file(char *);
+ void file2array();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_eam_fs_omp.cpp b/src/USER-OMP/pair_eam_fs_omp.cpp
new file mode 100644
index 0000000000..d0963fa621
--- /dev/null
+++ b/src/USER-OMP/pair_eam_fs_omp.cpp
@@ -0,0 +1,332 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Tim Lau (MIT)
+------------------------------------------------------------------------- */
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_eam_fs_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+
+/* ---------------------------------------------------------------------- */
+
+PairEAMFSOMP::PairEAMFSOMP(LAMMPS *lmp) : PairEAMOMP(lmp)
+{
+ one_coeff = 1;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+ read EAM Finnis-Sinclair file
+------------------------------------------------------------------------- */
+
+void PairEAMFSOMP::coeff(int narg, char **arg)
+{
+ int i,j;
+
+ if (!allocated) allocate();
+
+ if (narg != 3 + atom->ntypes)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // insure I,J args are * *
+
+ if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // read EAM Finnis-Sinclair file
+
+ if (fs) {
+ for (i = 0; i < fs->nelements; i++) delete [] fs->elements[i];
+ delete [] fs->elements;
+ delete [] fs->mass;
+ memory->destroy(fs->frho);
+ memory->destroy(fs->rhor);
+ memory->destroy(fs->z2r);
+ delete fs;
+ }
+ fs = new Fs();
+ read_file(arg[2]);
+
+ // read args that map atom types to elements in potential file
+ // map[i] = which element the Ith atom type is, -1 if NULL
+
+ for (i = 3; i < narg; i++) {
+ if (strcmp(arg[i],"NULL") == 0) {
+ map[i-2] = -1;
+ continue;
+ }
+ for (j = 0; j < fs->nelements; j++)
+ if (strcmp(arg[i],fs->elements[j]) == 0) break;
+ if (j < fs->nelements) map[i-2] = j;
+ else error->all(FLERR,"No matching element in EAM potential file");
+ }
+
+ // clear setflag since coeff() called once with I,J = * *
+
+ int n = atom->ntypes;
+ for (i = 1; i <= n; i++)
+ for (j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ // set setflag i,j for type pairs where both are mapped to elements
+ // set mass of atom type if i = j
+
+ int count = 0;
+ for (i = 1; i <= n; i++) {
+ for (j = i; j <= n; j++) {
+ if (map[i] >= 0 && map[j] >= 0) {
+ setflag[i][j] = 1;
+ if (i == j) atom->set_mass(i,fs->mass[map[i]]);
+ count++;
+ }
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ read a multi-element DYNAMO setfl file
+------------------------------------------------------------------------- */
+
+void PairEAMFSOMP::read_file(char *filename)
+{
+ Fs *file = fs;
+
+ // open potential file
+
+ int me = comm->me;
+ FILE *fptr;
+ char line[MAXLINE];
+
+ if (me == 0) {
+ fptr = fopen(filename,"r");
+ if (fptr == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open EAM potential file %s",filename);
+ error->one(FLERR,str);
+ }
+ }
+
+ // read and broadcast header
+ // extract element names from nelements line
+
+ int n;
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ fgets(line,MAXLINE,fptr);
+ n = strlen(line) + 1;
+ }
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ sscanf(line,"%d",&file->nelements);
+ int nwords = atom->count_words(line);
+ if (nwords != file->nelements + 1)
+ error->all(FLERR,"Incorrect element names in EAM potential file");
+
+ char **words = new char*[file->nelements+1];
+ nwords = 0;
+ strtok(line," \t\n\r\f");
+ while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue;
+
+ file->elements = new char*[file->nelements];
+ for (int i = 0; i < file->nelements; i++) {
+ n = strlen(words[i]) + 1;
+ file->elements[i] = new char[n];
+ strcpy(file->elements[i],words[i]);
+ }
+ delete [] words;
+
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ sscanf(line,"%d %lg %d %lg %lg",
+ &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
+ }
+
+ MPI_Bcast(&file->nrho,1,MPI_INT,0,world);
+ MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&file->nr,1,MPI_INT,0,world);
+ MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world);
+
+ file->mass = new double[file->nelements];
+ memory->create(file->frho,file->nelements,file->nrho+1,
+ "pair:frho");
+ memory->create(file->rhor,file->nelements,file->nelements,
+ file->nr+1,"pair:rhor");
+ memory->create(file->z2r,file->nelements,file->nelements,
+ file->nr+1,"pair:z2r");
+
+ int i,j,tmp;
+ for (i = 0; i < file->nelements; i++) {
+ if (me == 0) {
+ fgets(line,MAXLINE,fptr);
+ sscanf(line,"%d %lg",&tmp,&file->mass[i]);
+ }
+ MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);
+
+ if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
+ MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world);
+
+ for (j = 0; j < file->nelements; j++) {
+ if (me == 0) grab(fptr,file->nr,&file->rhor[i][j][1]);
+ MPI_Bcast(&file->rhor[i][j][1],file->nr,MPI_DOUBLE,0,world);
+ }
+ }
+
+ for (i = 0; i < file->nelements; i++)
+ for (j = 0; j <= i; j++) {
+ if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
+ MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world);
+ }
+
+ // close the potential file
+
+ if (me == 0) fclose(fptr);
+}
+
+/* ----------------------------------------------------------------------
+ copy read-in setfl potential to standard array format
+------------------------------------------------------------------------- */
+
+void PairEAMFSOMP::file2array()
+{
+ int i,j,m,n;
+ int ntypes = atom->ntypes;
+
+ // set function params directly from fs file
+
+ nrho = fs->nrho;
+ nr = fs->nr;
+ drho = fs->drho;
+ dr = fs->dr;
+
+ // ------------------------------------------------------------------
+ // setup frho arrays
+ // ------------------------------------------------------------------
+
+ // allocate frho arrays
+ // nfrho = # of fs elements + 1 for zero array
+
+ nfrho = fs->nelements + 1;
+ memory->destroy(frho);
+ memory->create(frho,nfrho,nrho+1,"pair:frho");
+
+ // copy each element's frho to global frho
+
+ for (i = 0; i < fs->nelements; i++)
+ for (m = 1; m <= nrho; m++) frho[i][m] = fs->frho[i][m];
+
+ // add extra frho of zeroes for non-EAM types to point to (pair hybrid)
+ // this is necessary b/c fp is still computed for non-EAM atoms
+
+ for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0;
+
+ // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to
+ // if atom type doesn't point to element (non-EAM atom in pair hybrid)
+ // then map it to last frho array of zeroes
+
+ for (i = 1; i <= ntypes; i++)
+ if (map[i] >= 0) type2frho[i] = map[i];
+ else type2frho[i] = nfrho-1;
+
+ // ------------------------------------------------------------------
+ // setup rhor arrays
+ // ------------------------------------------------------------------
+
+ // allocate rhor arrays
+ // nrhor = square of # of fs elements
+
+ nrhor = fs->nelements * fs->nelements;
+ memory->destroy(rhor);
+ memory->create(rhor,nrhor,nr+1,"pair:rhor");
+
+ // copy each element pair rhor to global rhor
+
+ n = 0;
+ for (i = 0; i < fs->nelements; i++)
+ for (j = 0; j < fs->nelements; j++) {
+ for (m = 1; m <= nr; m++) rhor[n][m] = fs->rhor[i][j][m];
+ n++;
+ }
+
+ // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to
+ // for fs files, there is a full NxN set of rhor arrays
+ // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used
+
+ for (i = 1; i <= ntypes; i++)
+ for (j = 1; j <= ntypes; j++)
+ type2rhor[i][j] = map[i] * fs->nelements + map[j];
+
+ // ------------------------------------------------------------------
+ // setup z2r arrays
+ // ------------------------------------------------------------------
+
+ // allocate z2r arrays
+ // nz2r = N*(N+1)/2 where N = # of fs elements
+
+ nz2r = fs->nelements * (fs->nelements+1) / 2;
+ memory->destroy(z2r);
+ memory->create(z2r,nz2r,nr+1,"pair:z2r");
+
+ // copy each element pair z2r to global z2r, only for I >= J
+
+ n = 0;
+ for (i = 0; i < fs->nelements; i++)
+ for (j = 0; j <= i; j++) {
+ for (m = 1; m <= nr; m++) z2r[n][m] = fs->z2r[i][j][m];
+ n++;
+ }
+
+ // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to
+ // set of z2r arrays only fill lower triangular Nelement matrix
+ // value = n = sum over rows of lower-triangular matrix until reach irow,icol
+ // swap indices when irow < icol to stay lower triangular
+ // if map = -1 (non-EAM atom in pair hybrid):
+ // type2z2r is not used by non-opt
+ // but set type2z2r to 0 since accessed by opt
+
+ int irow,icol;
+ for (i = 1; i <= ntypes; i++) {
+ for (j = 1; j <= ntypes; j++) {
+ irow = map[i];
+ icol = map[j];
+ if (irow == -1 || icol == -1) {
+ type2z2r[i][j] = 0;
+ continue;
+ }
+ if (irow < icol) {
+ irow = map[j];
+ icol = map[i];
+ }
+ n = 0;
+ for (m = 0; m < irow; m++) n += m + 1;
+ n += icol;
+ type2z2r[i][j] = n;
+ }
+ }
+}
diff --git a/src/USER-OMP/pair_eam_fs_omp.h b/src/USER-OMP/pair_eam_fs_omp.h
new file mode 100644
index 0000000000..bee6cef762
--- /dev/null
+++ b/src/USER-OMP/pair_eam_fs_omp.h
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(eam/fs/omp,PairEAMFSOMP)
+
+#else
+
+#ifndef LMP_PAIR_EAM_FS_OMP_H
+#define LMP_PAIR_EAM_FS_OMP_H
+
+#include "pair_eam_omp.h"
+
+namespace LAMMPS_NS {
+
+// need virtual public b/c of how eam/fs/opt inherits from it
+
+class PairEAMFSOMP : virtual public PairEAMOMP {
+ public:
+ PairEAMFSOMP(class LAMMPS *);
+ virtual ~PairEAMFSOMP() {}
+ void coeff(int, char **);
+
+ protected:
+ void read_file(char *);
+ void file2array();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_eam_omp.cpp b/src/USER-OMP/pair_eam_omp.cpp
new file mode 100644
index 0000000000..0ae4d54fb7
--- /dev/null
+++ b/src/USER-OMP/pair_eam_omp.cpp
@@ -0,0 +1,303 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "string.h"
+
+#include "pair_eam_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairEAMOMP::PairEAMOMP(LAMMPS *lmp) :
+ PairEAM(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairEAMOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow energy and fp arrays if necessary
+ // need to be atom->nmax in length
+
+ if (atom->nmax > nmax) {
+ memory->destroy(rho);
+ memory->destroy(fp);
+ nmax = atom->nmax;
+ memory->create(rho,nthreads*nmax,"pair:rho");
+ memory->create(fp,nmax,"pair:fp");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, *rho_t;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ if (force->newton_pair)
+ rho_t = rho + tid*nall;
+ else rho_t = rho + tid*atom->nlocal;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, rho_t, ifrom, ito, tid);
+ else eval<1,1,0>(f, rho_t, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, rho_t, ifrom, ito, tid);
+ else eval<1,0,0>(f, rho_t, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, rho_t, ifrom, ito, tid);
+ else eval<0,0,0>(f, rho_t, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairEAMOMP::eval(double **f, double *rho_t,
+ int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,m,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi;
+ double *coeff;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // zero out density
+
+ if (NEWTON_PAIR) memset(rho_t, 0, nall*sizeof(double));
+ else memset(rho_t, 0, nlocal*sizeof(double));
+
+ // rho = density at each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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);
+ coeff = rhor_spline[type2rhor[jtype][itype]][m];
+ rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ if (NEWTON_PAIR || j < nlocal) {
+ coeff = rhor_spline[type2rhor[itype][jtype]][m];
+ rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ }
+ }
+ }
+ }
+
+ // wait until all threads are done with computation
+ sync_threads();
+
+ // communicate and sum densities
+
+ if (NEWTON_PAIR) {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { comm->reverse_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ } else {
+ data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+ // fp = derivative of embedding energy at each atom
+ // phi = embedding energy at each atom
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ p = rho[i]*rdrho + 1.0;
+ m = static_cast (p);
+ m = MAX(1,MIN(m,nrho-1));
+ p -= m;
+ p = MIN(p,1.0);
+ coeff = frho_spline[type2frho[type[i]]][m];
+ fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
+ if (EFLAG) {
+ phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ if (eflag_global) eng_vdwl_thr[tid] += phi;
+ if (eflag_atom) eatom_thr[tid][i] += phi;
+ }
+ }
+
+ // wait until all theads are done with computation
+ sync_threads();
+
+ // communicate derivative of embedding function
+ // MPI communication only on master thread
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { comm->forward_comm_pair(this); }
+
+ // wait until master thread is done with communication
+ sync_threads();
+
+ // compute forces on each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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
+
+ coeff = rhor_spline[type2rhor[itype][jtype]][m];
+ rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = rhor_spline[type2rhor[jtype][itype]][m];
+ rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = z2r_spline[type2z2r[itype][jtype]][m];
+ z2p = (coeff[0]*p + coeff[1])*p + coeff[2];
+ z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+
+ recip = 1.0/r;
+ phi = z2*recip;
+ phip = z2p*recip - phi*recip;
+ psip = fp[i]*rhojp + fp[j]*rhoip + phip;
+ fpair = -psip*recip;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl = phi;
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairEAMOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairEAM::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_eam_omp.h b/src/USER-OMP/pair_eam_omp.h
new file mode 100644
index 0000000000..1184cb34bc
--- /dev/null
+++ b/src/USER-OMP/pair_eam_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(eam/omp,PairEAMOMP)
+
+#else
+
+#ifndef LMP_PAIR_EAM_OMP_H
+#define LMP_PAIR_EAM_OMP_H
+
+#include "pair_eam.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairEAMOMP : public PairEAM, public ThrOMP {
+
+ public:
+ PairEAMOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double *rho_t, int iifrom, int iito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_edip_omp.cpp b/src/USER-OMP/pair_edip_omp.cpp
new file mode 100644
index 0000000000..65b05c8143
--- /dev/null
+++ b/src/USER-OMP/pair_edip_omp.cpp
@@ -0,0 +1,485 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_edip_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairEDIPOMP::PairEDIPOMP(LAMMPS *lmp) :
+ PairEDIP(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairEDIPOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else eval<0,0,0>(f, ifrom, ito, tid);
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairEDIPOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,ii,inum,jnum;
+ int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+ double xtmp,ytmp,ztmp,evdwl;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ register int preForceCoord_counter;
+
+ double invR_ij;
+ double invR_ik;
+ double directorCos_ij_x;
+ double directorCos_ij_y;
+ double directorCos_ij_z;
+ double directorCos_ik_x;
+ double directorCos_ik_y;
+ double directorCos_ik_z;
+ double cosTeta;
+
+ int interpolIDX;
+ double interpolTMP;
+ double interpolDeltaX;
+ double interpolY1;
+ double interpolY2;
+
+ double invRMinusCutoffA;
+ double sigmaInvRMinusCutoffA;
+ double gammInvRMinusCutoffA;
+ double cosTetaDiff;
+ double cosTetaDiffCosTetaDiff;
+ double cutoffFunction_ij;
+ double exp2B_ij;
+ double exp2BDerived_ij;
+ double pow2B_ij;
+ double pow2BDerived_ij;
+ double exp3B_ij;
+ double exp3BDerived_ij;
+ double exp3B_ik;
+ double exp3BDerived_ik;
+ double qFunction;
+ double qFunctionDerived;
+ double tauFunction;
+ double tauFunctionDerived;
+ double expMinusBetaZeta_iZeta_i;
+ double qFunctionCosTetaDiffCosTetaDiff;
+ double expMinusQFunctionCosTetaDiffCosTetaDiff;
+ double zeta_i;
+ double zeta_iDerived;
+ double zeta_iDerivedInvR_ij;
+
+ double forceModCoord_factor;
+ double forceModCoord;
+ double forceModCoord_ij;
+ double forceMod2B;
+ double forceMod3B_factor1_ij;
+ double forceMod3B_factor2_ij;
+ double forceMod3B_factor2;
+ double forceMod3B_factor1_ik;
+ double forceMod3B_factor2_ik;
+ double potentia3B_factor;
+ double potential2B_factor;
+
+ double *pre_thrInvR_ij = preInvR_ij + tid * leadDimInteractionList;
+ double *pre_thrExp3B_ij = preExp3B_ij + tid * leadDimInteractionList;
+ double *pre_thrExp3BDerived_ij = preExp3BDerived_ij + tid * leadDimInteractionList;
+ double *pre_thrExp2B_ij = preExp2B_ij + tid * leadDimInteractionList;
+ double *pre_thrExp2BDerived_ij = preExp2BDerived_ij + tid * leadDimInteractionList;
+ double *pre_thrPow2B_ij = prePow2B_ij + tid * leadDimInteractionList;
+ double *pre_thrForceCoord = preForceCoord + tid * leadDimInteractionList;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over full neighbor list of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ zeta_i = 0.0;
+ int numForceCoordPairs = 0;
+
+ i = ilist[ii];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ // pre-loop to compute environment coordination f(Z)
+
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ double dr_ij[3], r_ij;
+
+ dr_ij[0] = xtmp - x[j][0];
+ dr_ij[1] = ytmp - x[j][1];
+ dr_ij[2] = ztmp - x[j][2];
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+
+ invR_ij = 1.0 / r_ij;
+ pre_thrInvR_ij[neighbor_j] = invR_ij;
+
+ invRMinusCutoffA = 1.0 / (r_ij - cutoffA);
+ sigmaInvRMinusCutoffA = sigma * invRMinusCutoffA;
+ gammInvRMinusCutoffA = gamm * invRMinusCutoffA;
+
+ interpolDeltaX = r_ij - GRIDSTART;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY);
+ interpolIDX = (int) interpolTMP;
+
+ interpolY1 = exp3B[interpolIDX];
+ interpolY2 = exp3B[interpolIDX+1];
+ exp3B_ij = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ exp3BDerived_ij = - exp3B_ij * gammInvRMinusCutoffA * invRMinusCutoffA;
+
+ pre_thrExp3B_ij[neighbor_j] = exp3B_ij;
+ pre_thrExp3BDerived_ij[neighbor_j] = exp3BDerived_ij;
+
+ interpolY1 = exp2B[interpolIDX];
+ interpolY2 = exp2B[interpolIDX+1];
+ exp2B_ij = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ exp2BDerived_ij = - exp2B_ij * sigmaInvRMinusCutoffA * invRMinusCutoffA;
+
+ pre_thrExp2B_ij[neighbor_j] = exp2B_ij;
+ pre_thrExp2BDerived_ij[neighbor_j] = exp2BDerived_ij;
+
+ interpolY1 = pow2B[interpolIDX];
+ interpolY2 = pow2B[interpolIDX+1];
+ pow2B_ij = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ pre_thrPow2B_ij[neighbor_j] = pow2B_ij;
+
+ // zeta and its derivative
+
+ if (r_ij < cutoffC) zeta_i += 1.0;
+ else {
+ interpolY1 = cutoffFunction[interpolIDX];
+ interpolY2 = cutoffFunction[interpolIDX+1];
+ cutoffFunction_ij = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ zeta_i += cutoffFunction_ij;
+
+ interpolY1 = cutoffFunctionDerived[interpolIDX];
+ interpolY2 = cutoffFunctionDerived[interpolIDX+1];
+ zeta_iDerived = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ zeta_iDerivedInvR_ij = zeta_iDerived * invR_ij;
+
+ preForceCoord_counter=numForceCoordPairs*5;
+ pre_thrForceCoord[preForceCoord_counter+0]=zeta_iDerivedInvR_ij;
+ pre_thrForceCoord[preForceCoord_counter+1]=dr_ij[0];
+ pre_thrForceCoord[preForceCoord_counter+2]=dr_ij[1];
+ pre_thrForceCoord[preForceCoord_counter+3]=dr_ij[2];
+ pre_thrForceCoord[preForceCoord_counter+4]=j;
+ numForceCoordPairs++;
+ }
+ }
+
+ // quantities depending on zeta_i
+
+ interpolDeltaX = zeta_i;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY);
+ interpolIDX = (int) interpolTMP;
+
+ interpolY1 = expMinusBetaZeta_iZeta_iGrid[interpolIDX];
+ interpolY2 = expMinusBetaZeta_iZeta_iGrid[interpolIDX+1];
+ expMinusBetaZeta_iZeta_i = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ interpolY1 = qFunctionGrid[interpolIDX];
+ interpolY2 = qFunctionGrid[interpolIDX+1];
+ qFunction = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ interpolY1 = tauFunctionGrid[interpolIDX];
+ interpolY2 = tauFunctionGrid[interpolIDX+1];
+ tauFunction = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ interpolY1 = tauFunctionDerivedGrid[interpolIDX];
+ interpolY2 = tauFunctionDerivedGrid[interpolIDX+1];
+ tauFunctionDerived = interpolY1 + (interpolY2 - interpolY1) *
+ (interpolTMP-interpolIDX);
+
+ qFunctionDerived = -mu * qFunction;
+
+ forceModCoord_factor = 2.0 * beta * zeta_i * expMinusBetaZeta_iZeta_i;
+
+ forceModCoord = 0.0;
+
+ // two-body interactions, skip half of them
+
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+ double dr_ij[3], r_ij, f_ij[3];
+
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ dr_ij[0] = x[j][0] - xtmp;
+ dr_ij[1] = x[j][1] - ytmp;
+ dr_ij[2] = x[j][2] - ztmp;
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+
+ invR_ij = pre_thrInvR_ij[neighbor_j];
+ pow2B_ij = pre_thrPow2B_ij[neighbor_j];
+
+ potential2B_factor = pow2B_ij - expMinusBetaZeta_iZeta_i;
+
+ exp2B_ij = pre_thrExp2B_ij[neighbor_j];
+
+ pow2BDerived_ij = - rho * invR_ij * pow2B_ij;
+
+ forceModCoord += (forceModCoord_factor*exp2B_ij);
+
+ exp2BDerived_ij = pre_thrExp2BDerived_ij[neighbor_j];
+ forceMod2B = exp2BDerived_ij * potential2B_factor +
+ exp2B_ij * pow2BDerived_ij;
+
+ directorCos_ij_x = invR_ij * dr_ij[0];
+ directorCos_ij_y = invR_ij * dr_ij[1];
+ directorCos_ij_z = invR_ij * dr_ij[2];
+
+ exp3B_ij = pre_thrExp3B_ij[neighbor_j];
+ exp3BDerived_ij = pre_thrExp3BDerived_ij[neighbor_j];
+
+ f_ij[0] = forceMod2B * directorCos_ij_x;
+ f_ij[1] = forceMod2B * directorCos_ij_y;
+ f_ij[2] = forceMod2B * directorCos_ij_z;
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[i][0] += f_ij[0];
+ f[i][1] += f_ij[1];
+ f[i][2] += f_ij[2];
+
+ // potential energy
+
+ evdwl = (exp2B_ij * potential2B_factor);
+
+ if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, evdwl, 0.0,
+ -forceMod2B*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid);
+
+ // three-body Forces
+
+ for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik, f_ik[3];
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = x[k][0] - xtmp;
+ dr_ik[1] = x[k][1] - ytmp;
+ dr_ik[2] = x[k][2] - ztmp;
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+
+ invR_ik = pre_thrInvR_ij[neighbor_k];
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x +
+ directorCos_ij_y * directorCos_ik_y +
+ directorCos_ij_z * directorCos_ik_z;
+
+ cosTetaDiff = cosTeta + tauFunction;
+ cosTetaDiffCosTetaDiff = cosTetaDiff * cosTetaDiff;
+ qFunctionCosTetaDiffCosTetaDiff = cosTetaDiffCosTetaDiff * qFunction;
+ expMinusQFunctionCosTetaDiffCosTetaDiff =
+ exp(-qFunctionCosTetaDiffCosTetaDiff);
+
+ potentia3B_factor = lambda *
+ ((1.0 - expMinusQFunctionCosTetaDiffCosTetaDiff) +
+ eta * qFunctionCosTetaDiffCosTetaDiff);
+
+ exp3B_ik = pre_thrExp3B_ij[neighbor_k];
+ exp3BDerived_ik = pre_thrExp3BDerived_ij[neighbor_k];
+
+ forceMod3B_factor1_ij = - exp3BDerived_ij * exp3B_ik *
+ potentia3B_factor;
+ forceMod3B_factor2 = 2.0 * lambda * exp3B_ij * exp3B_ik *
+ qFunction * cosTetaDiff *
+ (eta + expMinusQFunctionCosTetaDiffCosTetaDiff);
+ forceMod3B_factor2_ij = forceMod3B_factor2 * invR_ij;
+
+ f_ij[0] = forceMod3B_factor1_ij * directorCos_ij_x +
+ forceMod3B_factor2_ij *
+ (cosTeta * directorCos_ij_x - directorCos_ik_x);
+ f_ij[1] = forceMod3B_factor1_ij * directorCos_ij_y +
+ forceMod3B_factor2_ij *
+ (cosTeta * directorCos_ij_y - directorCos_ik_y);
+ f_ij[2] = forceMod3B_factor1_ij * directorCos_ij_z +
+ forceMod3B_factor2_ij *
+ (cosTeta * directorCos_ij_z - directorCos_ik_z);
+
+ forceMod3B_factor1_ik = - exp3BDerived_ik * exp3B_ij *
+ potentia3B_factor;
+ forceMod3B_factor2_ik = forceMod3B_factor2 * invR_ik;
+
+ f_ik[0] = forceMod3B_factor1_ik * directorCos_ik_x +
+ forceMod3B_factor2_ik *
+ (cosTeta * directorCos_ik_x - directorCos_ij_x);
+ f_ik[1] = forceMod3B_factor1_ik * directorCos_ik_y +
+ forceMod3B_factor2_ik *
+ (cosTeta * directorCos_ik_y - directorCos_ij_y);
+ f_ik[2] = forceMod3B_factor1_ik * directorCos_ik_z +
+ forceMod3B_factor2_ik *
+ (cosTeta * directorCos_ik_z - directorCos_ij_z);
+
+ forceModCoord += (forceMod3B_factor2 *
+ (tauFunctionDerived - 0.5 * mu * cosTetaDiff));
+
+ f[j][0] += f_ij[0];
+ f[j][1] += f_ij[1];
+ f[j][2] += f_ij[2];
+
+ f[k][0] += f_ik[0];
+ f[k][1] += f_ik[1];
+ f[k][2] += f_ik[2];
+
+ f[i][0] -= f_ij[0] + f_ik[0];
+ f[i][1] -= f_ij[1] + f_ik[1];
+ f[i][2] -= f_ij[2] + f_ik[2];
+
+ // potential energy
+
+ evdwl = (exp3B_ij * exp3B_ik * potentia3B_factor);
+
+ if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik);
+ }
+ }
+
+ // forces due to environment coordination f(Z)
+
+ for (int idx = 0; idx < numForceCoordPairs; idx++) {
+ double dr_ij[3], f_ij[3];
+
+ preForceCoord_counter = idx * 5;
+ zeta_iDerivedInvR_ij=pre_thrForceCoord[preForceCoord_counter+0];
+ dr_ij[0]=pre_thrForceCoord[preForceCoord_counter+1];
+ dr_ij[1]=pre_thrForceCoord[preForceCoord_counter+2];
+ dr_ij[2]=pre_thrForceCoord[preForceCoord_counter+3];
+ j = static_cast (pre_thrForceCoord[preForceCoord_counter+4]);
+
+ forceModCoord_ij = forceModCoord * zeta_iDerivedInvR_ij;
+
+ f_ij[0] = forceModCoord_ij * dr_ij[0];
+ f_ij[1] = forceModCoord_ij * dr_ij[1];
+ f_ij[2] = forceModCoord_ij * dr_ij[2];
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[i][0] += f_ij[0];
+ f[i][1] += f_ij[1];
+ f[i][2] += f_ij[2];
+
+ // potential energy
+
+ evdwl = 0.0;
+ if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, 0.0, 0.0,
+ forceModCoord_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairEDIPOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairEDIP::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_edip_omp.h b/src/USER-OMP/pair_edip_omp.h
new file mode 100644
index 0000000000..55c34db345
--- /dev/null
+++ b/src/USER-OMP/pair_edip_omp.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(edip/omp,PairEDIPOMP)
+
+#else
+
+#ifndef LMP_PAIR_EDIP_OMP_H
+#define LMP_PAIR_EDIP_OMP_H
+
+#include "pair_edip.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairEDIPOMP : public PairEDIP, public ThrOMP {
+
+ public:
+ PairEDIPOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_eim_omp.cpp b/src/USER-OMP/pair_eim_omp.cpp
new file mode 100644
index 0000000000..d31ad20120
--- /dev/null
+++ b/src/USER-OMP/pair_eim_omp.cpp
@@ -0,0 +1,365 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "string.h"
+
+#include "pair_eim_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairEIMOMP::PairEIMOMP(LAMMPS *lmp) :
+ PairEIM(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairEIMOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow energy and fp arrays if necessary
+ // need to be atom->nmax in length
+
+ if (atom->nmax > nmax) {
+ memory->destroy(rho);
+ memory->destroy(fp);
+ nmax = atom->nmax;
+ memory->create(rho,nthreads*nmax,"pair:rho");
+ memory->create(fp,nthreads*nmax,"pair:fp");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, *rho_t, *fp_t;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ if (force->newton_pair) {
+ rho_t = rho + tid*nall;
+ fp_t = fp + tid*nall;
+ } else {
+ rho_t = rho + tid*atom->nlocal;
+ fp_t = fp + tid*atom->nlocal;
+ }
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, rho_t, fp_t, ifrom, ito, tid);
+ else eval<1,1,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, rho_t, fp_t, ifrom, ito, tid);
+ else eval<1,0,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, rho_t, fp_t, ifrom, ito, tid);
+ else eval<0,0,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairEIMOMP::eval(double **f, double *rho_t, double *fp_t,
+ int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,m,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,p,rhoip,rhojp,phip,phi,coul,coulp,recip,psip;
+ double *coeff;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // zero out density and fp
+
+ if (NEWTON_PAIR) {
+ memset(rho_t, 0, nall*sizeof(double));
+ memset(fp_t, 0, nall*sizeof(double));
+ } else {
+ memset(rho_t, 0, nlocal*sizeof(double));
+ memset(fp_t, 0, nlocal*sizeof(double));
+ }
+
+ // rho = density at each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+ 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[itype][jtype]) {
+ p = sqrt(rsq)*rdr + 1.0;
+ m = static_cast (p);
+ m = MIN(m,nr-1);
+ p -= m;
+ p = MIN(p,1.0);
+ coeff = Fij_spline[type2Fij[itype][jtype]][m];
+ rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ if (NEWTON_PAIR || j < nlocal) {
+ coeff = Fij_spline[type2Fij[jtype][itype]][m];
+ rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ }
+ }
+ }
+ }
+
+ // wait until all threads are done with computation
+ sync_threads();
+
+ // communicate and sum densities
+ if (NEWTON_PAIR) {
+ // reduce per thread density
+ data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ {
+ rhofp = 1;
+ comm->reverse_comm_pair(this);
+ }
+
+ } else {
+ data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ {
+ rhofp = 1;
+ comm->forward_comm_pair(this);
+ }
+
+ // wait until master is finished communicating
+ sync_threads();
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+
+ 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[itype][jtype]) {
+ p = sqrt(rsq)*rdr + 1.0;
+ m = static_cast (p);
+ m = MIN(m,nr-1);
+ p -= m;
+ p = MIN(p,1.0);
+ coeff = Gij_spline[type2Gij[itype][jtype]][m];
+ fp_t[i] += rho[j]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]);
+ if (NEWTON_PAIR || j < nlocal) {
+ fp_t[j] += rho[i]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p +
+ coeff[6]);
+ }
+ }
+ }
+ }
+
+ // wait until all threads are done with computation
+ sync_threads();
+
+ // communicate and sum modified densities
+ if (NEWTON_PAIR) {
+ // reduce per thread density
+ data_reduce_thr(&(fp[0]), nall, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ {
+ rhofp = 2;
+ comm->reverse_comm_pair(this);
+ }
+
+ } else {
+ data_reduce_thr(&(fp[0]), nlocal, comm->nthreads, 1, tid);
+
+ // wait until reduction is complete
+ sync_threads();
+ }
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ {
+ rhofp = 2;
+ comm->forward_comm_pair(this);
+ }
+
+ // wait until master is finished communicating
+ sync_threads();
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ itype = type[i];
+ if (EFLAG) {
+ phi = 0.5*rho[i]*fp[i];
+ if (eflag_global) eng_vdwl_thr[tid] += phi;
+ if (eflag_atom) eatom_thr[tid][i] += phi;
+ }
+ }
+
+ // compute forces on each atom
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+ 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[itype][jtype]) {
+ 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'
+
+ coeff = Fij_spline[type2Fij[jtype][itype]][m];
+ rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = Fij_spline[type2Fij[itype][jtype]][m];
+ rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = phiij_spline[type2phiij[itype][jtype]][m];
+ phip = (coeff[0]*p + coeff[1])*p + coeff[2];
+ phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coeff = Gij_spline[type2Gij[itype][jtype]][m];
+ coul = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+ coulp = (coeff[0]*p + coeff[1])*p + coeff[2];
+ psip = phip + (rho[i]*rho[j]-q0[itype]*q0[jtype])*coulp +
+ fp[i]*rhojp + fp[j]*rhoip;
+ recip = 1.0/r;
+ fpair = -psip*recip;
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl = phi-q0[itype]*q0[jtype]*coul;
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairEIMOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairEIM::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_eim_omp.h b/src/USER-OMP/pair_eim_omp.h
new file mode 100644
index 0000000000..3693492e09
--- /dev/null
+++ b/src/USER-OMP/pair_eim_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(eim/omp,PairEIMOMP)
+
+#else
+
+#ifndef LMP_PAIR_EIM_OMP_H
+#define LMP_PAIR_EIM_OMP_H
+
+#include "pair_eim.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairEIMOMP : public PairEIM, public ThrOMP {
+
+ public:
+ PairEIMOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double *rho_t, double *fp_t, int iifrom, int iito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_gauss_omp.cpp b/src/USER-OMP/pair_gauss_omp.cpp
new file mode 100644
index 0000000000..e8b255d0b7
--- /dev/null
+++ b/src/USER-OMP/pair_gauss_omp.cpp
@@ -0,0 +1,170 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_gauss_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#define EPSILON 1.0e-10
+/* ---------------------------------------------------------------------- */
+
+PairGaussOMP::PairGaussOMP(LAMMPS *lmp) :
+ PairGauss(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGaussOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairGaussOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double r,rsq,r2inv,forcelj,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int occ = 0;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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];
+
+ // define a Gaussian well to be occupied if
+ // the site it interacts with is within the force maximum
+
+ if (EFLAG)
+ if (eflag_global && rsq < 0.5/b[itype][jtype]) occ++;
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ r = sqrt(rsq);
+ forcelj = - 2.0*a[itype][jtype]*b[itype][jtype] * rsq *
+ exp(-b[itype][jtype]*rsq);
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = -(a[itype][jtype]*exp(-b[itype][jtype]*rsq) -
+ offset[itype][jtype]);
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+ if (eflag_global) pvector[0] = occ;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGaussOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairGauss::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_gauss_omp.h b/src/USER-OMP/pair_gauss_omp.h
new file mode 100644
index 0000000000..7f8fc9a85b
--- /dev/null
+++ b/src/USER-OMP/pair_gauss_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(gauss/omp,PairGaussOMP)
+
+#else
+
+#ifndef LMP_PAIR_GAUSS_OMP_H
+#define LMP_PAIR_GAUSS_OMP_H
+
+#include "pair_gauss.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairGaussOMP : public PairGauss, public ThrOMP {
+
+ public:
+ PairGaussOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_gayberne_omp.cpp b/src/USER-OMP/pair_gayberne_omp.cpp
new file mode 100644
index 0000000000..ff115e8ef7
--- /dev/null
+++ b/src/USER-OMP/pair_gayberne_omp.cpp
@@ -0,0 +1,227 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_gayberne_omp.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "comm.h"
+#include "atom_vec_ellipsoid.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairGayBerneOMP::PairGayBerneOMP(LAMMPS *lmp) :
+ PairGayBerne(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGayBerneOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces and torques into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairGayBerneOMP::eval(double **f, double **tor, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
+ double fforce[3],ttor[3],rtor[3],r12[3];
+ double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double *iquat,*jquat;
+
+ double **x = atom->x;
+ int *ellipsoid = atom->ellipsoid;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+
+ AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+
+ double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itype = type[i];
+
+ if (form[itype][itype] == ELLIPSE_ELLIPSE) {
+ iquat = bonus[ellipsoid[i]].quat;
+ MathExtra::quat_to_mat_trans(iquat,a1);
+ MathExtra::diag_times3(well[itype],a1,temp);
+ MathExtra::transpose_times3(a1,temp,b1);
+ MathExtra::diag_times3(shape2[itype],a1,temp);
+ MathExtra::transpose_times3(a1,temp,g1);
+ }
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ // r12 = center to center vector
+
+ r12[0] = x[j][0]-x[i][0];
+ r12[1] = x[j][1]-x[i][1];
+ r12[2] = x[j][2]-x[i][2];
+ rsq = MathExtra::dot3(r12,r12);
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+
+ switch (form[itype][jtype]) {
+ case SPHERE_SPHERE:
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ forcelj *= -r2inv;
+ if (EFLAG)
+ one_eng = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ fforce[0] = r12[0]*forcelj;
+ fforce[1] = r12[1]*forcelj;
+ fforce[2] = r12[2]*forcelj;
+ ttor[0] = ttor[1] = ttor[2] = 0.0;
+ rtor[0] = rtor[1] = rtor[2] = 0.0;
+ break;
+
+ case SPHERE_ELLIPSE:
+ jquat = bonus[ellipsoid[j]].quat;
+ MathExtra::quat_to_mat_trans(jquat,a2);
+ MathExtra::diag_times3(well[jtype],a2,temp);
+ MathExtra::transpose_times3(a2,temp,b2);
+ MathExtra::diag_times3(shape2[jtype],a2,temp);
+ MathExtra::transpose_times3(a2,temp,g2);
+ one_eng = gayberne_lj(j,i,a2,b2,g2,r12,rsq,fforce,rtor);
+ ttor[0] = ttor[1] = ttor[2] = 0.0;
+ break;
+
+ case ELLIPSE_SPHERE:
+ one_eng = gayberne_lj(i,j,a1,b1,g1,r12,rsq,fforce,ttor);
+ rtor[0] = rtor[1] = rtor[2] = 0.0;
+ break;
+
+ default:
+ jquat = bonus[ellipsoid[j]].quat;
+ MathExtra::quat_to_mat_trans(jquat,a2);
+ MathExtra::diag_times3(well[jtype],a2,temp);
+ MathExtra::transpose_times3(a2,temp,b2);
+ MathExtra::diag_times3(shape2[jtype],a2,temp);
+ MathExtra::transpose_times3(a2,temp,g2);
+ one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
+ fforce,ttor,rtor);
+ break;
+ }
+
+ fforce[0] *= factor_lj;
+ fforce[1] *= factor_lj;
+ fforce[2] *= factor_lj;
+ ttor[0] *= factor_lj;
+ ttor[1] *= factor_lj;
+ ttor[2] *= factor_lj;
+
+ f[i][0] += fforce[0];
+ f[i][1] += fforce[1];
+ f[i][2] += fforce[2];
+ tor[i][0] += ttor[0];
+ tor[i][1] += ttor[1];
+ tor[i][2] += ttor[2];
+
+ if (NEWTON_PAIR || j < nlocal) {
+ rtor[0] *= factor_lj;
+ rtor[1] *= factor_lj;
+ rtor[2] *= factor_lj;
+ f[j][0] -= fforce[0];
+ f[j][1] -= fforce[1];
+ f[j][2] -= fforce[2];
+ tor[j][0] += rtor[0];
+ tor[j][1] += rtor[1];
+ tor[j][2] += rtor[2];
+ }
+
+ if (EFLAG) evdwl = factor_lj*one_eng;
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fforce[0],fforce[1],fforce[2],
+ -r12[0],-r12[1],-r12[2],tid);
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGayBerneOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairGayBerne::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_gayberne_omp.h b/src/USER-OMP/pair_gayberne_omp.h
new file mode 100644
index 0000000000..737b4ec67d
--- /dev/null
+++ b/src/USER-OMP/pair_gayberne_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(gayberne/omp,PairGayBerneOMP)
+
+#else
+
+#ifndef LMP_PAIR_GAYBERNE_OMP_H
+#define LMP_PAIR_GAYBERNE_OMP_H
+
+#include "pair_gayberne.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairGayBerneOMP : public PairGayBerne, public ThrOMP {
+
+ public:
+ PairGayBerneOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.cpp b/src/USER-OMP/pair_gran_hertz_history_omp.cpp
new file mode 100644
index 0000000000..1866833afe
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hertz_history_omp.cpp
@@ -0,0 +1,298 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_gran_hertz_history_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "update.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairGranHertzHistoryOMP::PairGranHertzHistoryOMP(LAMMPS *lmp) :
+ PairGranHertzHistory(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGranHertzHistoryOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int shearupdate = (update->ntimestep > laststep) ? 1 : 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag)
+ if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0>(f, torque, ifrom, ito, tid);
+ else
+ if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0>(f, torque, ifrom, ito, tid);
+
+ // reduce per thread forces and torque into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+
+ laststep = update->ntimestep;
+}
+
+template
+void PairGranHertzHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
+ double radi,radj,radsum,rsq,r,rinv,rsqinv;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
+ double wr1,wr2,wr3;
+ double vtr1,vtr2,vtr3,vrel;
+ double meff,damp,ccel,tor1,tor2,tor3;
+ double fn,fs,fs1,fs2,fs3;
+ double shrmag,rsht,polyhertz;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int *touch,**firsttouch;
+ double *shear,*allshear,**firstshear;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **omega = atom->omega;
+ double *radius = atom->radius;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ double fxtmp,fytmp,fztmp;
+ double t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ firsttouch = list->listgranhistory->firstneigh;
+ firstshear = list->listgranhistory->firstdouble;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ touch = firsttouch[i];
+ allshear = firstshear[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radj = radius[j];
+ radsum = radi + radj;
+
+ if (rsq >= radsum*radsum) {
+
+ // unset non-touching neighbors
+
+ touch[jj] = 0;
+ shear = &allshear[3*jj];
+ shear[0] = 0.0;
+ shear[1] = 0.0;
+ shear[2] = 0.0;
+
+ } else {
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal force = Hertzian contact + normal velocity damping
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ itype = type[i];
+ jtype = type[j];
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+ polyhertz = sqrt((radsum-r)*radi*radj / radsum);
+ ccel *= polyhertz;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // shear history effects
+
+ touch[jj] = 1;
+ shear = &allshear[3*jj];
+
+ if (SHEARUPDATE) {
+ shear[0] += vtr1*dt;
+ shear[1] += vtr2*dt;
+ shear[2] += vtr3*dt;
+ }
+ shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
+ shear[2]*shear[2]);
+
+ // rotate shear displacements
+
+ rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
+ rsht *= rsqinv;
+ if (SHEARUPDATE) {
+ shear[0] -= rsht*delx;
+ shear[1] -= rsht*dely;
+ shear[2] -= rsht*delz;
+ }
+
+ // tangential forces = shear + tangential velocity damping
+
+ fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1);
+ fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2);
+ fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3);
+
+ // rescale frictional displacements and forces if needed
+
+ fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
+ fn = xmu * fabs(ccel*r);
+
+ if (fs > fn) {
+ if (shrmag != 0.0) {
+ const double fnfs = fn/fs;
+ const double mgkt = meff*gammat/kt;
+ shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1;
+ shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2;
+ shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3;
+ fs1 *= fnfs;
+ fs2 *= fnfs;
+ fs3 *= fnfs;
+ } else fs1 = fs2 = fs3 = 0.0;
+ }
+
+ // forces & torques
+
+ fx = delx*ccel + fs1;
+ fy = dely*ccel + fs2;
+ fz = delz*ccel + fs3;
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+
+ tor1 = rinv * (dely*fs3 - delz*fs2);
+ tor2 = rinv * (delz*fs1 - delx*fs3);
+ tor3 = rinv * (delx*fs2 - dely*fs1);
+ t1tmp -= radi*tor1;
+ t2tmp -= radi*tor2;
+ t3tmp -= radi*tor3;
+
+ if (j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ torque[j][0] -= radj*tor1;
+ torque[j][1] -= radj*tor2;
+ torque[j][2] -= radj*tor3;
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0,
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ torque[i][0] += t1tmp;
+ torque[i][1] += t2tmp;
+ torque[i][2] += t3tmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHertzHistoryOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairGranHertzHistory::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.h b/src/USER-OMP/pair_gran_hertz_history_omp.h
new file mode 100644
index 0000000000..66d7bc0fa5
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hertz_history_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(gran/hertz/history/omp,PairGranHertzHistoryOMP)
+
+#else
+
+#ifndef LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
+#define LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
+
+#include "pair_gran_hertz_history.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairGranHertzHistoryOMP : public PairGranHertzHistory, public ThrOMP {
+
+ public:
+ PairGranHertzHistoryOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.cpp b/src/USER-OMP/pair_gran_hooke_history_omp.cpp
new file mode 100644
index 0000000000..ad0537b516
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hooke_history_omp.cpp
@@ -0,0 +1,301 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_gran_hooke_history_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "update.h"
+
+#include "string.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairGranHookeHistoryOMP::PairGranHookeHistoryOMP(LAMMPS *lmp) :
+ PairGranHookeHistory(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ // trigger use of OpenMP version of FixShearHistory
+ suffix = new char[4];
+ memcpy(suffix,"omp",4);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGranHookeHistoryOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int shearupdate = (update->ntimestep > laststep) ? 1 : 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag)
+ if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0>(f, torque, ifrom, ito, tid);
+ else
+ if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0>(f, torque, ifrom, ito, tid);
+
+ // reduce per thread forces and torque into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+
+ laststep = update->ntimestep;
+}
+
+template
+void PairGranHookeHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
+ double radi,radj,radsum,rsq,r,rinv,rsqinv;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
+ double wr1,wr2,wr3;
+ double vtr1,vtr2,vtr3,vrel;
+ double meff,damp,ccel,tor1,tor2,tor3;
+ double fn,fs,fs1,fs2,fs3;
+ double shrmag,rsht;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int *touch,**firsttouch;
+ double *shear,*allshear,**firstshear;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **omega = atom->omega;
+ double *radius = atom->radius;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ double fxtmp,fytmp,fztmp;
+ double t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ firsttouch = listgranhistory->firstneigh;
+ firstshear = listgranhistory->firstdouble;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ touch = firsttouch[i];
+ allshear = firstshear[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radj = radius[j];
+ radsum = radi + radj;
+
+ if (rsq >= radsum*radsum) {
+
+ // unset non-touching neighbors
+
+ touch[jj] = 0;
+ shear = &allshear[3*jj];
+ shear[0] = 0.0;
+ shear[1] = 0.0;
+ shear[2] = 0.0;
+
+ } else {
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal forces = Hookian contact + normal velocity damping
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ itype = type[i];
+ jtype = type[j];
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // shear history effects
+
+ touch[jj] = 1;
+ shear = &allshear[3*jj];
+
+ if (SHEARUPDATE) {
+ shear[0] += vtr1*dt;
+ shear[1] += vtr2*dt;
+ shear[2] += vtr3*dt;
+ }
+ shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
+ shear[2]*shear[2]);
+
+ // rotate shear displacements
+
+ rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
+ rsht *= rsqinv;
+ if (SHEARUPDATE) {
+ shear[0] -= rsht*delx;
+ shear[1] -= rsht*dely;
+ shear[2] -= rsht*delz;
+ }
+
+ // tangential forces = shear + tangential velocity damping
+
+ fs1 = - (kt*shear[0] + meff*gammat*vtr1);
+ fs2 = - (kt*shear[1] + meff*gammat*vtr2);
+ fs3 = - (kt*shear[2] + meff*gammat*vtr3);
+
+ // rescale frictional displacements and forces if needed
+
+ fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
+ fn = xmu * fabs(ccel*r);
+
+ if (fs > fn) {
+ if (shrmag != 0.0) {
+ const double fnfs = fn/fs;
+ const double mgkt = meff*gammat/kt;
+ shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1;
+ shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2;
+ shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3;
+ fs1 *= fnfs;
+ fs2 *= fnfs;
+ fs3 *= fnfs;
+ } else fs1 = fs2 = fs3 = 0.0;
+ }
+
+ // forces & torques
+
+ fx = delx*ccel + fs1;
+ fy = dely*ccel + fs2;
+ fz = delz*ccel + fs3;
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+
+ tor1 = rinv * (dely*fs3 - delz*fs2);
+ tor2 = rinv * (delz*fs1 - delx*fs3);
+ tor3 = rinv * (delx*fs2 - dely*fs1);
+ t1tmp -= radi*tor1;
+ t2tmp -= radi*tor2;
+ t3tmp -= radi*tor3;
+
+ if (j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ torque[j][0] -= radj*tor1;
+ torque[j][1] -= radj*tor2;
+ torque[j][2] -= radj*tor3;
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0,
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ torque[i][0] += t1tmp;
+ torque[i][1] += t2tmp;
+ torque[i][2] += t3tmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHookeHistoryOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairGranHookeHistory::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.h b/src/USER-OMP/pair_gran_hooke_history_omp.h
new file mode 100644
index 0000000000..33325025fc
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hooke_history_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(gran/hooke/history/omp,PairGranHookeHistoryOMP)
+
+#else
+
+#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H
+#define LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H
+
+#include "pair_gran_hooke_history.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairGranHookeHistoryOMP : public PairGranHookeHistory, public ThrOMP {
+
+ public:
+ PairGranHookeHistoryOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_gran_hooke_omp.cpp b/src/USER-OMP/pair_gran_hooke_omp.cpp
new file mode 100644
index 0000000000..d6991fa453
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hooke_omp.cpp
@@ -0,0 +1,240 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_gran_hooke_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairGranHookeOMP::PairGranHookeOMP(LAMMPS *lmp) :
+ PairGranHooke(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGranHookeOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag)
+ if (force->newton_pair) eval<1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0>(f, torque, ifrom, ito, tid);
+ else
+ if (force->newton_pair) eval<0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0>(f, torque, ifrom, ito, tid);
+
+ // reduce per thread forces and torque into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+}
+
+template
+void PairGranHookeOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
+ double radi,radj,radsum,rsq,r,rinv,rsqinv;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
+ double wr1,wr2,wr3;
+ double vtr1,vtr2,vtr3,vrel;
+ double meff,damp,ccel,tor1,tor2,tor3;
+ double fn,fs,ft,fs1,fs2,fs3;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **omega = atom->omega;
+ double *radius = atom->radius;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ double fxtmp,fytmp,fztmp;
+ double t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radj = radius[j];
+ radsum = radi + radj;
+
+ if (rsq < radsum*radsum) {
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal forces = Hookian contact + normal velocity damping
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ itype = type[i];
+ jtype = type[j];
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // force normalization
+
+ fn = xmu * fabs(ccel*r);
+ fs = meff*gammat*vrel;
+ if (vrel != 0.0) ft = MIN(fn,fs) / vrel;
+ else ft = 0.0;
+
+ // tangential force due to tangential velocity damping
+
+ fs1 = -ft*vtr1;
+ fs2 = -ft*vtr2;
+ fs3 = -ft*vtr3;
+
+ // forces & torques
+
+ fx = delx*ccel + fs1;
+ fy = dely*ccel + fs2;
+ fz = delz*ccel + fs3;
+ fxtmp += fx;
+ fytmp += fy;
+ fztmp += fz;
+
+ tor1 = rinv * (dely*fs3 - delz*fs2);
+ tor2 = rinv * (delz*fs1 - delx*fs3);
+ tor3 = rinv * (delx*fs2 - dely*fs1);
+ t1tmp -= radi*tor1;
+ t2tmp -= radi*tor2;
+ t3tmp -= radi*tor3;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+ torque[j][0] -= radj*tor1;
+ torque[j][1] -= radj*tor2;
+ torque[j][2] -= radj*tor3;
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ torque[i][0] += t1tmp;
+ torque[i][1] += t2tmp;
+ torque[i][2] += t3tmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHookeOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairGranHooke::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_gran_hooke_omp.h b/src/USER-OMP/pair_gran_hooke_omp.h
new file mode 100644
index 0000000000..f2b093778c
--- /dev/null
+++ b/src/USER-OMP/pair_gran_hooke_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(gran/hooke/omp,PairGranHookeOMP)
+
+#else
+
+#ifndef LMP_PAIR_GRAN_HOOKE_OMP_H
+#define LMP_PAIR_GRAN_HOOKE_OMP_H
+
+#include "pair_gran_hooke.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairGranHookeOMP : public PairGranHooke, public ThrOMP {
+
+ public:
+ PairGranHookeOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
new file mode 100644
index 0000000000..012fd596b3
--- /dev/null
+++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
@@ -0,0 +1,299 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_hbond_dreiding_lj_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+PairHbondDreidingLJOMP::PairHbondDreidingLJOMP(LAMMPS *lmp) :
+ PairHbondDreidingLJ(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ hbcount_thr = hbeng_thr = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairHbondDreidingLJOMP::~PairHbondDreidingLJOMP()
+{
+ respa_enable = 0;
+ if (hbcount_thr) {
+ delete[] hbcount_thr;
+ delete[] hbeng_thr;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairHbondDreidingLJOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ if (!hbcount_thr) {
+ hbcount_thr = new double[nthreads];
+ hbeng_thr = new double[nthreads];
+ }
+
+ for (int i=0; i < nthreads; ++i) {
+ hbcount_thr[i] = 0.0;
+ hbeng_thr[i] = 0.0;
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+
+ // reduce per thread hbond data
+ if (eflag_global) {
+ pvector[0] = 0.0;
+ pvector[1] = 0.0;
+ for (int i=0; i < nthreads; ++i) {
+ pvector[0] += hbcount_thr[i];
+ pvector[1] += hbeng_thr[i];
+ }
+ }
+}
+
+template
+void PairHbondDreidingLJOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
+ double factor_hb,force_angle,force_kernel,evdwl,eng_lj;
+ double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
+ double fi[3],fj[3],delr1[3],delr2[3];
+ double r2inv,r10inv;
+ double switch1,switch2;
+ int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+ Param *pm;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+
+ // ii = loop over donors
+ // jj = loop over acceptors
+ // kk = loop over hydrogens bonded to donor
+
+ int hbcount = 0;
+ double hbeng = 0.0;
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itype = type[i];
+ if (!donor[itype]) continue;
+
+ klist = special[i];
+ knum = nspecial[i][0];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_hb = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ jtype = type[j];
+ if (!acceptor[jtype]) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ for (kk = 0; kk < knum; kk++) {
+ k = atom->map(klist[kk]);
+ if (k < 0) continue;
+ ktype = type[k];
+ m = type2param[itype][jtype][ktype];
+ if (m < 0) continue;
+ pm = ¶ms[m];
+
+ if (rsq < pm->cut_outersq) {
+ delr1[0] = xtmp - x[k][0];
+ delr1[1] = ytmp - x[k][1];
+ delr1[2] = ztmp - x[k][2];
+ domain->minimum_image(delr1);
+ rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
+ r1 = sqrt(rsq1);
+
+ delr2[0] = x[j][0] - x[k][0];
+ delr2[1] = x[j][1] - x[k][1];
+ delr2[2] = x[j][2] - x[k][2];
+ domain->minimum_image(delr2);
+ rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2];
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+ ac = acos(c);
+
+ if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+
+ // LJ-specific kernel
+
+ r2inv = 1.0/rsq;
+ r10inv = r2inv*r2inv*r2inv*r2inv*r2inv;
+ force_kernel = r10inv*(pm->lj1*r2inv - pm->lj2)*r2inv *
+ pow(c,pm->ap);
+ force_angle = pm->ap * r10inv*(pm->lj3*r2inv - pm->lj4) *
+ pow(c,pm->ap-1)*s;
+
+ eng_lj = r10inv*(pm->lj3*r2inv - pm->lj4);
+ if (rsq > pm->cut_innersq) {
+ switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) *
+ (pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) /
+ pm->denom_vdw;
+ switch2 = 12.0*rsq * (pm->cut_outersq-rsq) *
+ (rsq-pm->cut_innersq) / pm->denom_vdw;
+ force_kernel = force_kernel*switch1 + eng_lj*switch2;
+ eng_lj *= switch1;
+ }
+
+ if (EFLAG) {
+ evdwl = eng_lj * pow(c,pm->ap);
+ evdwl *= factor_hb;
+ }
+
+ a = factor_hb*force_angle/s;
+ b = factor_hb*force_kernel;
+
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ vx1 = a11*delr1[0] + a12*delr2[0];
+ vx2 = a22*delr2[0] + a12*delr1[0];
+ vy1 = a11*delr1[1] + a12*delr2[1];
+ vy2 = a22*delr2[1] + a12*delr1[1];
+ vz1 = a11*delr1[2] + a12*delr2[2];
+ vz2 = a22*delr2[2] + a12*delr1[2];
+
+ fi[0] = vx1 + b*delx;
+ fi[1] = vy1 + b*dely;
+ fi[2] = vz1 + b*delz;
+ fj[0] = vx2 - b*delx;
+ fj[1] = vy2 - b*dely;
+ fj[2] = vz2 - b*delz;
+
+ fxtmp += fi[0];
+ fytmp += fi[1];
+ fztmp += fi[2];
+
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+
+ f[k][0] -= vx1 + vx2;
+ f[k][1] -= vy1 + vy2;
+ f[k][2] -= vz1 + vz2;
+
+ // KIJ instead of IJK b/c delr1/delr2 are both with respect to k
+
+ if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid);
+ if (EFLAG) {
+ hbcount++;
+ hbeng += evdwl;
+ }
+ }
+ }
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+ hbcount_thr[tid] = static_cast(hbcount);
+ hbeng_thr[tid] = hbeng;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairHbondDreidingLJOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += comm->nthreads * 2 * sizeof(double);
+ bytes += PairHbondDreidingLJ::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.h b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h
new file mode 100644
index 0000000000..1aef78490c
--- /dev/null
+++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(hbond/dreiding/lj/omp,PairHbondDreidingLJOMP)
+
+#else
+
+#ifndef LMP_PAIR_HBOND_DREIDING_LJ_OMP_H
+#define LMP_PAIR_HBOND_DREIDING_LJ_OMP_H
+
+#include "pair_hbond_dreiding_lj.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairHbondDreidingLJOMP : public PairHbondDreidingLJ, public ThrOMP {
+
+ public:
+ PairHbondDreidingLJOMP(class LAMMPS *);
+ virtual ~PairHbondDreidingLJOMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ double *hbcount_thr, *hbeng_thr;
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
new file mode 100644
index 0000000000..b6c966f8c7
--- /dev/null
+++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
@@ -0,0 +1,297 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_hbond_dreiding_morse_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+PairHbondDreidingMorseOMP::PairHbondDreidingMorseOMP(LAMMPS *lmp) :
+ PairHbondDreidingMorse(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ hbcount_thr = hbeng_thr = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairHbondDreidingMorseOMP::~PairHbondDreidingMorseOMP()
+{
+ respa_enable = 0;
+ if (hbcount_thr) {
+ delete[] hbcount_thr;
+ delete[] hbeng_thr;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairHbondDreidingMorseOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ if (!hbcount_thr) {
+ hbcount_thr = new double[nthreads];
+ hbeng_thr = new double[nthreads];
+ }
+
+ for (int i=0; i < nthreads; ++i) {
+ hbcount_thr[i] = 0.0;
+ hbeng_thr[i] = 0.0;
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+
+ // reduce per thread hbond data
+ if (eflag_global) {
+ pvector[0] = 0.0;
+ pvector[1] = 0.0;
+ for (int i=0; i < nthreads; ++i) {
+ pvector[0] += hbcount_thr[i];
+ pvector[1] += hbeng_thr[i];
+ }
+ }
+}
+
+template
+void PairHbondDreidingMorseOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
+ double factor_hb,force_angle,force_kernel,evdwl;
+ double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
+ double fi[3],fj[3],delr1[3],delr2[3];
+ double r,dr,dexp,eng_morse,switch1,switch2;
+ int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+ Param *pm;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+
+ // ii = loop over donors
+ // jj = loop over acceptors
+ // kk = loop over hydrogens bonded to donor
+
+ int hbcount = 0;
+ double hbeng = 0.0;
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itype = type[i];
+ if (!donor[itype]) continue;
+
+ klist = special[i];
+ knum = nspecial[i][0];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_hb = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ jtype = type[j];
+ if (!acceptor[jtype]) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ for (kk = 0; kk < knum; kk++) {
+ k = atom->map(klist[kk]);
+ if (k < 0) continue;
+ ktype = type[k];
+ m = type2param[itype][jtype][ktype];
+ if (m < 0) continue;
+ pm = ¶ms[m];
+
+ if (rsq < pm->cut_outersq) {
+ delr1[0] = xtmp - x[k][0];
+ delr1[1] = ytmp - x[k][1];
+ delr1[2] = ztmp - x[k][2];
+ domain->minimum_image(delr1);
+ rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
+ r1 = sqrt(rsq1);
+
+ delr2[0] = x[j][0] - x[k][0];
+ delr2[1] = x[j][1] - x[k][1];
+ delr2[2] = x[j][2] - x[k][2];
+ domain->minimum_image(delr2);
+ rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2];
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+ ac = acos(c);
+
+ if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+
+ // Morse-specific kernel
+
+ r = sqrt(rsq);
+ dr = r - pm->r0;
+ dexp = exp(-pm->alpha * dr);
+ force_kernel = pm->morse1*(dexp*dexp - dexp)/r * pow(c,pm->ap);
+ force_angle = pm->ap * eng_morse * pow(c,pm->ap-1)*s;
+
+ eng_morse = pm->d0 * (dexp*dexp - 2.0*dexp);
+ if (rsq > pm->cut_innersq) {
+ switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) *
+ (pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) /
+ pm->denom_vdw;
+ switch2 = 12.0*rsq * (pm->cut_outersq-rsq) *
+ (rsq-pm->cut_innersq) / pm->denom_vdw;
+ force_kernel = force_kernel*switch1 + eng_morse*switch2;
+ eng_morse *= switch1;
+ }
+
+ if (EFLAG) {
+ evdwl = eng_morse * pow(c,params[m].ap);
+ evdwl *= factor_hb;
+ }
+
+ a = factor_hb*force_angle/s;
+ b = factor_hb*force_kernel;
+
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ vx1 = a11*delr1[0] + a12*delr2[0];
+ vx2 = a22*delr2[0] + a12*delr1[0];
+ vy1 = a11*delr1[1] + a12*delr2[1];
+ vy2 = a22*delr2[1] + a12*delr1[1];
+ vz1 = a11*delr1[2] + a12*delr2[2];
+ vz2 = a22*delr2[2] + a12*delr1[2];
+
+ fi[0] = vx1 + b*delx;
+ fi[1] = vy1 + b*dely;
+ fi[2] = vz1 + b*delz;
+ fj[0] = vx2 - b*delx;
+ fj[1] = vy2 - b*dely;
+ fj[2] = vz2 - b*delz;
+
+ fxtmp += fi[0];
+ fytmp += fi[1];
+ fztmp += fi[2];
+
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+
+ f[k][0] -= vx1 + vx2;
+ f[k][1] -= vy1 + vy2;
+ f[k][2] -= vz1 + vz2;
+
+ // KIJ instead of IJK b/c delr1/delr2 are both with respect to k
+
+ if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid);
+ if (EFLAG) {
+ hbcount++;
+ hbeng += evdwl;
+ }
+ }
+ }
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+ hbcount_thr[tid] = static_cast(hbcount);
+ hbeng_thr[tid] = hbeng;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairHbondDreidingMorseOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += comm->nthreads * 2 * sizeof(double);
+ bytes += PairHbondDreidingMorse::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.h b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h
new file mode 100644
index 0000000000..2a13c618c6
--- /dev/null
+++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(hbond/dreiding/morse/omp,PairHbondDreidingMorseOMP)
+
+#else
+
+#ifndef LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H
+#define LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H
+
+#include "pair_hbond_dreiding_morse.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairHbondDreidingMorseOMP : public PairHbondDreidingMorse, public ThrOMP {
+
+ public:
+ PairHbondDreidingMorseOMP(class LAMMPS *);
+ virtual ~PairHbondDreidingMorseOMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ double *hbcount_thr, *hbeng_thr;
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj96_cut_omp.cpp b/src/USER-OMP/pair_lj96_cut_omp.cpp
new file mode 100644
index 0000000000..f0998363e1
--- /dev/null
+++ b/src/USER-OMP/pair_lj96_cut_omp.cpp
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj96_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJ96CutOMP::PairLJ96CutOMP(LAMMPS *lmp) :
+ PairLJ96Cut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJ96CutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJ96CutOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ r3inv = sqrt(r6inv);
+
+ forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype])
+ - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJ96CutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJ96Cut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj96_cut_omp.h b/src/USER-OMP/pair_lj96_cut_omp.h
new file mode 100644
index 0000000000..333212303d
--- /dev/null
+++ b/src/USER-OMP/pair_lj96_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj96/cut/omp,PairLJ96CutOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ96_CUT_OMP_H
+#define LMP_PAIR_LJ96_CUT_OMP_H
+
+#include "pair_lj96_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJ96CutOMP : public PairLJ96Cut, public ThrOMP {
+
+ public:
+ PairLJ96CutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
new file mode 100644
index 0000000000..32ad05acda
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
@@ -0,0 +1,213 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_charmm_coul_charmm_implicit_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCharmmCoulCharmmImplicitOMP::PairLJCharmmCoulCharmmImplicitOMP(LAMMPS *lmp) :
+ PairLJCharmmCoulCharmmImplicit(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCharmmCoulCharmmImplicitOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCharmmCoulCharmmImplicitOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double philj,switch1,switch2;
+ double invdenom_coul,invdenom_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
+ invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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) {
+ 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) * invdenom_coul;
+ switch2 = 12.0*rsq * (cut_coulsq-rsq) *
+ (rsq-cut_coul_innersq) * invdenom_coul;
+ forcecoul *= switch1 + switch2;
+ }
+ forcecoul *= factor_coul;
+ } 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) * invdenom_lj;
+ switch2 = 12.0*rsq * (cut_ljsq-rsq) *
+ (rsq-cut_lj_innersq) * invdenom_lj;
+ philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
+ forcelj = forcelj*switch1 + philj*switch2;
+ }
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = 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) *
+ invdenom_coul;
+ ecoul *= switch1;
+ }
+ ecoul *= factor_coul;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq) {
+ evdwl = 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) * invdenom_lj;
+ evdwl *= switch1;
+ }
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCharmmCoulCharmmImplicitOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCharmmCoulCharmmImplicit::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
new file mode 100644
index 0000000000..ba016d7d3d
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/charmm/coul/charmm/implicit/omp,PairLJCharmmCoulCharmmImplicitOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H
+#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H
+
+#include "pair_lj_charmm_coul_charmm_implicit.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCharmmCoulCharmmImplicitOMP : public PairLJCharmmCoulCharmmImplicit, public ThrOMP {
+
+ public:
+ PairLJCharmmCoulCharmmImplicitOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
new file mode 100644
index 0000000000..6dac7a17f6
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
@@ -0,0 +1,213 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_charmm_coul_charmm_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCharmmCoulCharmmOMP::PairLJCharmmCoulCharmmOMP(LAMMPS *lmp) :
+ PairLJCharmmCoulCharmm(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCharmmCoulCharmmOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCharmmCoulCharmmOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double philj,switch1,switch2;
+ double invdenom_coul,invdenom_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
+ invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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) {
+ 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) * invdenom_coul;
+ switch2 = 12.0*rsq * (cut_coulsq-rsq) *
+ (rsq-cut_coul_innersq) * invdenom_coul;
+ forcecoul *= switch1 + switch2;
+ }
+ forcecoul *= factor_coul;
+ } 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) * invdenom_lj;
+ switch2 = 12.0*rsq * (cut_ljsq-rsq) *
+ (rsq-cut_lj_innersq) * invdenom_lj;
+ philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
+ forcelj = forcelj*switch1 + philj*switch2;
+ }
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = 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) *
+ invdenom_coul;
+ ecoul *= switch1;
+ }
+ ecoul *= factor_coul;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq) {
+ evdwl = 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) * invdenom_lj;
+ evdwl *= switch1;
+ }
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCharmmCoulCharmmOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCharmmCoulCharmm::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
new file mode 100644
index 0000000000..f2889b05fe
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/charmm/coul/charmm/omp,PairLJCharmmCoulCharmmOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H
+#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H
+
+#include "pair_lj_charmm_coul_charmm.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCharmmCoulCharmmOMP : public PairLJCharmmCoulCharmm, public ThrOMP {
+
+ public:
+ PairLJCharmmCoulCharmmOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
new file mode 100644
index 0000000000..c99f27f2e1
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
@@ -0,0 +1,234 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_charmm_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCharmmCoulLongOMP::PairLJCharmmCoulLongOMP(LAMMPS *lmp) :
+ PairLJCharmmCoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCharmmCoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCharmmCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype,itable;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double fraction,table;
+ double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+ double philj,switch1,switch2;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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 = 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 {
+ union_int_float_t rsq_lookup;
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup.f - 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;
+ }
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ ecoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ ecoul = qtmp*q[j] * table;
+ }
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq) {
+ evdwl = 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;
+ evdwl *= switch1;
+ }
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCharmmCoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCharmmCoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
new file mode 100644
index 0000000000..b14e4c1fe4
--- /dev/null
+++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/charmm/coul/long/omp,PairLJCharmmCoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
+#define LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
+
+#include "pair_lj_charmm_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCharmmCoulLongOMP : public PairLJCharmmCoulLong, public ThrOMP {
+
+ public:
+ PairLJCharmmCoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
new file mode 100644
index 0000000000..0321882793
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
@@ -0,0 +1,185 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_class2_coul_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJClass2CoulCutOMP::PairLJClass2CoulCutOMP(LAMMPS *lmp) :
+ PairLJClass2CoulCut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJClass2CoulCutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJClass2CoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj;
+ double factor_coul,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ rinv = sqrt(r2inv);
+
+ if (rsq < cut_coulsq[itype][jtype]) {
+ forcecoul = qqrd2e * qtmp*q[j]*rinv;
+ forcecoul *= factor_coul;
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r3inv = r2inv*rinv;
+ r6inv = r3inv*r3inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype])
+ ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv;
+ else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJClass2CoulCutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJClass2CoulCut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
new file mode 100644
index 0000000000..5fe4895691
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/class2/coul/cut/omp,PairLJClass2CoulCutOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
+#define LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
+
+#include "pair_lj_class2_coul_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJClass2CoulCutOMP : public PairLJClass2CoulCut, public ThrOMP {
+
+ public:
+ PairLJClass2CoulCutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
new file mode 100644
index 0000000000..84d26ceb14
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
@@ -0,0 +1,201 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_class2_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairLJClass2CoulLongOMP::PairLJClass2CoulLongOMP(LAMMPS *lmp) :
+ PairLJClass2CoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJClass2CoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJClass2CoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double r,rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ rinv = sqrt(r2inv);
+ r3inv = r2inv*rinv;
+ r6inv = r3inv*r3inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = prefactor*erfc;
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJClass2CoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJClass2CoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.h b/src/USER-OMP/pair_lj_class2_coul_long_omp.h
new file mode 100644
index 0000000000..da4ac3680f
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/class2/coul/long/omp,PairLJClass2CoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H
+#define LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H
+
+#include "pair_lj_class2_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJClass2CoulLongOMP : public PairLJClass2CoulLong, public ThrOMP {
+
+ public:
+ PairLJClass2CoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_class2_omp.cpp b/src/USER-OMP/pair_lj_class2_omp.cpp
new file mode 100644
index 0000000000..4f5d2550fc
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_omp.cpp
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_class2_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJClass2OMP::PairLJClass2OMP(LAMMPS *lmp) :
+ PairLJClass2(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJClass2OMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJClass2OMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ r3inv = sqrt(r6inv);
+
+ forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype])
+ - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJClass2OMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJClass2::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_class2_omp.h b/src/USER-OMP/pair_lj_class2_omp.h
new file mode 100644
index 0000000000..cfe24bb714
--- /dev/null
+++ b/src/USER-OMP/pair_lj_class2_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/class2/omp,PairLJClass2OMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CLASS2_OMP_H
+#define LMP_PAIR_LJ_CLASS2_OMP_H
+
+#include "pair_lj_class2.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJClass2OMP : public PairLJClass2, public ThrOMP {
+
+ public:
+ PairLJClass2OMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_coul_omp.cpp b/src/USER-OMP/pair_lj_coul_omp.cpp
new file mode 100644
index 0000000000..23e2a8d906
--- /dev/null
+++ b/src/USER-OMP/pair_lj_coul_omp.cpp
@@ -0,0 +1,234 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_coul_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "math_vector.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCoulOMP::PairLJCoulOMP(LAMMPS *lmp) :
+ PairLJCoul(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCoulOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCoulOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ double evdwl,ecoul,fpair;
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+
+ double *x0 = x[0];
+ double *f0 = f[0], *fi = f0;
+
+ int *ilist = list->ilist;
+
+ // loop over neighbors of my atoms
+
+ int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
+ int *jneigh, *jneighn, typei, typej, ni;
+ double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti;
+ double rsq, r2inv, force_coul, force_lj;
+ double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
+ vector xi, d;
+
+ for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms
+ i = ilist[ii]; fi = f0+3*i;
+ if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants
+ offseti = offset[typei = type[i]];
+ lj1i = lj1[typei]; lj2i = lj2[typei]; lj3i = lj3[typei]; lj4i = lj4[typei];
+ cutsqi = cutsq[typei]; cut_ljsqi = cut_ljsq[typei];
+ memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
+ jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
+
+ for (; jneigh= cutsqi[typej = type[j]]) continue;
+ r2inv = 1.0/rsq;
+
+ if (order1 && (rsq < cut_coulsq)) { // coulombic
+ if (!ncoultablebits || rsq <= tabinnersq) { // series real space
+ register double r = sqrt(rsq), x = g_ewald*r;
+ register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x);
+ if (ni == 0) {
+ s *= g_ewald*exp(-x*x);
+ force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
+ if (EFLAG) ecoul = t;
+ }
+ else { // special case
+ r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x);
+ force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r;
+ if (EFLAG) ecoul = t-r;
+ }
+ } // table real space
+ else {
+ register union_int_float_t t;
+ t.f = rsq;
+ register const int k = (t.i & ncoulmask)>>ncoulshiftbits;
+ register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
+ if (ni == 0) {
+ force_coul = qiqj*(ftable[k]+f*dftable[k]);
+ if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]);
+ }
+ else { // special case
+ t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
+ force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f);
+ if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f);
+ }
+ }
+ }
+ else force_coul = ecoul = 0.0;
+
+ if (rsq < cut_ljsqi[typej]) { // lj
+ if (order6) { // long-range lj
+ register double rn = r2inv*r2inv*r2inv;
+ register double x2 = g2*rsq, a2 = 1.0/x2;
+ x2 = a2*exp(-x2)*lj4i[typej];
+ if (ni == 0) {
+ force_lj =
+ (rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
+ if (EFLAG)
+ evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2;
+ }
+ else { // special case
+ register double f = special_lj[ni], t = rn*(1.0-f);
+ force_lj = f*(rn *= rn)*lj1i[typej]-
+ g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej];
+ if (EFLAG)
+ evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej];
+ }
+ }
+ else { // cut lj
+ register double rn = r2inv*r2inv*r2inv;
+ if (ni == 0) {
+ force_lj = rn*(rn*lj1i[typej]-lj2i[typej]);
+ if (EFLAG) evdwl = rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej];
+ }
+ else { // special case
+ register double f = special_lj[ni];
+ force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]);
+ if (EFLAG)
+ evdwl = f * (rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
+ }
+ }
+ }
+ else force_lj = evdwl = 0.0;
+
+ fpair = (force_coul+force_lj)*r2inv;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ register double *fj = f0+(j+(j<<1)), f;
+ fi[0] += f = d[0]*fpair; fj[0] -= f;
+ fi[1] += f = d[1]*fpair; fj[1] -= f;
+ fi[2] += f = d[2]*fpair; fj[2] -= f;
+ }
+ else {
+ fi[0] += d[0]*fpair;
+ fi[1] += d[1]*fpair;
+ fi[2] += d[2]*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,d[0],d[1],d[2],tid);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCoulOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCoul::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_coul_omp.h b/src/USER-OMP/pair_lj_coul_omp.h
new file mode 100644
index 0000000000..619e609ba8
--- /dev/null
+++ b/src/USER-OMP/pair_lj_coul_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/coul/omp,PairLJCoulOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_COUL_OMP_H
+#define LMP_PAIR_LJ_COUL_OMP_H
+
+#include "pair_lj_coul.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCoulOMP : public PairLJCoul, public ThrOMP {
+
+ public:
+ PairLJCoulOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cubic_omp.cpp b/src/USER-OMP/pair_lj_cubic_omp.cpp
new file mode 100644
index 0000000000..4f806bd71f
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cubic_omp.cpp
@@ -0,0 +1,173 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_cubic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+using namespace PairLJCubicConstants;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCubicOMP::PairLJCubicOMP(LAMMPS *lmp) :
+ PairLJCubic(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCubicOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJCubicOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,forcelj,factor_lj;
+ double r,t,rmin;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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_inner_sq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ } else {
+ r = sqrt(rsq);
+ rmin = sigma[itype][jtype]*RT6TWO;
+ t = (r - cut_inner[itype][jtype])/rmin;
+ forcelj = epsilon[itype][jtype]*(-DPHIDS + A3*t*t/2.0)*r/rmin;
+ }
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq <= cut_inner_sq[itype][jtype])
+ evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
+ else
+ evdwl = epsilon[itype][jtype]*
+ (PHIS + DPHIDS*t - A3*t*t*t/6.0);
+
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCubicOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCubic::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_cubic_omp.h b/src/USER-OMP/pair_lj_cubic_omp.h
new file mode 100644
index 0000000000..559a6125ab
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cubic_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cubic/omp,PairLJCubicOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CUBIC_OMP_H
+#define LMP_PAIR_LJ_CUBIC_OMP_H
+
+#include "pair_lj_cubic.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCubicOMP : public PairLJCubic, public ThrOMP {
+
+ public:
+ PairLJCubicOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
new file mode 100644
index 0000000000..be98ec38fc
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_cut_coul_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCutCoulCutOMP::PairLJCutCoulCutOMP(LAMMPS *lmp) :
+ PairLJCutCoulCut(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulCutOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCutCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,rinv,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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[itype][jtype]) {
+ rinv = sqrt(r2inv);
+ forcecoul = qqrd2e * qtmp*q[j]*rinv;
+ forcecoul *= factor_coul;
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype])
+ ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv;
+ else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+ } else evdwl = 0.0;
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCutCoulCutOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCutCoulCut::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.h b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h
new file mode 100644
index 0000000000..c8c34e2591
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cut/coul/cut/omp,PairLJCutCoulCutOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H
+
+#include "pair_lj_cut_coul_cut.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCutCoulCutOMP : public PairLJCutCoulCut, public ThrOMP {
+
+ public:
+ PairLJCutCoulCutOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
new file mode 100644
index 0000000000..13a4a1906f
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
@@ -0,0 +1,186 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_cut_coul_debye_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCutCoulDebyeOMP::PairLJCutCoulDebyeOMP(LAMMPS *lmp) :
+ PairLJCutCoulDebye(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulDebyeOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCutCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double r,rinv,screening;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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[itype][jtype]) {
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ screening = exp(-kappa*r);
+ forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv);
+ forcecoul *= factor_coul;
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq[itype][jtype])
+ ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening;
+ else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCutCoulDebyeOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCutCoulDebye::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
new file mode 100644
index 0000000000..00cf540be2
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cut/coul/debye/omp,PairLJCutCoulDebyeOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
+
+#include "pair_lj_cut_coul_debye.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCutCoulDebyeOMP : public PairLJCutCoulDebye, public ThrOMP {
+
+ public:
+ PairLJCutCoulDebyeOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
new file mode 100644
index 0000000000..1d8f977c96
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
@@ -0,0 +1,220 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_cut_coul_long_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) :
+ PairLJCutCoulLong(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulLongOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCutCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype,itable;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double fraction,table;
+ double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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 = 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 {
+ union_int_float_t rsq_lookup;
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup.f - 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]);
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ ecoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ ecoul = qtmp*q[j] * table;
+ }
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCutCoulLongOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCutCoulLong::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_omp.h
new file mode 100644
index 0000000000..ac408ba886
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
+
+#include "pair_lj_cut_coul_long.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP {
+
+ public:
+ PairLJCutCoulLongOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
new file mode 100644
index 0000000000..6ada944c53
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
@@ -0,0 +1,462 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_cut_coul_long_tip4p_omp.h"
+#include "atom.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "error.h"
+#include "memory.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#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
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCutCoulLongTIP4POMP::PairLJCutCoulLongTIP4POMP(LAMMPS *lmp) :
+ PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+
+ // for caching m-shift corrected positions
+ maxmpos = 0;
+ h1idx = h2idx = NULL;
+ mpos = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLJCutCoulLongTIP4POMP::~PairLJCutCoulLongTIP4POMP()
+{
+ memory->destroy(h1idx);
+ memory->destroy(h2idx);
+ memory->destroy(mpos);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
+
+ // reallocate per-atom arrays, if necessary
+ if (nall > maxmpos) {
+ maxmpos = nall;
+ memory->grow(mpos,maxmpos,3,"pair:mpos");
+ memory->grow(h1idx,maxmpos,"pair:h1idx");
+ memory->grow(h2idx,maxmpos,"pair:h2idx");
+ }
+
+ // cache corrected M positions in mpos[]
+ double **x = atom->x;
+ int *type = atom->type;
+ for (int i = 0; i < nlocal; i++) {
+ if (type[i] == typeO) {
+ find_M(i,h1idx[i],h2idx[i],mpos[i]);
+ } else {
+ mpos[i][0] = x[i][0];
+ mpos[i][1] = x[i][1];
+ mpos[i][2] = x[i][2];
+ }
+ }
+ for (int i = nlocal; i < nall; i++) {
+ if (type[i] == typeO) {
+ find_M_permissive(i,h1idx[i],h2idx[i],mpos[i]);
+ } else {
+ mpos[i][0] = x[i][0];
+ mpos[i][1] = x[i][1];
+ mpos[i][2] = x[i][2];
+ }
+ }
+
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (vflag) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (vflag) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJCutCoulLongTIP4POMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype,itable;
+ int n,vlist[6];
+ int iH1,iH2,jH1,jH2;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
+ double fraction,table;
+ double delxOM,delyOM,delzOM;
+ double r,rsq,r2inv,r6inv,forcecoul,forcelj,cforce;
+ double factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc,ddotf;
+ double v[6],xH1[3],xH2[3];
+ double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz;
+ double *x1,*x2;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+ x1 = mpos[i];
+ iH1 = h1idx[i];
+ iH2 = h2idx[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+
+ fxtmp += delx*forcelj;
+ fytmp += dely*forcelj;
+ fztmp += delz*forcelj;
+ f[j][0] -= delx*forcelj;
+ f[j][1] -= dely*forcelj;
+ f[j][2] -= delz*forcelj;
+
+ if (EFLAG) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
+ evdwl,0.0,forcelj,delx,dely,delz,tid);
+ }
+
+ // adjust rsq and delxyz for off-site O charge(s)
+
+ if (itype == typeO || jtype == typeO) {
+ x2 = mpos[j];
+ jH1 = h1idx[j];
+ jH2 = h2idx[j];
+ if (jtype == typeO && ( jH1 < 0 || jH2 < 0 ))
+ error->one(FLERR,"TIP4P hydrogen is missing");
+ 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) {
+ r2inv = 1 / rsq;
+ 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 = qqrd2e * qtmp*q[j]/r;
+ forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
+ if (factor_coul < 1.0) {
+ forcecoul -= (1.0-factor_coul)*prefactor;
+ }
+ } else {
+ union_int_float_t rsq_lookup;
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup.f - 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 atom & partitioned
+ // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
+ // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
+ // preserves total force and torque on water molecule
+ // virial = sum(r x F) where each water's atoms are near xi and xj
+ // vlist stores 2,4,6 atoms whose forces contribute to virial
+
+ n = 0;
+
+ if (itype != typeO) {
+ fxtmp += delx * cforce;
+ fytmp += dely * cforce;
+ fztmp += delz * cforce;
+
+ if (VFLAG) {
+ v[0] = x[i][0] * delx * cforce;
+ v[1] = x[i][1] * dely * cforce;
+ v[2] = x[i][2] * delz * cforce;
+ v[3] = x[i][0] * dely * cforce;
+ v[4] = x[i][0] * delz * cforce;
+ v[5] = x[i][1] * delz * cforce;
+ vlist[n++] = i;
+ }
+
+ } else {
+
+ fdx = delx*cforce;
+ fdy = dely*cforce;
+ fdz = delz*cforce;
+
+ delxOM = x[i][0] - x1[0];
+ delyOM = x[i][1] - x1[1];
+ delzOM = x[i][2] - x1[2];
+
+ ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+ (qdist*qdist);
+
+ f1x = alpha * (fdx - ddotf * delxOM);
+ f1y = alpha * (fdy - ddotf * delyOM);
+ f1z = alpha * (fdz - ddotf * delzOM);
+
+ fOx = fdx - f1x;
+ fOy = fdy - f1y;
+ fOz = fdz - f1z;
+
+ fHx = 0.5 * f1x;
+ fHy = 0.5 * f1y;
+ fHz = 0.5 * f1z;
+
+ fxtmp += fOx;
+ fytmp += fOy;
+ fztmp += fOz;
+
+ f[iH1][0] += fHx;
+ f[iH1][1] += fHy;
+ f[iH1][2] += fHz;
+
+ f[iH2][0] += fHx;
+ f[iH2][1] += fHy;
+ f[iH2][2] += fHz;
+
+ if (VFLAG) {
+ domain->closest_image(x[i],x[iH1],xH1);
+ domain->closest_image(x[i],x[iH2],xH2);
+
+ v[0] = x[i][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
+ v[1] = x[i][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
+ v[2] = x[i][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
+ v[3] = x[i][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
+ v[4] = x[i][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
+ v[5] = x[i][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
+
+ vlist[n++] = i;
+ vlist[n++] = iH1;
+ vlist[n++] = iH2;
+ }
+ }
+
+ if (jtype != typeO) {
+ f[j][0] -= delx * cforce;
+ f[j][1] -= dely * cforce;
+ f[j][2] -= delz * cforce;
+
+ if (VFLAG) {
+ v[0] -= x[j][0] * delx * cforce;
+ v[1] -= x[j][1] * dely * cforce;
+ v[2] -= x[j][2] * delz * cforce;
+ v[3] -= x[j][0] * dely * cforce;
+ v[4] -= x[j][0] * delz * cforce;
+ v[5] -= x[j][1] * delz * cforce;
+ vlist[n++] = j;
+ }
+
+ } else {
+
+ fdx = -delx*cforce;
+ fdy = -dely*cforce;
+ fdz = -delz*cforce;
+
+ delxOM = x[j][0] - x2[0];
+ delyOM = x[j][1] - x2[1];
+ delzOM = x[j][2] - x2[2];
+
+ ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+ (qdist*qdist);
+
+ f1x = alpha * (fdx - ddotf * delxOM);
+ f1y = alpha * (fdy - ddotf * delyOM);
+ f1z = alpha * (fdz - ddotf * delzOM);
+
+ fOx = fdx - f1x;
+ fOy = fdy - f1y;
+ fOz = fdz - f1z;
+
+ fHx = 0.5 * f1x;
+ fHy = 0.5 * f1y;
+ fHz = 0.5 * f1z;
+
+ f[j][0] += fOx;
+ f[j][1] += fOy;
+ f[j][2] += fOz;
+
+ f[jH1][0] += fHx;
+ f[jH1][1] += fHy;
+ f[jH1][2] += fHz;
+
+ f[jH2][0] += fHx;
+ f[jH2][1] += fHy;
+ f[jH2][2] += fHz;
+
+ if (VFLAG) {
+ domain->closest_image(x[j],x[jH1],xH1);
+ domain->closest_image(x[j],x[jH2],xH2);
+
+ v[0] += x[j][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
+ v[1] += x[j][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
+ v[2] += x[j][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
+ v[3] += x[j][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
+ v[4] += x[j][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
+ v[5] += x[j][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
+
+ vlist[n++] = j;
+ vlist[n++] = jH1;
+ vlist[n++] = jH2;
+ }
+ }
+
+ if (EFLAG) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ ecoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ ecoul = qtmp*q[j] * table;
+ }
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+
+ if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,tid);
+ }
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulLongTIP4POMP::find_M_permissive(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)
+ return;
+ else
+ find_M(i,iH1,iH2,xM);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJCutCoulLongTIP4POMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJCutCoulLongTIP4P::memory_usage();
+ bytes += 2 * maxmpos * sizeof(int);
+ bytes += 3 * maxmpos * sizeof(double);
+ bytes += maxmpos * sizeof(double *);
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
new file mode 100644
index 0000000000..093fc0216b
--- /dev/null
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cut/coul/long/tip4p/omp,PairLJCutCoulLongTIP4POMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
+
+#include "pair_lj_cut_coul_long_tip4p.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJCutCoulLongTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
+
+ public:
+ PairLJCutCoulLongTIP4POMP(class LAMMPS *);
+ virtual ~PairLJCutCoulLongTIP4POMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+
+ // this is to cache m-shift corrected positions.
+ int maxmpos; // size of the following arrays
+ int *h1idx, *h2idx; // local index of hydrogen atoms
+ double **mpos; // coordinates corrected for m-shift.
+ void find_M_permissive(int, int &, int &, double *);
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_omp.cpp
index 8ed82c5e5b..3d82149fec 100644
--- a/src/USER-OMP/pair_lj_cut_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_omp.cpp
@@ -19,9 +19,6 @@
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
-#include "neigh_request.h"
-#include "memory.h"
-#include "error.h"
using namespace LAMMPS_NS;
@@ -69,7 +66,7 @@ void PairLJCutOMP::compute(int eflag, int vflag)
}
// reduce per thread forces into global force array.
- force_reduce_thr(&(atom->f[0][0]), nall, nthreads, tid);
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
} // end of omp parallel region
// reduce per thread energy and virial, if requested.
diff --git a/src/USER-OMP/pair_lj_expand_omp.cpp b/src/USER-OMP/pair_lj_expand_omp.cpp
new file mode 100644
index 0000000000..7b06503ee4
--- /dev/null
+++ b/src/USER-OMP/pair_lj_expand_omp.cpp
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_expand_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJExpandOMP::PairLJExpandOMP(LAMMPS *lmp) :
+ PairLJExpand(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJExpandOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJExpandOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,forcelj,factor_lj;
+ double r,rshift,rshiftsq;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ r = sqrt(rsq);
+ rshift = r - shift[itype][jtype];
+ rshiftsq = rshift*rshift;
+ r2inv = 1.0/rshiftsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = factor_lj*forcelj/rshift/r;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])
+ - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJExpandOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJExpand::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_expand_omp.h b/src/USER-OMP/pair_lj_expand_omp.h
new file mode 100644
index 0000000000..29488deae8
--- /dev/null
+++ b/src/USER-OMP/pair_lj_expand_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/cut/omp,PairLJExpandOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_EXPAND_OMP_H
+#define LMP_PAIR_LJ_EXPAND_OMP_H
+
+#include "pair_lj_expand.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJExpandOMP : public PairLJExpand, public ThrOMP {
+
+ public:
+ PairLJExpandOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
new file mode 100644
index 0000000000..2e97fa1b5e
--- /dev/null
+++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
@@ -0,0 +1,210 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_gromacs_coul_gromacs_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJGromacsCoulGromacsOMP::PairLJGromacsCoulGromacsOMP(LAMMPS *lmp) :
+ PairLJGromacsCoulGromacs(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJGromacsCoulGromacsOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void PairLJGromacsCoulGromacsOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double r,tlj,tc,fswitch,fswitchcoul,eswitch,ecoulswitch;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = ecoul = 0.0;
+
+ double **x = atom->x;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+
+ // skip if qi or qj = 0.0 since this potential may be used as
+ // coarse-grain model with many uncharged atoms
+
+ if (rsq < cut_coulsq && qtmp != 0.0 && q[j] != 0.0) {
+ forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
+ if (rsq > cut_coul_innersq) {
+ r = sqrt(rsq);
+ tc = r - cut_coul_inner;
+ fswitchcoul = qqrd2e * qtmp*q[j]*r*tc*tc*(coulsw1 + coulsw2*tc);
+ forcecoul += fswitchcoul;
+ }
+ forcecoul *= factor_coul;
+ } 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) {
+ r = sqrt(rsq);
+ tlj = r - cut_lj_inner;
+ fswitch = r*tlj*tlj*(ljsw1[itype][jtype] +
+ ljsw2[itype][jtype]*tlj);
+ forcelj += fswitch;
+ }
+ forcelj *= factor_lj;
+ } else forcelj = 0.0;
+
+ fpair = (forcecoul + forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ ecoul = qqrd2e * qtmp*q[j] * (sqrt(r2inv) - coulsw5);
+ if (rsq > cut_coul_innersq) {
+ ecoulswitch = tc*tc*tc * (coulsw3 + coulsw4*tc);
+ ecoul += qqrd2e*qtmp*q[j]*ecoulswitch;
+ }
+ ecoul *= factor_coul;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq) {
+ evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
+ evdwl += ljsw5[itype][jtype];
+ if (rsq > cut_lj_innersq) {
+ eswitch = tlj*tlj*tlj *
+ (ljsw3[itype][jtype] + ljsw4[itype][jtype]*tlj);
+ evdwl += eswitch;
+ }
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJGromacsCoulGromacsOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJGromacsCoulGromacs::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
new file mode 100644
index 0000000000..d789bd6797
--- /dev/null
+++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/gromacs/coul/gromacs/omp,PairLJGromacsCoulGromacsOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H
+#define LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H
+
+#include "pair_lj_gromacs_coul_gromacs.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJGromacsCoulGromacsOMP : public PairLJGromacsCoulGromacs, public ThrOMP {
+
+ public:
+ PairLJGromacsCoulGromacsOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_omp.cpp
new file mode 100644
index 0000000000..f1c7d2faf9
--- /dev/null
+++ b/src/USER-OMP/pair_lj_gromacs_omp.cpp
@@ -0,0 +1,172 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_gromacs_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJGromacsOMP::PairLJGromacsOMP(LAMMPS *lmp) :
+ PairLJGromacs(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJGromacsOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJGromacsOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,forcelj,factor_lj;
+ double r,t,fswitch,eswitch;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ if (rsq > cut_inner_sq[itype][jtype]) {
+ r = sqrt(rsq);
+ t = r - cut_inner[itype][jtype];
+ fswitch = r*t*t*(ljsw1[itype][jtype] + ljsw2[itype][jtype]*t);
+ forcelj += fswitch;
+ }
+
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
+ evdwl += ljsw5[itype][jtype];
+ if (rsq > cut_inner_sq[itype][jtype]) {
+ eswitch = t*t*t*(ljsw3[itype][jtype] + ljsw4[itype][jtype]*t);
+ evdwl += eswitch;
+ }
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJGromacsOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJGromacs::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_omp.h
new file mode 100644
index 0000000000..d192a414ef
--- /dev/null
+++ b/src/USER-OMP/pair_lj_gromacs_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/gromacs/omp,PairLJGromacsOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_GROMACS_OMP_H
+#define LMP_PAIR_LJ_GROMACS_OMP_H
+
+#include "pair_lj_gromacs.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJGromacsOMP : public PairLJGromacs, public ThrOMP {
+
+ public:
+ PairLJGromacsOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_sf_omp.cpp b/src/USER-OMP/pair_lj_sf_omp.cpp
new file mode 100644
index 0000000000..55ee908e47
--- /dev/null
+++ b/src/USER-OMP/pair_lj_sf_omp.cpp
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_sf_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJShiftedForceOMP::PairLJShiftedForceOMP(LAMMPS *lmp) :
+ PairLJShiftedForce(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJShiftedForceOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJShiftedForceOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double t,rsq,r2inv,r6inv,forcelj,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r6inv = r2inv*r2inv*r2inv;
+ t = sqrt(r2inv*cutsq[itype][jtype]);
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) -
+ t*foffset[itype][jtype];
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) +
+ (t-1.0)*foffset[itype][jtype] - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJShiftedForceOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJShiftedForce::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_sf_omp.h b/src/USER-OMP/pair_lj_sf_omp.h
new file mode 100644
index 0000000000..6fba43fb8f
--- /dev/null
+++ b/src/USER-OMP/pair_lj_sf_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/sf/omp,PairLJShiftedForceOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_SF_OMP_H
+#define LMP_PAIR_LJ_SF_OMP_H
+
+#include "pair_lj_sf.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJShiftedForceOMP : public PairLJShiftedForce, public ThrOMP {
+
+ public:
+ PairLJShiftedForceOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lj_smooth_omp.cpp b/src/USER-OMP/pair_lj_smooth_omp.cpp
new file mode 100644
index 0000000000..1ad88044a6
--- /dev/null
+++ b/src/USER-OMP/pair_lj_smooth_omp.cpp
@@ -0,0 +1,176 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_smooth_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSmoothOMP::PairLJSmoothOMP(LAMMPS *lmp) :
+ PairLJSmooth(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJSmoothOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLJSmoothOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,forcelj,factor_lj;
+ double r,t,tsq,fskin;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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_inner_sq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv-lj2[itype][jtype]);
+ } else {
+ r = sqrt(rsq);
+ t = r - cut_inner[itype][jtype];
+ tsq = t*t;
+ fskin = ljsw1[itype][jtype] + ljsw2[itype][jtype]*t +
+ ljsw3[itype][jtype]*tsq + ljsw4[itype][jtype]*tsq*t;
+ forcelj = fskin*r;
+ }
+
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_inner_sq[itype][jtype])
+ evdwl = r6inv * (lj3[itype][jtype]*r6inv -
+ lj4[itype][jtype]) - offset[itype][jtype];
+ else
+ evdwl = ljsw0[itype][jtype] - ljsw1[itype][jtype]*t -
+ ljsw2[itype][jtype]*tsq/2.0 - ljsw3[itype][jtype]*tsq*t/3.0 -
+ ljsw4[itype][jtype]*tsq*tsq/4.0 - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSmoothOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJSmooth::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lj_smooth_omp.h b/src/USER-OMP/pair_lj_smooth_omp.h
new file mode 100644
index 0000000000..de27a4008d
--- /dev/null
+++ b/src/USER-OMP/pair_lj_smooth_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/smooth/omp,PairLJSmoothOMP)
+
+#else
+
+#ifndef LMP_PAIR_LJ_SMOOTH_OMP_H
+#define LMP_PAIR_LJ_SMOOTH_OMP_H
+
+#include "pair_lj_smooth.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLJSmoothOMP : public PairLJSmooth, public ThrOMP {
+
+ public:
+ PairLJSmoothOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_lubricate_omp.cpp b/src/USER-OMP/pair_lubricate_omp.cpp
new file mode 100644
index 0000000000..d45e0bf1b6
--- /dev/null
+++ b/src/USER-OMP/pair_lubricate_omp.cpp
@@ -0,0 +1,328 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lubricate_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "update.h"
+#include "neighbor.h"
+#include "random_mars.h"
+#include "neigh_list.h"
+
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+/* ---------------------------------------------------------------------- */
+
+PairLubricateOMP::PairLubricateOMP(LAMMPS *lmp) :
+ PairLubricate(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+ random_thr = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLubricateOMP::~PairLubricateOMP()
+{
+ if (random_thr) {
+ for (int i=1; i < comm->nthreads; ++i)
+ delete random_thr[i];
+
+ delete[] random_thr;
+ random_thr = NULL;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLubricateOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ if (!random_thr)
+ random_thr = new RanMars*[nthreads];
+
+ random_thr[0] = random;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (random_thr && tid > 0)
+ random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me
+ + comm->nprocs*tid);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces and torques into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairLubricateOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz;
+ double rsq,r,h_sep,radi,tfmag;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3;
+ double vt1,vt2,vt3,w1,w2,w3,v_shear1,v_shear2,v_shear3;
+ double omega_t_1,omega_t_2,omega_t_3;
+ double n_cross_omega_t_1,n_cross_omega_t_2,n_cross_omega_t_3;
+ double wr1,wr2,wr3,wnnr,wn1,wn2,wn3;
+ double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3;
+ double a_squeeze,a_shear,a_pump,a_twist;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **omega = atom->omega;
+ double *radius = atom->radius;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double vxmu2f = force->vxmu2f;
+ RanMars &rng = *random_thr[tid];
+
+ double prethermostat = sqrt(2.0 * force->boltz * t_target / update->dt);
+ prethermostat *= sqrt(force->vxmu2f/force->ftm2v/force->mvv2e);
+
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ a_squeeze = a_shear = a_pump = a_twist = 0.0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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]) {
+
+ r = sqrt(rsq);
+
+ // relative translational velocity
+
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component N.(v1-v2) = nn.(v1-v2)
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vnnr /= r;
+ vn1 = delx*vnnr / r;
+ vn2 = dely*vnnr / r;
+ vn3 = delz*vnnr / r;
+
+ // tangential component -P.(v1-v2)
+ // P = (I - nn) where n is vector between centers
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // additive rotational velocity = omega_1 + omega_2
+
+ w1 = omega[i][0] + omega[j][0];
+ w2 = omega[i][1] + omega[j][1];
+ w3 = omega[i][2] + omega[j][2];
+
+ // relative velocities n X P . (v1-v2) = n X (I-nn) . (v1-v2)
+
+ v_shear1 = (dely*vt3 - delz*vt2) / r;
+ v_shear2 = -(delx*vt3 - delz*vt1) / r;
+ v_shear3 = (delx*vt2 - dely*vt1) / r;
+
+ // relative rotation rate P.(omega1 + omega2)
+
+ omega_t_1 = w1 - delx*(delx*w1) / rsq;
+ omega_t_2 = w2 - dely*(dely*w2) / rsq;
+ omega_t_3 = w3 - delz*(delz*w3) / rsq;
+
+ // n X omega_t
+
+ n_cross_omega_t_1 = (dely*omega_t_3 - delz*omega_t_2) / r;
+ n_cross_omega_t_2 = -(delx*omega_t_3 - delz*omega_t_1) / r;
+ n_cross_omega_t_3 = (delx*omega_t_2 - dely*omega_t_1) / r;
+
+ // N.(w1-w2) and P.(w1-w2)
+
+ wr1 = omega[i][0] - omega[j][0];
+ wr2 = omega[i][1] - omega[j][1];
+ wr3 = omega[i][2] - omega[j][2];
+
+ wnnr = wr1*delx + wr2*dely + wr3*delz;
+ wn1 = delx*wnnr / rsq;
+ wn2 = dely*wnnr / rsq;
+ wn3 = delz*wnnr / rsq;
+
+ P_dot_wrel_1 = wr1 - delx*(delx*wr1)/rsq;
+ P_dot_wrel_2 = wr2 - dely*(dely*wr2)/rsq;
+ P_dot_wrel_3 = wr3 - delz*(delz*wr3)/rsq;
+
+ // compute components of pair-hydro
+
+ h_sep = r - 2.0*radi;
+
+ if (flag1)
+ a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep);
+ if (flag2)
+ a_shear = (MY_PI*mu*2.*radi/2.0) *
+ log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0;
+ if (flag3)
+ a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) *
+ ((3.0/20.0) * log(2.0*radi/2.0/h_sep) +
+ (63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep));
+ if (flag4)
+ a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) *
+ (h_sep/2.0/radi) * log(2.0/(2.0*h_sep));
+
+ if (h_sep >= cut_inner[itype][jtype]) {
+ fx = -a_squeeze*vn1 - a_shear*(2.0/r)*(2.0/r)*vt1 +
+ (2.0/r)*a_shear*n_cross_omega_t_1;
+ fy = -a_squeeze*vn2 - a_shear*(2.0/r)*(2.0/r)*vt2 +
+ (2.0/r)*a_shear*n_cross_omega_t_2;
+ fz = -a_squeeze*vn3 - a_shear*(2.0/r)*(2.0/r)*vt3 +
+ (2.0/r)*a_shear*n_cross_omega_t_3;
+ fx *= vxmu2f;
+ fy *= vxmu2f;
+ fz *= vxmu2f;
+
+ // add in thermostat force
+
+ tfmag = prethermostat*sqrt(a_squeeze)*(rng.uniform()-0.5);
+ fx -= tfmag * delx/r;
+ fy -= tfmag * dely/r;
+ fz -= tfmag * delz/r;
+
+ tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 -
+ a_pump*P_dot_wrel_1 - a_twist*wn1;
+ ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 -
+ a_pump*P_dot_wrel_2 - a_twist*wn2;
+ tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 -
+ a_pump*P_dot_wrel_3 - a_twist*wn3;
+ torque[i][0] += vxmu2f * tx;
+ torque[i][1] += vxmu2f * ty;
+ torque[i][2] += vxmu2f * tz;
+
+ } else {
+ a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) *
+ (2.0*radi/4.0/cut_inner[itype][jtype]);
+ fpair = -a_squeeze*vnnr;
+ fpair *= vxmu2f;
+
+ // add in thermostat force
+
+ fpair -= prethermostat*sqrt(a_squeeze)*(rng.uniform()-0.5);
+
+ fx = fpair * delx/r;
+ fy = fpair * dely/r;
+ fz = fpair * delz/r;
+ }
+
+ f[i][0] += fx;
+ f[i][1] += fy;
+ f[i][2] += fz;
+
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fx;
+ f[j][1] -= fy;
+ f[j][2] -= fz;
+
+ if (h_sep >= cut_inner[itype][jtype]) {
+ tx = -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 +
+ a_pump*P_dot_wrel_1 + a_twist*wn1;
+ ty = -(2.0/r)*a_shear*v_shear2 - a_shear*omega_t_2 +
+ a_pump*P_dot_wrel_2 + a_twist*wn2;
+ tz = -(2.0/r)*a_shear*v_shear3 - a_shear*omega_t_3 +
+ a_pump*P_dot_wrel_3 + a_twist*wn3;
+ torque[j][0] += vxmu2f * tx;
+ torque[j][1] += vxmu2f * ty;
+ torque[j][2] += vxmu2f * tz;
+ }
+ }
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLubricateOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLubricate::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_lubricate_omp.h b/src/USER-OMP/pair_lubricate_omp.h
new file mode 100644
index 0000000000..d36d190463
--- /dev/null
+++ b/src/USER-OMP/pair_lubricate_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lubricate/omp,PairLubricateOMP)
+
+#else
+
+#ifndef LMP_PAIR_LUBRICATE_OMP_H
+#define LMP_PAIR_LUBRICATE_OMP_H
+
+#include "pair_lubricate.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairLubricateOMP : public PairLubricate, public ThrOMP {
+
+ public:
+ PairLubricateOMP(class LAMMPS *);
+ virtual ~PairLubricateOMP();
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ class RanMars **random_thr;
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_morse_omp.cpp b/src/USER-OMP/pair_morse_omp.cpp
new file mode 100644
index 0000000000..a53e35a977
--- /dev/null
+++ b/src/USER-OMP/pair_morse_omp.cpp
@@ -0,0 +1,160 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_morse_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairMorseOMP::PairMorseOMP(LAMMPS *lmp) :
+ PairMorse(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMorseOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairMorseOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,dr,dexp,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ r = sqrt(rsq);
+ dr = r - r0[itype][jtype];
+ dexp = exp(-alpha[itype][jtype] * dr);
+ fpair = factor_lj * morse1[itype][jtype] * (dexp*dexp - dexp) / r;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = d0[itype][jtype] * (dexp*dexp - 2.0*dexp) -
+ offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairMorseOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairMorse::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_morse_omp.h b/src/USER-OMP/pair_morse_omp.h
new file mode 100644
index 0000000000..a966e6f11f
--- /dev/null
+++ b/src/USER-OMP/pair_morse_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(morse/omp,PairMorseOMP)
+
+#else
+
+#ifndef LMP_PAIR_MORSE_OMP_H
+#define LMP_PAIR_MORSE_OMP_H
+
+#include "pair_morse.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairMorseOMP : public PairMorse, public ThrOMP {
+
+ public:
+ PairMorseOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_peri_lps_omp.cpp b/src/USER-OMP/pair_peri_lps_omp.cpp
new file mode 100644
index 0000000000..7cb1e83086
--- /dev/null
+++ b/src/USER-OMP/pair_peri_lps_omp.cpp
@@ -0,0 +1,456 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "float.h"
+#include "pair_peri_lps_omp.h"
+#include "fix.h"
+#include "fix_peri_neigh.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "force.h"
+#include "memory.h"
+#include "lattice.h"
+#include "modify.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairPeriLPSOMP::PairPeriLPSOMP(LAMMPS *lmp) :
+ PairPeriLPS(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairPeriLPSOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow bond forces array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->destroy(s0_new);
+ memory->destroy(theta);
+ nmax = atom->nmax;
+ memory->create(s0_new,nmax,"pair:s0_new");
+ memory->create(theta,nmax,"pair:theta");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairPeriLPSOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz;
+ double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0;
+ double rsq,r,dr,rk,evdwl,fpair,fbond;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double d_ij,delta,stretch;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double fxtmp,fytmp,fztmp;
+
+ double *vfrac = atom->vfrac;
+ double *s0 = atom->s0;
+ double **x0 = atom->x0;
+ double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
+ int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+ int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
+ double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
+
+ // lc = lattice constant
+ // init_style guarantees it's the same in x, y, and z
+
+ double lc = domain->lattice->xlattice;
+ double half_lc = 0.5*lc;
+ double vfrac_scale = 1.0;
+
+ // short-range forces
+
+ int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic);
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+ // need minimg() for x0 difference since not ghosted
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ xtmp0 = x0[i][0];
+ ytmp0 = x0[i][1];
+ ztmp0 = x0[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ delx0 = xtmp0 - x0[j][0];
+ dely0 = ytmp0 - x0[j][1];
+ delz0 = ztmp0 - x0[j][2];
+ if (periodic) domain->minimum_image(delx0,dely0,delz0);
+ rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
+ jtype = type[j];
+
+ r = sqrt(rsq);
+
+ // short-range interaction distance based on initial particle position
+ // 0.9 and 1.35 are constants
+
+ d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
+
+ // short-range contact forces
+ // 15 is constant taken from the EMU Theory Manual
+ // Silling, 12 May 2005, p 18
+
+ if (r < d_ij) {
+ dr = r - d_ij;
+
+ // kshort based upon short-range force constant
+ // of the bond-based theory used in PMB model
+
+ double kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) /
+ (3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]);
+ rk = (kshort * vfrac[j]) * (dr / cut[itype][jtype]);
+
+ if (r > 0.0) fpair = -(rk/r);
+ else fpair = 0.0;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl = 0.5*rk*dr;
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
+ fpair*vfrac[i],delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+
+ // wait until all threads are done since we
+ // need to distribute the work differently.
+ sync_threads();
+
+#if defined(_OPENMP)
+ // each thread works on a fixed chunk of atoms.
+ const int idelta = 1 + nlocal/comm->nthreads;
+ iifrom = tid*idelta;
+ iito = iifrom + idelta;
+ if (iito > nlocal)
+ iito = nlocal;
+#else
+ iifrom = 0;
+ iito = nlocal;
+#endif
+
+ // Compute the dilatation on each particle
+ compute_dilatation_thr(iifrom, iito);
+
+ // wait until all threads are done before communication
+ sync_threads();
+
+#if defined(_OPENMP)
+#pragma omp master
+#endif
+ { // communicate dilatation (theta) of each particle
+ comm->forward_comm_pair(this);
+ // communicate wighted volume (wvolume) upon every reneighbor
+ if (neighbor->ago == 0)
+ comm->forward_comm_fix(modify->fix[ifix_peri]);
+ }
+
+ sync_threads();
+
+ // Volume-dependent part of the energy
+ if (EFLAG) {
+ for (i = iifrom; i < iito; i++) {
+ itype = type[i];
+ if (eflag_global)
+ eng_vdwl_thr[tid] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
+ if (eflag_atom)
+ eatom_thr[tid][i] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
+ }
+ }
+
+ // loop over my particles and their partners
+ // partner list contains all bond partners, so I-J appears twice
+ // if bond already broken, skip this partner
+ // first = true if this is first neighbor of particle i
+
+ bool first;
+ double omega_minus, omega_plus;
+
+ for (i = iifrom; i < iito; ++i) {
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ xtmp0 = x0[i][0];
+ ytmp0 = x0[i][1];
+ ztmp0 = x0[i][2];
+ itype = type[i];
+ jnum = npartner[i];
+ first = true;
+
+ for (jj = 0; jj < jnum; jj++) {
+ if (partner[i][jj] == 0) continue;
+ j = atom->map(partner[i][jj]);
+
+ // check if lost a partner without first breaking bond
+
+ if (j < 0) {
+ partner[i][jj] = 0;
+ continue;
+ }
+
+ // compute force density, add to PD equation of motion
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ if (periodic) domain->minimum_image(delx,dely,delz);
+ rsq = delx*delx + dely*dely + delz*delz;
+ delx0 = xtmp0 - x0[j][0];
+ dely0 = ytmp0 - x0[j][1];
+ delz0 = ztmp0 - x0[j][2];
+ if (periodic) domain->minimum_image(delx0,dely0,delz0);
+ jtype = type[j];
+ delta = cut[itype][jtype];
+ r = sqrt(rsq);
+ dr = r - r0[i][jj];
+
+ // avoid roundoff errors
+
+ if (fabs(dr) < 2.2204e-016) dr = 0.0;
+
+ // scale vfrac[j] if particle j near the horizon
+
+ if ((fabs(r0[i][jj] - delta)) <= half_lc)
+ vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
+ (1.0 + ((delta - half_lc)/(2*half_lc) ) );
+ else vfrac_scale = 1.0;
+
+ omega_plus = influence_function(-1.0*delx0,-1.0*dely0,-1.0*delz0);
+ omega_minus = influence_function(delx0,dely0,delz0);
+ rk = ( (3.0 * bulkmodulus[itype][itype]) -
+ (5.0 * shearmodulus[itype][itype]) ) * vfrac[j] * vfrac_scale *
+ ( (omega_plus * theta[i] / wvolume[i]) +
+ ( omega_minus * theta[j] / wvolume[j] ) ) * r0[i][jj];
+ rk += 15.0 * ( shearmodulus[itype][itype] * vfrac[j] * vfrac_scale ) *
+ ( (omega_plus / wvolume[i]) + (omega_minus / wvolume[j]) ) * dr;
+
+ if (r > 0.0) fbond = -(rk/r);
+ else fbond = 0.0;
+
+ f[i][0] += delx*fbond;
+ f[i][1] += dely*fbond;
+ f[i][2] += delz*fbond;
+
+ // since I-J is double counted, set newton off & use 1/2 factor and I,I
+
+ double deviatoric_extension = dr - (theta[i]* r0[i][jj] / 3.0);
+ if (EFLAG) evdwl = 0.5 * 15 * (shearmodulus[itype][itype]/wvolume[i]) *
+ omega_plus*(deviatoric_extension * deviatoric_extension) *
+ vfrac[j] * vfrac_scale;
+ if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0,
+ 0.5*fbond*vfrac[i],delx,dely,delz,tid);
+
+ // find stretch in bond I-J and break if necessary
+ // use s0 from previous timestep
+
+ stretch = dr / r0[i][jj];
+ if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0;
+
+ // update s0 for next timestep
+
+ if (first)
+ s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch);
+ else
+ s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch));
+
+ first = false;
+ }
+ }
+
+ sync_threads();
+
+ // store new s0 (in parallel)
+ for (i = iifrom; i < iito; i++) s0[i] = s0_new[i];
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairPeriLPSOMP::compute_dilatation_thr(int ifrom, int ito)
+{
+ int i,j,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz;
+ double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0;
+ double rsq,r,dr;
+ double delta;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ double **x0 = atom->x0;
+ double *vfrac = atom->vfrac;
+ double vfrac_scale = 1.0;
+
+ double lc = domain->lattice->xlattice;
+ double half_lc = 0.5*lc;
+
+ double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
+ int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+ int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
+ double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
+
+ int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic;
+
+ // compute the dilatation theta
+
+ for (i = ifrom; i < ito; i++) {
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ xtmp0 = x0[i][0];
+ ytmp0 = x0[i][1];
+ ztmp0 = x0[i][2];
+ jnum = npartner[i];
+ theta[i] = 0.0;
+ itype = type[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+
+ // if bond already broken, skip this partner
+ if (partner[i][jj] == 0) continue;
+
+ // Look up local index of this partner particle
+ j = atom->map(partner[i][jj]);
+
+ // Skip if particle is "lost"
+ if (j < 0) continue;
+
+ // Compute force density and add to PD equation of motion
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ if (periodic) domain->minimum_image(delx,dely,delz);
+ rsq = delx*delx + dely*dely + delz*delz;
+ delx0 = xtmp0 - x0[j][0];
+ dely0 = ytmp0 - x0[j][1];
+ delz0 = ztmp0 - x0[j][2];
+ if (periodic) domain->minimum_image(delx0,dely0,delz0);
+
+ r = sqrt(rsq);
+ dr = r - r0[i][jj];
+ if (fabs(dr) < 2.2204e-016) dr = 0.0;
+
+ jtype = type[j];
+ delta = cut[itype][jtype];
+
+ // scale vfrac[j] if particle j near the horizon
+
+ if ((fabs(r0[i][jj] - delta)) <= half_lc)
+ vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
+ (1.0 + ((delta - half_lc)/(2*half_lc) ) );
+ else vfrac_scale = 1.0;
+
+ theta[i] += influence_function(delx0, dely0, delz0) * r0[i][jj] * dr *
+ vfrac[j] * vfrac_scale;
+ }
+
+ // if wvolume[i] is zero, then particle i has no bonds
+ // therefore, the dilatation is set to
+
+ if (wvolume[i] != 0.0) theta[i] = (3.0/wvolume[i]) * theta[i];
+ else theta[i] = 0;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairPeriLPSOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairPeriLPS::memory_usage();
+
+ return bytes;
+}
+
diff --git a/src/USER-OMP/pair_peri_lps_omp.h b/src/USER-OMP/pair_peri_lps_omp.h
new file mode 100644
index 0000000000..2068830ca0
--- /dev/null
+++ b/src/USER-OMP/pair_peri_lps_omp.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(peri/lps/omp,PairPeriLPSOMP)
+
+#else
+
+#ifndef LMP_PAIR_PERI_LPS_OMP_H
+#define LMP_PAIR_PERI_LPS_OMP_H
+
+#include "pair_peri_lps.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairPeriLPSOMP : public PairPeriLPS, public ThrOMP {
+
+ public:
+ PairPeriLPSOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ void compute_dilatation_thr(int ifrom, int ito);
+
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_peri_pmb_omp.cpp b/src/USER-OMP/pair_peri_pmb_omp.cpp
new file mode 100644
index 0000000000..4e46d142d9
--- /dev/null
+++ b/src/USER-OMP/pair_peri_pmb_omp.cpp
@@ -0,0 +1,312 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "float.h"
+#include "pair_peri_pmb_omp.h"
+#include "fix.h"
+#include "fix_peri_neigh.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "force.h"
+#include "memory.h"
+#include "lattice.h"
+#include "modify.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairPeriPMBOMP::PairPeriPMBOMP(LAMMPS *lmp) :
+ PairPeriPMB(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairPeriPMBOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow bond forces array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->destroy(s0_new);
+ nmax = atom->nmax;
+ memory->create(s0_new,nmax,"pair:s0_new");
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairPeriPMBOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz;
+ double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0;
+ double rsq,r,dr,rk,evdwl,fpair,fbond;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double d_ij,delta,stretch;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double fxtmp,fytmp,fztmp;
+
+ double *vfrac = atom->vfrac;
+ double *s0 = atom->s0;
+ double **x0 = atom->x0;
+ double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
+ int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+ int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
+
+ // lc = lattice constant
+ // init_style guarantees it's the same in x, y, and z
+
+ double lc = domain->lattice->xlattice;
+ double half_lc = 0.5*lc;
+ double vfrac_scale = 1.0;
+
+ // short-range forces
+
+ int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic);
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+ // need minimg() for x0 difference since not ghosted
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ xtmp0 = x0[i][0];
+ ytmp0 = x0[i][1];
+ ztmp0 = x0[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ delx0 = xtmp0 - x0[j][0];
+ dely0 = ytmp0 - x0[j][1];
+ delz0 = ztmp0 - x0[j][2];
+ if (periodic) domain->minimum_image(delx0,dely0,delz0);
+ rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
+ jtype = type[j];
+
+ r = sqrt(rsq);
+
+ // short-range interaction distance based on initial particle position
+ // 0.9 and 1.35 are constants
+
+ d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
+
+ // short-range contact forces
+ // 15 is constant taken from the EMU Theory Manual
+ // Silling, 12 May 2005, p 18
+
+ if (r < d_ij) {
+ dr = r - d_ij;
+
+ rk = (15.0 * kspring[itype][jtype] * vfrac[j]) *
+ (dr / cut[itype][jtype]);
+ if (r > 0.0) fpair = -(rk/r);
+ else fpair = 0.0;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl = 0.5*rk*dr;
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
+ fpair*vfrac[i],delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+
+ // wait until all threads are done since we
+ // need to distribute the work differently.
+ sync_threads();
+
+#if defined(_OPENMP)
+ // each thread works on a fixed chunk of atoms.
+ const int idelta = 1 + nlocal/comm->nthreads;
+ iifrom = tid*idelta;
+ iito = iifrom + idelta;
+ if (iito > nlocal)
+ iito = nlocal;
+#else
+ iifrom = 0;
+ iito = nlocal;
+#endif
+
+ // loop over my particles and their partners
+ // partner list contains all bond partners, so I-J appears twice
+ // if bond already broken, skip this partner
+ // first = true if this is first neighbor of particle i
+
+ bool first;
+
+ for (i = iifrom; i < iito; ++i) {
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jnum = npartner[i];
+ s0_new[i] = DBL_MAX;
+ first = true;
+
+ for (jj = 0; jj < jnum; jj++) {
+ if (partner[i][jj] == 0) continue;
+ j = atom->map(partner[i][jj]);
+
+ // check if lost a partner without first breaking bond
+
+ if (j < 0) {
+ partner[i][jj] = 0;
+ continue;
+ }
+
+ // compute force density, add to PD equation of motion
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ if (periodic) domain->minimum_image(delx,dely,delz);
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+ delta = cut[itype][jtype];
+ r = sqrt(rsq);
+ dr = r - r0[i][jj];
+
+ // avoid roundoff errors
+
+ if (fabs(dr) < 2.2204e-016) dr = 0.0;
+
+ // scale vfrac[j] if particle j near the horizon
+
+ if ((fabs(r0[i][jj] - delta)) <= half_lc)
+ vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
+ (1.0 + ((delta - half_lc)/(2*half_lc) ) );
+ else vfrac_scale = 1.0;
+
+ stretch = dr / r0[i][jj];
+ rk = (kspring[itype][jtype] * vfrac[j]) * vfrac_scale * stretch;
+ if (r > 0.0) fbond = -(rk/r);
+ else fbond = 0.0;
+
+ f[i][0] += delx*fbond;
+ f[i][1] += dely*fbond;
+ f[i][2] += delz*fbond;
+
+ // since I-J is double counted, set newton off & use 1/2 factor and I,I
+
+ if (EFLAG) evdwl = 0.5*rk*dr;
+ if (EVFLAG)
+ ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0,
+ 0.5*fbond*vfrac[i],delx,dely,delz,tid);
+
+ // find stretch in bond I-J and break if necessary
+ // use s0 from previous timestep
+
+ if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0;
+
+ // update s0 for next timestep
+
+ if (first)
+ s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch);
+ else
+ s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch));
+ first = false;
+ }
+ }
+
+ sync_threads();
+
+ // store new s0
+ for (i = iifrom; i < iito; i++) s0[i] = s0_new[i];
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairPeriPMBOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairPeriPMB::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_peri_pmb_omp.h b/src/USER-OMP/pair_peri_pmb_omp.h
new file mode 100644
index 0000000000..9940e5ed15
--- /dev/null
+++ b/src/USER-OMP/pair_peri_pmb_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(peri/pmb/omp,PairPeriPMBOMP)
+
+#else
+
+#ifndef LMP_PAIR_PERI_PMB_OMP_H
+#define LMP_PAIR_PERI_PMB_OMP_H
+
+#include "pair_peri_pmb.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairPeriPMBOMP : public PairPeriPMB, public ThrOMP {
+
+ public:
+ PairPeriPMBOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_rebo_omp.cpp b/src/USER-OMP/pair_rebo_omp.cpp
new file mode 100644
index 0000000000..70b5c4e8ae
--- /dev/null
+++ b/src/USER-OMP/pair_rebo_omp.cpp
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "pair_rebo_omp.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairREBOOMP::PairREBOOMP(LAMMPS *lmp) : PairAIREBOOMP(lmp) {}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairREBOOMP::settings(int narg, char **arg)
+{
+ if (narg != 0) error->all(FLERR,"Illegal pair_style command");
+
+ cutlj = 0.0;
+ ljflag = torflag = 0;
+}
diff --git a/src/USER-OMP/pair_rebo_omp.h b/src/USER-OMP/pair_rebo_omp.h
new file mode 100644
index 0000000000..4606e56ae1
--- /dev/null
+++ b/src/USER-OMP/pair_rebo_omp.h
@@ -0,0 +1,36 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(rebo/omp,PairREBOOMP)
+
+#else
+
+#ifndef LMP_PAIR_REBO_OMP_H
+#define LMP_PAIR_REBO_OMP_H
+
+#include "pair_airebo_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairREBOOMP : public PairAIREBOOMP {
+ public:
+ PairREBOOMP(class LAMMPS *);
+ virtual void settings(int, char **);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_resquared_omp.cpp b/src/USER-OMP/pair_resquared_omp.cpp
new file mode 100644
index 0000000000..4870553050
--- /dev/null
+++ b/src/USER-OMP/pair_resquared_omp.cpp
@@ -0,0 +1,210 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_resquared_omp.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "comm.h"
+#include "atom_vec_ellipsoid.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairRESquaredOMP::PairRESquaredOMP(LAMMPS *lmp) :
+ PairRESquared(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairRESquaredOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f, **torque;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ torque = atom->torque + tid*nall;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
+ else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
+ else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
+ else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces and torques into global arrays.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairRESquaredOMP::eval(double **f, double **tor, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
+ double fforce[3],ttor[3],rtor[3],r12[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ RE2Vars wi,wj;
+
+ double **x = atom->x;
+ int *ellipsoid = atom->ellipsoid;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+
+ double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itype = type[i];
+
+ // not a LJ sphere
+
+ if (lshape[itype] != 0.0) precompute_i(i,wi);
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ // r12 = center to center vector
+
+ r12[0] = x[j][0]-x[i][0];
+ r12[1] = x[j][1]-x[i][1];
+ r12[2] = x[j][2]-x[i][2];
+ rsq = MathExtra::dot3(r12,r12);
+ jtype = type[j];
+
+ // compute if less than cutoff
+
+ if (rsq < cutsq[itype][jtype]) {
+ switch (form[itype][jtype]) {
+
+ case SPHERE_SPHERE:
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ forcelj *= -r2inv;
+ if (EFLAG) one_eng =
+ r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
+ offset[itype][jtype];
+ fforce[0] = r12[0]*forcelj;
+ fforce[1] = r12[1]*forcelj;
+ fforce[2] = r12[2]*forcelj;
+ break;
+
+ case SPHERE_ELLIPSE:
+ precompute_i(j,wj);
+ if (NEWTON_PAIR || j < nlocal) {
+ one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,true);
+ tor[j][0] += rtor[0]*factor_lj;
+ tor[j][1] += rtor[1]*factor_lj;
+ tor[j][2] += rtor[2]*factor_lj;
+ } else
+ one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,false);
+ break;
+
+ case ELLIPSE_SPHERE:
+ one_eng = resquared_lj(i,j,wi,r12,rsq,fforce,ttor,true);
+ tor[i][0] += ttor[0]*factor_lj;
+ tor[i][1] += ttor[1]*factor_lj;
+ tor[i][2] += ttor[2]*factor_lj;
+ break;
+
+ default:
+ precompute_i(j,wj);
+ one_eng = resquared_analytic(i,j,wi,wj,r12,rsq,fforce,ttor,rtor);
+ tor[i][0] += ttor[0]*factor_lj;
+ tor[i][1] += ttor[1]*factor_lj;
+ tor[i][2] += ttor[2]*factor_lj;
+ if (NEWTON_PAIR || j < nlocal) {
+ tor[j][0] += rtor[0]*factor_lj;
+ tor[j][1] += rtor[1]*factor_lj;
+ tor[j][2] += rtor[2]*factor_lj;
+ }
+ break;
+ }
+
+ fforce[0] *= factor_lj;
+ fforce[1] *= factor_lj;
+ fforce[2] *= factor_lj;
+ f[i][0] += fforce[0];
+ f[i][1] += fforce[1];
+ f[i][2] += fforce[2];
+
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= fforce[0];
+ f[j][1] -= fforce[1];
+ f[j][2] -= fforce[2];
+ }
+
+ if (EFLAG) evdwl = factor_lj*one_eng;
+
+ if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fforce[0],fforce[1],fforce[2],
+ -r12[0],-r12[1],-r12[2],tid);
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairRESquaredOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairRESquared::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_resquared_omp.h b/src/USER-OMP/pair_resquared_omp.h
new file mode 100644
index 0000000000..2a50bb6dd0
--- /dev/null
+++ b/src/USER-OMP/pair_resquared_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(resquared/omp,PairRESquaredOMP)
+
+#else
+
+#ifndef LMP_PAIR_RESQUARED_OMP_H
+#define LMP_PAIR_RESQUARED_OMP_H
+
+#include "pair_resquared.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairRESquaredOMP : public PairRESquared, public ThrOMP {
+
+ public:
+ PairRESquaredOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, double **torque, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp
new file mode 100644
index 0000000000..7667efa983
--- /dev/null
+++ b/src/USER-OMP/pair_soft_omp.cpp
@@ -0,0 +1,160 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_soft_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+#define SMALL 1.0e-4
+
+/* ---------------------------------------------------------------------- */
+
+PairSoftOMP::PairSoftOMP(LAMMPS *lmp) :
+ PairSoft(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairSoftOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairSoftOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double r,rsq,arg,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ r = sqrt(rsq);
+ arg = PI/cut[itype][jtype];
+ if (r > SMALL) fpair = factor_lj * prefactor[itype][jtype] *
+ sin(arg*r) * arg/r;
+ else fpair = 0.0;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG)
+ evdwl = factor_lj * prefactor[itype][jtype] * (1.0+cos(arg*r));
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairSoftOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairSoft::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_soft_omp.h b/src/USER-OMP/pair_soft_omp.h
new file mode 100644
index 0000000000..840d874601
--- /dev/null
+++ b/src/USER-OMP/pair_soft_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(soft/omp,PairSoftOMP)
+
+#else
+
+#ifndef LMP_PAIR_SOFT_OMP_H
+#define LMP_PAIR_SOFT_OMP_H
+
+#include "pair_soft.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairSoftOMP : public PairSoft, public ThrOMP {
+
+ public:
+ PairSoftOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_sw_omp.cpp b/src/USER-OMP/pair_sw_omp.cpp
new file mode 100644
index 0000000000..5d7f1a60d7
--- /dev/null
+++ b/src/USER-OMP/pair_sw_omp.cpp
@@ -0,0 +1,212 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_sw_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairSWOMP::PairSWOMP(LAMMPS *lmp) :
+ PairSW(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairSWOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ eval<1,1>(f, ifrom, ito, tid);
+ } else {
+ eval<1,0>(f, ifrom, ito, tid);
+ }
+ } else eval<0,0>(f, ifrom, ito, tid);
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairSWOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,ii,jj,kk,jnum,jnumm1,itag,jtag;
+ int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,rsq1,rsq2;
+ double delr1[3],delr2[3],fj[3],fk[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ double fxtmp,fytmp,fztmp;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ // two-body interactions, skip half of them
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
+ jtype = map[type[j]];
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ ijparam = elem2param[itype][jtype][jtype];
+ if (rsq > params[ijparam].cutsq) continue;
+
+ twobody(¶ms[ijparam],rsq,fpair,EFLAG,evdwl);
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+
+ jnumm1 = jnum - 1;
+
+ for (jj = 0; jj < jnumm1; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
+ if (rsq1 > params[ijparam].cutsq) continue;
+
+ double fjxtmp,fjytmp,fjztmp;
+ fjxtmp = fjytmp = fjztmp = 0.0;
+
+ for (kk = jj+1; kk < jnum; kk++) {
+ k = jlist[kk];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
+ if (rsq2 > params[ikparam].cutsq) continue;
+
+ threebody(¶ms[ijparam],¶ms[ikparam],¶ms[ijkparam],
+ rsq1,rsq2,delr1,delr2,fj,fk,EFLAG,evdwl);
+
+ fxtmp -= fj[0] + fk[0];
+ fytmp -= fj[1] + fk[1];
+ fztmp -= fj[2] + fk[2];
+ fjxtmp += fj[0];
+ fjytmp += fj[1];
+ fjztmp += fj[2];
+ f[k][0] += fk[0];
+ f[k][1] += fk[1];
+ f[k][2] += fk[2];
+
+ if (EVFLAG) ev_tally3_thr(this,i,j,k,evdwl,0.0,fj,fk,delr1,delr2,tid);
+ }
+ f[j][0] += fjxtmp;
+ f[j][1] += fjytmp;
+ f[j][2] += fjztmp;
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairSWOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairSW::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_sw_omp.h b/src/USER-OMP/pair_sw_omp.h
new file mode 100644
index 0000000000..40052d7d41
--- /dev/null
+++ b/src/USER-OMP/pair_sw_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(sw/omp,PairSWOMP)
+
+#else
+
+#ifndef LMP_PAIR_SW_OMP_H
+#define LMP_PAIR_SW_OMP_H
+
+#include "pair_sw.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairSWOMP : public PairSW, public ThrOMP {
+
+ public:
+ PairSWOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_table_omp.cpp b/src/USER-OMP/pair_table_omp.cpp
new file mode 100644
index 0000000000..6b14d4c981
--- /dev/null
+++ b/src/USER-OMP/pair_table_omp.cpp
@@ -0,0 +1,202 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_table_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairTableOMP::PairTableOMP(LAMMPS *lmp) :
+ PairTable(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTableOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairTableOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype,itable;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,factor_lj,fraction,value,a,b;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ Table *tb;
+
+ union_int_float_t rsq_lookup;
+ int tlm1 = tablength - 1;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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]) {
+ tb = &tables[tabindex[itype][jtype]];
+ if (rsq < tb->innersq)
+ error->one(FLERR,"Pair distance < table inner cutoff");
+
+ if (tabstyle == LOOKUP) {
+ itable = static_cast ((rsq - tb->innersq) * tb->invdelta);
+ if (itable >= tlm1)
+ error->one(FLERR,"Pair distance > table outer cutoff");
+ fpair = factor_lj * tb->f[itable];
+ } else if (tabstyle == LINEAR) {
+ itable = static_cast ((rsq - tb->innersq) * tb->invdelta);
+ if (itable >= tlm1)
+ error->one(FLERR,"Pair distance > table outer cutoff");
+ fraction = (rsq - tb->rsq[itable]) * tb->invdelta;
+ value = tb->f[itable] + fraction*tb->df[itable];
+ fpair = factor_lj * value;
+ } else if (tabstyle == SPLINE) {
+ itable = static_cast ((rsq - tb->innersq) * tb->invdelta);
+ if (itable >= tlm1)
+ error->one(FLERR,"Pair distance > table outer cutoff");
+ b = (rsq - tb->rsq[itable]) * tb->invdelta;
+ a = 1.0 - b;
+ value = a * tb->f[itable] + b * tb->f[itable+1] +
+ ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) *
+ tb->deltasq6;
+ fpair = factor_lj * value;
+ } else {
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & tb->nmask;
+ itable >>= tb->nshiftbits;
+ fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable];
+ value = tb->f[itable] + fraction*tb->df[itable];
+ fpair = factor_lj * value;
+ }
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (tabstyle == LOOKUP)
+ evdwl = tb->e[itable];
+ else if (tabstyle == LINEAR || tabstyle == BITMAP)
+ evdwl = tb->e[itable] + fraction*tb->de[itable];
+ else
+ evdwl = a * tb->e[itable] + b * tb->e[itable+1] +
+ ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
+ tb->deltasq6;
+ evdwl *= factor_lj;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairTableOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairTable::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_table_omp.h b/src/USER-OMP/pair_table_omp.h
new file mode 100644
index 0000000000..6fd1ce74a4
--- /dev/null
+++ b/src/USER-OMP/pair_table_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(table/omp,PairTableOMP)
+
+#else
+
+#ifndef LMP_PAIR_TABLE_OMP_H
+#define LMP_PAIR_TABLE_OMP_H
+
+#include "pair_table.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairTableOMP : public PairTable, public ThrOMP {
+
+ public:
+ PairTableOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_tersoff_omp.cpp b/src/USER-OMP/pair_tersoff_omp.cpp
new file mode 100644
index 0000000000..f59a8488f7
--- /dev/null
+++ b/src/USER-OMP/pair_tersoff_omp.cpp
@@ -0,0 +1,252 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_tersoff_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffOMP::PairTersoffOMP(LAMMPS *lmp) :
+ PairTersoff(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else eval<0,0,0>(f, ifrom, ito, tid);
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairTersoffOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,k,ii,jj,kk,jnum;
+ int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,rsq1,rsq2;
+ double delr1[3],delr2[3],fi[3],fj[3],fk[3];
+ double zeta_ij,prefactor;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ double fxtmp,fytmp,fztmp;
+
+ // loop over full neighbor list of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ // two-body interactions, skip half of them
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
+ jtype = map[type[j]];
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ iparam_ij = elem2param[itype][jtype][jtype];
+ if (rsq > params[iparam_ij].cutsq) continue;
+
+ repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl);
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+
+ // three-body interactions
+ // skip immediately if I-J is not within cutoff
+ double fjxtmp,fjytmp,fjztmp;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+
+ // accumulate bondorder zeta for each i-j interaction via loop over k
+
+ fjxtmp = fjytmp = fjztmp = 0.0;
+ zeta_ij = 0.0;
+
+ for (kk = 0; kk < jnum; kk++) {
+ if (jj == kk) continue;
+ k = jlist[kk];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
+ }
+
+ // pairwise force due to zeta
+
+ force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair,prefactor,EFLAG,evdwl);
+
+ fxtmp += delr1[0]*fpair;
+ fytmp += delr1[1]*fpair;
+ fztmp += delr1[2]*fpair;
+ fjxtmp -= delr1[0]*fpair;
+ fjytmp -= delr1[1]*fpair;
+ fjztmp -= delr1[2]*fpair;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0,
+ -fpair,-delr1[0],-delr1[1],-delr1[2],tid);
+
+ // attractive term via loop over k
+
+ for (kk = 0; kk < jnum; kk++) {
+ if (jj == kk) continue;
+ k = jlist[kk];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ attractive(¶ms[iparam_ijk],prefactor,
+ rsq1,rsq2,delr1,delr2,fi,fj,fk);
+
+ fxtmp += fi[0];
+ fytmp += fi[1];
+ fztmp += fi[2];
+ fjxtmp += fj[0];
+ fjytmp += fj[1];
+ fjztmp += fj[2];
+ f[k][0] += fk[0];
+ f[k][1] += fk[1];
+ f[k][2] += fk[2];
+
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid);
+ }
+ f[j][0] += fjxtmp;
+ f[j][1] += fjytmp;
+ f[j][2] += fjztmp;
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairTersoffOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairTersoff::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_tersoff_omp.h b/src/USER-OMP/pair_tersoff_omp.h
new file mode 100644
index 0000000000..5e5dc066d2
--- /dev/null
+++ b/src/USER-OMP/pair_tersoff_omp.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tersoff/omp,PairTersoffOMP)
+
+#else
+
+#ifndef LMP_PAIR_TERSOFF_OMP_H
+#define LMP_PAIR_TERSOFF_OMP_H
+
+#include "pair_tersoff.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairTersoffOMP : public PairTersoff, public ThrOMP {
+
+ public:
+ PairTersoffOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_tersoff_zbl_omp.cpp b/src/USER-OMP/pair_tersoff_zbl_omp.cpp
new file mode 100644
index 0000000000..4265d84fb7
--- /dev/null
+++ b/src/USER-OMP/pair_tersoff_zbl_omp.cpp
@@ -0,0 +1,296 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Aidan Thompson (SNL) - original Tersoff implementation
+ David Farrell (NWU) - ZBL addition
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_tersoff_zbl_omp.h"
+#include "atom.h"
+#include "update.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "force.h"
+#include "comm.h"
+#include "memory.h"
+#include "error.h"
+
+#include "math_const.h"
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define MAXLINE 1024
+#define DELTA 4
+
+/* ----------------------------------------------------------------------
+ Fermi-like smoothing function
+------------------------------------------------------------------------- */
+
+static double F_fermi(const double r, const double expsc, const double cut)
+{
+ return 1.0 / (1.0 + exp(-expsc*(r-cut)));
+}
+
+/* ----------------------------------------------------------------------
+ Fermi-like smoothing function derivative with respect to r
+------------------------------------------------------------------------- */
+
+static double F_fermi_d(const double r, const double expsc, const double cut)
+{
+ return expsc*exp(-expsc*(r-cut)) / pow(1.0 + exp(-expsc*(r-cut)),2.0);
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffZBLOMP::PairTersoffZBLOMP(LAMMPS *lmp) : PairTersoffOMP(lmp)
+{
+ // hard-wired constants in metal or real units
+ // a0 = Bohr radius
+ // epsilon0 = permittivity of vacuum = q / energy-distance units
+ // e = unit charge
+ // 1 Kcal/mole = 0.043365121 eV
+
+ if (strcmp(update->unit_style,"metal") == 0) {
+ global_a_0 = 0.529;
+ global_epsilon_0 = 0.00552635;
+ global_e = 1.0;
+ } else if (strcmp(update->unit_style,"real") == 0) {
+ global_a_0 = 0.529;
+ global_epsilon_0 = 0.00552635 * 0.043365121;
+ global_e = 1.0;
+ } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffZBLOMP::read_file(char *file)
+{
+ int params_per_line = 21;
+ char **words = new char*[params_per_line+1];
+
+ delete [] params;
+ params = NULL;
+ nparams = 0;
+
+ // open file on proc 0
+
+ FILE *fp;
+ if (comm->me == 0) {
+ fp = fopen(file,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open Tersoff potential file %s",file);
+ error->one(FLERR,str);
+ }
+ }
+
+ // read each line out of file, skipping blank lines or leading '#'
+ // store line of params if all 3 element tags are in element list
+
+ int n,nwords,ielement,jelement,kelement;
+ char line[MAXLINE],*ptr;
+ int eof = 0;
+
+ while (1) {
+ if (comm->me == 0) {
+ ptr = fgets(line,MAXLINE,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ // strip comment, skip line if blank
+
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ nwords = atom->count_words(line);
+ if (nwords == 0) continue;
+
+ // concatenate additional lines until have params_per_line words
+
+ while (nwords < params_per_line) {
+ n = strlen(line);
+ if (comm->me == 0) {
+ ptr = fgets(&line[n],MAXLINE-n,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ nwords = atom->count_words(line);
+ }
+
+ if (nwords != params_per_line)
+ error->all(FLERR,"Incorrect format in Tersoff potential file");
+
+ // words = ptrs to all words in line
+
+ nwords = 0;
+ words[nwords++] = strtok(line," \t\n\r\f");
+ while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue;
+
+ // ielement,jelement,kelement = 1st args
+ // if all 3 args are in element list, then parse this line
+ // else skip to next line
+
+ for (ielement = 0; ielement < nelements; ielement++)
+ if (strcmp(words[0],elements[ielement]) == 0) break;
+ if (ielement == nelements) continue;
+ for (jelement = 0; jelement < nelements; jelement++)
+ if (strcmp(words[1],elements[jelement]) == 0) break;
+ if (jelement == nelements) continue;
+ for (kelement = 0; kelement < nelements; kelement++)
+ if (strcmp(words[2],elements[kelement]) == 0) break;
+ if (kelement == nelements) continue;
+
+ // load up parameter settings and error check their values
+
+ if (nparams == maxparam) {
+ maxparam += DELTA;
+ params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),
+ "pair:params");
+ }
+
+ params[nparams].ielement = ielement;
+ params[nparams].jelement = jelement;
+ params[nparams].kelement = kelement;
+ params[nparams].powerm = atof(words[3]);
+ params[nparams].gamma = atof(words[4]);
+ params[nparams].lam3 = atof(words[5]);
+ params[nparams].c = atof(words[6]);
+ params[nparams].d = atof(words[7]);
+ params[nparams].h = atof(words[8]);
+ params[nparams].powern = atof(words[9]);
+ params[nparams].beta = atof(words[10]);
+ params[nparams].lam2 = atof(words[11]);
+ params[nparams].bigb = atof(words[12]);
+ params[nparams].bigr = atof(words[13]);
+ params[nparams].bigd = atof(words[14]);
+ params[nparams].lam1 = atof(words[15]);
+ params[nparams].biga = atof(words[16]);
+ params[nparams].Z_i = atof(words[17]);
+ params[nparams].Z_j = atof(words[18]);
+ params[nparams].ZBLcut = atof(words[19]);
+ params[nparams].ZBLexpscale = atof(words[20]);
+
+ // currently only allow m exponent of 1 or 3
+
+ params[nparams].powermint = int(params[nparams].powerm);
+
+ if (
+ params[nparams].lam3 < 0.0 || params[nparams].c < 0.0 ||
+ params[nparams].d < 0.0 || params[nparams].powern < 0.0 ||
+ params[nparams].beta < 0.0 || params[nparams].lam2 < 0.0 ||
+ params[nparams].bigb < 0.0 || params[nparams].bigr < 0.0 ||
+ params[nparams].bigd < 0.0 ||
+ params[nparams].bigd > params[nparams].bigr ||
+ params[nparams].lam3 < 0.0 || params[nparams].biga < 0.0 ||
+ params[nparams].powerm - params[nparams].powermint != 0.0 ||
+ (params[nparams].powermint != 3 && params[nparams].powermint != 1) ||
+ params[nparams].gamma < 0.0 ||
+ params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 ||
+ params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0)
+ error->all(FLERR,"Illegal Tersoff parameter");
+
+ nparams++;
+ }
+
+ delete [] words;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffZBLOMP::force_zeta(Param *param, double rsq, double zeta_ij,
+ double &fforce, double &prefactor,
+ int eflag, double &eng)
+{
+ double r,fa,fa_d,bij;
+
+ r = sqrt(rsq);
+
+ fa = (r > param->bigr + param->bigd) ? 0.0 :
+ -param->bigb * exp(-param->lam2 * r) * ters_fc(r,param) *
+ F_fermi(r,param->ZBLexpscale,param->ZBLcut);
+
+ fa_d = (r > param->bigr + param->bigd) ? 0.0 :
+ param->bigb * exp(-param->lam2 * r) *
+ (param->lam2 * ters_fc(r,param) *
+ F_fermi(r,param->ZBLexpscale,param->ZBLcut) -
+ ters_fc_d(r,param) * F_fermi(r,param->ZBLexpscale,param->ZBLcut)
+ - ters_fc(r,param) * F_fermi_d(r,param->ZBLexpscale,param->ZBLcut));
+
+ bij = ters_bij(zeta_ij,param);
+ fforce = 0.5*bij*fa_d / r;
+ prefactor = -0.5*fa * ters_bij_d(zeta_ij,param);
+ if (eflag) eng = 0.5*bij*fa;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffZBLOMP::repulsive(Param *param, double rsq, double &fforce,
+ int eflag, double &eng)
+{
+ double r,tmp_fc,tmp_fc_d,tmp_exp;
+
+ // Tersoff repulsive portion
+
+ r = sqrt(rsq);
+ tmp_fc = ters_fc(r,param);
+ tmp_fc_d = ters_fc_d(r,param);
+ tmp_exp = exp(-param->lam1 * r);
+ double fforce_ters = param->biga * tmp_exp * (tmp_fc_d - tmp_fc*param->lam1);
+ double eng_ters = tmp_fc * param->biga * tmp_exp;
+
+ // ZBL repulsive portion
+
+ double esq = pow(global_e,2.0);
+ double a_ij = (0.8854*global_a_0) /
+ (pow(param->Z_i,0.23) + pow(param->Z_j,0.23));
+ double premult = (param->Z_i * param->Z_j * esq)/(4.0*MY_PI*global_epsilon_0);
+ double r_ov_a = r/a_ij;
+ double phi = 0.1818*exp(-3.2*r_ov_a) + 0.5099*exp(-0.9423*r_ov_a) +
+ 0.2802*exp(-0.4029*r_ov_a) + 0.02817*exp(-0.2016*r_ov_a);
+ double dphi = (1.0/a_ij) * (-3.2*0.1818*exp(-3.2*r_ov_a) -
+ 0.9423*0.5099*exp(-0.9423*r_ov_a) -
+ 0.4029*0.2802*exp(-0.4029*r_ov_a) -
+ 0.2016*0.02817*exp(-0.2016*r_ov_a));
+ double fforce_ZBL = premult*-pow(r,-2.0)* phi + premult*pow(r,-1.0)*dphi;
+ double eng_ZBL = premult*(1.0/r)*phi;
+
+ // combine two parts with smoothing by Fermi-like function
+
+ fforce = -(-F_fermi_d(r,param->ZBLexpscale,param->ZBLcut) * eng_ZBL +
+ (1.0 - F_fermi(r,param->ZBLexpscale,param->ZBLcut))*fforce_ZBL +
+ F_fermi_d(r,param->ZBLexpscale,param->ZBLcut)*eng_ters +
+ F_fermi(r,param->ZBLexpscale,param->ZBLcut)*fforce_ters) / r;
+
+ if (eflag)
+ eng = (1.0 - F_fermi(r,param->ZBLexpscale,param->ZBLcut))*eng_ZBL +
+ F_fermi(r,param->ZBLexpscale,param->ZBLcut)*eng_ters;
+}
+
diff --git a/src/USER-OMP/pair_tersoff_zbl_omp.h b/src/USER-OMP/pair_tersoff_zbl_omp.h
new file mode 100644
index 0000000000..84d6ef1135
--- /dev/null
+++ b/src/USER-OMP/pair_tersoff_zbl_omp.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tersoff/zbl/omp,PairTersoffZBLOMP)
+
+#else
+
+#ifndef LMP_PAIR_TERSOFF_ZBL_OMP_H
+#define LMP_PAIR_TERSOFF_ZBL_OMP_H
+
+#include "pair_tersoff_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairTersoffZBLOMP : public PairTersoffOMP {
+ public:
+ PairTersoffZBLOMP(class LAMMPS *);
+ virtual ~PairTersoffZBLOMP() {}
+
+ protected:
+ double global_a_0; // Bohr radius for Coulomb repulsion
+ double global_epsilon_0; // permittivity of vacuum for Coulomb repulsion
+ double global_e; // proton charge (negative of electron charge)
+
+ virtual void read_file(char *);
+ virtual void repulsive(Param *, double, double &, int, double &);
+ virtual void force_zeta(Param *, double, double, double &, double &, int, double &);
+
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.cpp b/src/USER-OMP/pair_yukawa_colloid_omp.cpp
new file mode 100644
index 0000000000..710ad9df18
--- /dev/null
+++ b/src/USER-OMP/pair_yukawa_colloid_omp.cpp
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_yukawa_colloid_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairYukawaColloidOMP::PairYukawaColloidOMP(LAMMPS *lmp) :
+ PairYukawaColloid(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairYukawaColloidOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairYukawaColloidOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,radi,radj;
+ double rsq,r,rinv,r2inv,screening,forceyukawa,factor;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radj = radius[j];
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ screening = exp(-kappa*(r-(radi+radj)));
+ forceyukawa = a[itype][jtype] * screening;
+
+ fpair = factor*forceyukawa * rinv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = a[itype][jtype]/kappa * screening - offset[itype][jtype];
+ evdwl *= factor;
+ }
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairYukawaColloidOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairYukawaColloid::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.h b/src/USER-OMP/pair_yukawa_colloid_omp.h
new file mode 100644
index 0000000000..9483cd15c1
--- /dev/null
+++ b/src/USER-OMP/pair_yukawa_colloid_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(yukawa/colloid/omp,PairYukawaColloidOMP)
+
+#else
+
+#ifndef LMP_PAIR_YUKAWA_COLLOID_OMP_H
+#define LMP_PAIR_YUKAWA_COLLOID_OMP_H
+
+#include "pair_yukawa_colloid.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairYukawaColloidOMP : public PairYukawaColloid, public ThrOMP {
+
+ public:
+ PairYukawaColloidOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_yukawa_omp.cpp b/src/USER-OMP/pair_yukawa_omp.cpp
new file mode 100644
index 0000000000..1380e2239c
--- /dev/null
+++ b/src/USER-OMP/pair_yukawa_omp.cpp
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_yukawa_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairYukawaOMP::PairYukawaOMP(LAMMPS *lmp) :
+ PairYukawa(lmp), ThrOMP(lmp, PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairYukawaOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ ev_setup_thr(this);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(shared)
+#endif
+ {
+ int ifrom, ito, tid;
+ double **f;
+
+ f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
+ else eval<1,1,0>(f, ifrom, ito, tid);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
+ else eval<1,0,0>(f, ifrom, ito, tid);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
+ else eval<0,0,0>(f, ifrom, ito, tid);
+ }
+
+ // reduce per thread forces into global force array.
+ data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ } // end of omp parallel region
+
+ // reduce per thread energy and virial, if requested.
+ if (evflag) ev_reduce_thr(this);
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+template
+void PairYukawaOMP::eval(double **f, int iifrom, int iito, int tid)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r,rinv,screening,forceyukawa,factor;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ 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;
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ screening = exp(-kappa*r);
+ forceyukawa = a[itype][jtype] * screening * (kappa + rinv);
+
+ fpair = factor*forceyukawa * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ evdwl = a[itype][jtype] * screening * rinv - offset[itype][jtype];
+ evdwl *= factor;
+ }
+
+ if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,tid);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairYukawaOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairYukawa::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_yukawa_omp.h b/src/USER-OMP/pair_yukawa_omp.h
new file mode 100644
index 0000000000..e363ac6d17
--- /dev/null
+++ b/src/USER-OMP/pair_yukawa_omp.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(yukawa/omp,PairYukawaOMP)
+
+#else
+
+#ifndef LMP_PAIR_YUKAWA_OMP_H
+#define LMP_PAIR_YUKAWA_OMP_H
+
+#include "pair_yukawa.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairYukawaOMP : public PairYukawa, public ThrOMP {
+
+ public:
+ PairYukawaOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ private:
+ template
+ void eval(double **f, int ifrom, int ito, int tid);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/thr_omp.cpp b/src/USER-OMP/thr_omp.cpp
index d05fae5b33..37ce1f198b 100644
--- a/src/USER-OMP/thr_omp.cpp
+++ b/src/USER-OMP/thr_omp.cpp
@@ -31,7 +31,10 @@
#include
#endif
+#include "math_const.h"
+
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -40,6 +43,7 @@ ThrOMP::ThrOMP(LAMMPS *ptr, int style) : thr_style(style), lmp(ptr)
// initialize fixed size per thread storage
eng_vdwl_thr = eng_coul_thr = eng_bond_thr = NULL;
virial_thr = NULL;
+
lmp->memory->create(eng_vdwl_thr,lmp->comm->nthreads,"thr_omp:eng_vdwl_thr");
lmp->memory->create(eng_coul_thr,lmp->comm->nthreads,"thr_omp:eng_coul_thr");
lmp->memory->create(eng_bond_thr,lmp->comm->nthreads,"thr_omp:eng_bond_thr");
@@ -48,6 +52,7 @@ ThrOMP::ThrOMP(LAMMPS *ptr, int style) : thr_style(style), lmp(ptr)
// variable size per thread, per atom storage
// the actually allocation happens via memory->grow() in ev_steup_thr()
maxeatom_thr = maxvatom_thr = 0;
+ evflag_global = evflag_atom = 0;
eatom_thr = NULL;
vatom_thr = NULL;
}
@@ -66,10 +71,13 @@ ThrOMP::~ThrOMP()
/* ---------------------------------------------------------------------- */
-void ThrOMP::ev_zero_acc_thr(int ntotal, int eflag_global, int vflag_global,
+void ThrOMP::ev_setup_acc_thr(int ntotal, int eflag_global, int vflag_global,
int eflag_atom, int vflag_atom, int nthreads)
{
int t,i;
+
+ evflag_global = (eflag_global || vflag_global);
+ evflag_atom = (eflag_atom || vflag_atom);
for (t = 0; t < nthreads; ++t) {
@@ -115,9 +123,9 @@ void ThrOMP::ev_setup_thr(Dihedral *dihed)
int ntotal = (lmp->force->newton_bond) ?
(lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
- // zero per thread accumulators
- ev_zero_acc_thr(ntotal, dihed->eflag_global, dihed->vflag_global,
- dihed->eflag_atom, dihed->vflag_atom, nthreads);
+ // set up per thread accumulators
+ ev_setup_acc_thr(ntotal, dihed->eflag_global, dihed->vflag_global,
+ dihed->eflag_atom, dihed->vflag_atom, nthreads);
}
/* ---------------------------------------------------------------------- */
@@ -139,9 +147,9 @@ void ThrOMP::ev_setup_thr(Pair *pair)
int ntotal = (lmp->force->newton) ?
(lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
- // zero per thread accumulators
- ev_zero_acc_thr(ntotal, pair->eflag_global, pair->vflag_global,
- pair->eflag_atom, pair->vflag_atom, nthreads);
+ // set up per thread accumulators
+ ev_setup_acc_thr(ntotal, pair->eflag_global, pair->vflag_global,
+ pair->eflag_atom, pair->vflag_atom, nthreads);
}
/* ----------------------------------------------------------------------
@@ -181,6 +189,44 @@ void ThrOMP::ev_reduce_thr(Dihedral *dihed)
}
}
+/* ----------------------------------------------------------------------
+ reduce the per thread accumulated E/V data into the canonical accumulators.
+------------------------------------------------------------------------- */
+void ThrOMP::ev_reduce_thr(Pair *pair)
+{
+ const int nthreads = lmp->comm->nthreads;
+ const int ntotal = (lmp->force->newton) ?
+ (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
+
+ for (int n = 0; n < nthreads; ++n) {
+ pair->eng_vdwl += eng_vdwl_thr[n];
+ pair->eng_coul += eng_coul_thr[n];
+ if (pair->vflag_either) {
+ pair->virial[0] += virial_thr[n][0];
+ pair->virial[1] += virial_thr[n][1];
+ pair->virial[2] += virial_thr[n][2];
+ pair->virial[3] += virial_thr[n][3];
+ pair->virial[4] += virial_thr[n][4];
+ pair->virial[5] += virial_thr[n][5];
+ if (pair->vflag_atom) {
+ for (int i = 0; i < ntotal; ++i) {
+ pair->vatom[i][0] += vatom_thr[n][i][0];
+ pair->vatom[i][1] += vatom_thr[n][i][1];
+ pair->vatom[i][2] += vatom_thr[n][i][2];
+ pair->vatom[i][3] += vatom_thr[n][i][3];
+ pair->vatom[i][4] += vatom_thr[n][i][4];
+ pair->vatom[i][5] += vatom_thr[n][i][5];
+ }
+ }
+ }
+ if (pair->eflag_atom) {
+ for (int i = 0; i < ntotal; ++i) {
+ pair->eatom[i] += eatom_thr[n][i];
+ }
+ }
+ }
+}
+
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into per thread global and per-atom accumulators
need i < nlocal test since called by bond_quartic and dihedral_charmm
@@ -276,43 +322,444 @@ void ThrOMP::ev_tally_thr(Pair *pair, int i, int j, int nlocal,
}
/* ----------------------------------------------------------------------
- reduce the per thread accumulated E/V data into the canonical accumulators.
+ tally eng_vdwl and virial into global and per-atom accumulators
+ for virial, have delx,dely,delz and fx,fy,fz
------------------------------------------------------------------------- */
-void ThrOMP::ev_reduce_thr(Pair *pair)
-{
- const int nthreads = lmp->comm->nthreads;
- const int ntotal = (lmp->force->newton) ?
- (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
- for (int n = 0; n < nthreads; ++n) {
- pair->eng_vdwl += eng_vdwl_thr[n];
- pair->eng_coul += eng_coul_thr[n];
- if (pair->vflag_either) {
- pair->virial[0] += virial_thr[n][0];
- pair->virial[1] += virial_thr[n][1];
- pair->virial[2] += virial_thr[n][2];
- pair->virial[3] += virial_thr[n][3];
- pair->virial[4] += virial_thr[n][4];
- pair->virial[5] += virial_thr[n][5];
- if (pair->vflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- pair->vatom[i][0] += vatom_thr[n][i][0];
- pair->vatom[i][1] += vatom_thr[n][i][1];
- pair->vatom[i][2] += vatom_thr[n][i][2];
- pair->vatom[i][3] += vatom_thr[n][i][3];
- pair->vatom[i][4] += vatom_thr[n][i][4];
- pair->vatom[i][5] += vatom_thr[n][i][5];
- }
+void ThrOMP::ev_tally_xyz_thr(Pair *pair, int i, int j, int nlocal,
+ int newton_pair, double evdwl, double ecoul,
+ double fx, double fy, double fz,
+ double delx, double dely, double delz, int tid)
+{
+ double evdwlhalf,ecoulhalf,epairhalf,v[6];
+
+ if (pair->eflag_either) {
+ if (pair->eflag_global) {
+ if (newton_pair) {
+ eng_vdwl_thr[tid] += evdwl;
+ eng_coul_thr[tid] += ecoul;
+ } else {
+ evdwlhalf = 0.5*evdwl;
+ ecoulhalf = 0.5*ecoul;
+ if (i < nlocal) {
+ eng_vdwl_thr[tid] += evdwlhalf;
+ eng_coul_thr[tid] += ecoulhalf;
+ }
+ if (j < nlocal) {
+ eng_vdwl_thr[tid] += evdwlhalf;
+ eng_coul_thr[tid] += ecoulhalf;
+ }
}
}
if (pair->eflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- pair->eatom[i] += eatom_thr[n][i];
+ epairhalf = 0.5 * (evdwl + ecoul);
+ if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf;
+ if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf;
+ }
+ }
+
+ if (pair->vflag_either) {
+ v[0] = delx*fx;
+ v[1] = dely*fy;
+ v[2] = delz*fz;
+ v[3] = delx*fy;
+ v[4] = delx*fz;
+ v[5] = dely*fz;
+
+ if (pair->vflag_global) {
+ if (newton_pair) {
+ virial_thr[tid][0] += v[0];
+ virial_thr[tid][1] += v[1];
+ virial_thr[tid][2] += v[2];
+ virial_thr[tid][3] += v[3];
+ virial_thr[tid][4] += v[4];
+ virial_thr[tid][5] += v[5];
+ } else {
+ if (i < nlocal) {
+ virial_thr[tid][0] += 0.5*v[0];
+ virial_thr[tid][1] += 0.5*v[1];
+ virial_thr[tid][2] += 0.5*v[2];
+ virial_thr[tid][3] += 0.5*v[3];
+ virial_thr[tid][4] += 0.5*v[4];
+ virial_thr[tid][5] += 0.5*v[5];
+ }
+ if (j < nlocal) {
+ virial_thr[tid][0] += 0.5*v[0];
+ virial_thr[tid][1] += 0.5*v[1];
+ virial_thr[tid][2] += 0.5*v[2];
+ virial_thr[tid][3] += 0.5*v[3];
+ virial_thr[tid][4] += 0.5*v[4];
+ virial_thr[tid][5] += 0.5*v[5];
+ }
+ }
+ }
+
+ if (pair->vflag_atom) {
+ if (newton_pair || i < nlocal) {
+ vatom_thr[tid][i][0] += 0.5*v[0];
+ vatom_thr[tid][i][1] += 0.5*v[1];
+ vatom_thr[tid][i][2] += 0.5*v[2];
+ vatom_thr[tid][i][3] += 0.5*v[3];
+ vatom_thr[tid][i][4] += 0.5*v[4];
+ vatom_thr[tid][i][5] += 0.5*v[5];
+ }
+ if (newton_pair || j < nlocal) {
+ vatom_thr[tid][j][0] += 0.5*v[0];
+ vatom_thr[tid][j][1] += 0.5*v[1];
+ vatom_thr[tid][j][2] += 0.5*v[2];
+ vatom_thr[tid][j][3] += 0.5*v[3];
+ vatom_thr[tid][j][4] += 0.5*v[4];
+ vatom_thr[tid][j][5] += 0.5*v[5];
}
}
}
}
+/* ----------------------------------------------------------------------
+ tally eng_vdwl and virial into global and per-atom accumulators
+ called by SW and hbond potentials, newton_pair is always on
+ virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk
+ ------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally3_thr(Pair *pair, int i, int j, int k, double evdwl, double ecoul,
+ double *fj, double *fk, double *drji, double *drki, int tid)
+{
+ double epairthird,v[6];
+
+ if (pair->eflag_either) {
+ if (pair->eflag_global) {
+ eng_vdwl_thr[tid] += evdwl;
+ eng_coul_thr[tid] += ecoul;
+ }
+ if (pair->eflag_atom) {
+ epairthird = THIRD * (evdwl + ecoul);
+ eatom_thr[tid][i] += epairthird;
+ eatom_thr[tid][j] += epairthird;
+ eatom_thr[tid][k] += epairthird;
+ }
+ }
+
+ if (pair->vflag_either) {
+ v[0] = drji[0]*fj[0] + drki[0]*fk[0];
+ v[1] = drji[1]*fj[1] + drki[1]*fk[1];
+ v[2] = drji[2]*fj[2] + drki[2]*fk[2];
+ v[3] = drji[0]*fj[1] + drki[0]*fk[1];
+ v[4] = drji[0]*fj[2] + drki[0]*fk[2];
+ v[5] = drji[1]*fj[2] + drki[1]*fk[2];
+
+ if (pair->vflag_global) {
+ virial_thr[tid][0] += v[0];
+ virial_thr[tid][1] += v[1];
+ virial_thr[tid][2] += v[2];
+ virial_thr[tid][3] += v[3];
+ virial_thr[tid][4] += v[4];
+ virial_thr[tid][5] += v[5];
+ }
+
+ if (pair->vflag_atom) {
+ for (int n=0; n < 6; ++n) {
+ vatom_thr[tid][i][n] += THIRD*v[n];
+ vatom_thr[tid][j][n] += THIRD*v[n];
+ vatom_thr[tid][k][n] += THIRD*v[n];
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally eng_vdwl and virial into global and per-atom accumulators
+ called by AIREBO potential, newton_pair is always on
+ ------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally4_thr(Pair *pair, int i, int j, int k, int m, double evdwl,
+ double *fi, double *fj, double *fk,
+ double *drim, double *drjm, double *drkm,int tid)
+{
+ double epairfourth,v[6];
+
+ if (pair->eflag_either) {
+ if (pair->eflag_global) eng_vdwl_thr[tid] += evdwl;
+ if (pair->eflag_atom) {
+ epairfourth = 0.25 * evdwl;
+ eatom_thr[tid][i] += epairfourth;
+ eatom_thr[tid][j] += epairfourth;
+ eatom_thr[tid][k] += epairfourth;
+ eatom_thr[tid][m] += epairfourth;
+ }
+ }
+
+ if (pair->vflag_atom) {
+ v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
+ v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
+ v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
+ v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
+ v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
+ v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
+
+ vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
+ vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
+ vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
+ vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
+ vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
+ vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
+ vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2];
+ vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally ecoul and virial into each of n atoms in list
+ called by TIP4P potential, newton_pair is always on
+ changes v values by dividing by n
+ ------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally_list_thr(Pair *pair, int n, int *list, double ecoul, double *v, int tid)
+{
+ int i,j;
+
+ if (pair->eflag_either) {
+ if (pair->eflag_global) eng_coul_thr[tid] += ecoul;
+ if (pair->eflag_atom) {
+ double epairatom = ecoul/n;
+ for (i = 0; i < n; i++) eatom_thr[tid][list[i]] += epairatom;
+ }
+ }
+
+ if (pair->vflag_either) {
+ if (pair->vflag_global) {
+ virial_thr[tid][0] += v[0];
+ virial_thr[tid][1] += v[1];
+ virial_thr[tid][2] += v[2];
+ virial_thr[tid][3] += v[3];
+ virial_thr[tid][4] += v[4];
+ virial_thr[tid][5] += v[5];
+ }
+
+ if (pair->vflag_atom) {
+ v[0] /= n;
+ v[1] /= n;
+ v[2] /= n;
+ v[3] /= n;
+ v[4] /= n;
+ v[5] /= n;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ vatom_thr[tid][j][0] += v[0];
+ vatom_thr[tid][j][1] += v[1];
+ vatom_thr[tid][j][2] += v[2];
+ vatom_thr[tid][j][3] += v[3];
+ vatom_thr[tid][j][4] += v[4];
+ vatom_thr[tid][j][5] += v[5];
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+ virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4
+ = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4
+ = vb1*f1 + vb2*f3 + (vb3+vb2)*f4
+------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally_thr(Dihedral *dihed, int i1, int i2, int i3, int i4,
+ int nlocal, int newton_bond,
+ double edihedral, double *f1, double *f3, double *f4,
+ double vb1x, double vb1y, double vb1z,
+ double vb2x, double vb2y, double vb2z,
+ double vb3x, double vb3y, double vb3z, int tid)
+{
+ double edihedralquarter,v[6];
+ int cnt;
+
+ if (dihed->eflag_either) {
+ if (dihed->eflag_global) {
+ if (newton_bond) {
+ eng_bond_thr[tid] += edihedral;
+ } else {
+ edihedralquarter = 0.25*edihedral;
+ cnt = 0;
+ if (i1 < nlocal) ++cnt;
+ if (i2 < nlocal) ++cnt;
+ if (i3 < nlocal) ++cnt;
+ if (i4 < nlocal) ++cnt;
+ eng_bond_thr[tid] += static_cast(cnt) * edihedralquarter;
+ }
+ }
+ if (dihed->eflag_atom) {
+ edihedralquarter = 0.25*edihedral;
+ if (newton_bond || i1 < nlocal) eatom_thr[tid][i1] += edihedralquarter;
+ if (newton_bond || i2 < nlocal) eatom_thr[tid][i2] += edihedralquarter;
+ if (newton_bond || i3 < nlocal) eatom_thr[tid][i3] += edihedralquarter;
+ if (newton_bond || i4 < nlocal) eatom_thr[tid][i4] += edihedralquarter;
+ }
+ }
+
+ if (dihed->vflag_either) {
+ v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0];
+ v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1];
+ v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2];
+ v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1];
+ v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2];
+ v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2];
+
+ if (dihed->vflag_global) {
+ if (newton_bond) {
+ virial_thr[tid][0] += v[0];
+ virial_thr[tid][1] += v[1];
+ virial_thr[tid][2] += v[2];
+ virial_thr[tid][3] += v[3];
+ virial_thr[tid][4] += v[4];
+ virial_thr[tid][5] += v[5];
+ } else {
+ if (i1 < nlocal) {
+ virial_thr[tid][0] += 0.25*v[0];
+ virial_thr[tid][1] += 0.25*v[1];
+ virial_thr[tid][2] += 0.25*v[2];
+ virial_thr[tid][3] += 0.25*v[3];
+ virial_thr[tid][4] += 0.25*v[4];
+ virial_thr[tid][5] += 0.25*v[5];
+ }
+ if (i2 < nlocal) {
+ virial_thr[tid][0] += 0.25*v[0];
+ virial_thr[tid][1] += 0.25*v[1];
+ virial_thr[tid][2] += 0.25*v[2];
+ virial_thr[tid][3] += 0.25*v[3];
+ virial_thr[tid][4] += 0.25*v[4];
+ virial_thr[tid][5] += 0.25*v[5];
+ }
+ if (i3 < nlocal) {
+ virial_thr[tid][0] += 0.25*v[0];
+ virial_thr[tid][1] += 0.25*v[1];
+ virial_thr[tid][2] += 0.25*v[2];
+ virial_thr[tid][3] += 0.25*v[3];
+ virial_thr[tid][4] += 0.25*v[4];
+ virial_thr[tid][5] += 0.25*v[5];
+ }
+ if (i4 < nlocal) {
+ virial_thr[tid][0] += 0.25*v[0];
+ virial_thr[tid][1] += 0.25*v[1];
+ virial_thr[tid][2] += 0.25*v[2];
+ virial_thr[tid][3] += 0.25*v[3];
+ virial_thr[tid][4] += 0.25*v[4];
+ virial_thr[tid][5] += 0.25*v[5];
+ }
+ }
+ }
+
+ if (dihed->vflag_atom) {
+ if (newton_bond || i1 < nlocal) {
+ vatom_thr[tid][i1][0] += 0.25*v[0];
+ vatom_thr[tid][i1][1] += 0.25*v[1];
+ vatom_thr[tid][i1][2] += 0.25*v[2];
+ vatom_thr[tid][i1][3] += 0.25*v[3];
+ vatom_thr[tid][i1][4] += 0.25*v[4];
+ vatom_thr[tid][i1][5] += 0.25*v[5];
+ }
+ if (newton_bond || i2 < nlocal) {
+ vatom_thr[tid][i2][0] += 0.25*v[0];
+ vatom_thr[tid][i2][1] += 0.25*v[1];
+ vatom_thr[tid][i2][2] += 0.25*v[2];
+ vatom_thr[tid][i2][3] += 0.25*v[3];
+ vatom_thr[tid][i2][4] += 0.25*v[4];
+ vatom_thr[tid][i2][5] += 0.25*v[5];
+ }
+ if (newton_bond || i3 < nlocal) {
+ vatom_thr[tid][i3][0] += 0.25*v[0];
+ vatom_thr[tid][i3][1] += 0.25*v[1];
+ vatom_thr[tid][i3][2] += 0.25*v[2];
+ vatom_thr[tid][i3][3] += 0.25*v[3];
+ vatom_thr[tid][i3][4] += 0.25*v[4];
+ vatom_thr[tid][i3][5] += 0.25*v[5];
+ }
+ if (newton_bond || i4 < nlocal) {
+ vatom_thr[tid][i4][0] += 0.25*v[0];
+ vatom_thr[tid][i4][1] += 0.25*v[1];
+ vatom_thr[tid][i4][2] += 0.25*v[2];
+ vatom_thr[tid][i4][3] += 0.25*v[3];
+ vatom_thr[tid][i4][4] += 0.25*v[4];
+ vatom_thr[tid][i4][5] += 0.25*v[5];
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally virial into per-atom accumulators
+ called by AIREBO potential, newton_pair is always on
+ fpair is magnitude of force on atom I
+------------------------------------------------------------------------- */
+
+void ThrOMP::v_tally2_thr(int i, int j, double fpair, double *drij, int tid)
+{
+ double v[6];
+
+ v[0] = 0.5 * drij[0]*drij[0]*fpair;
+ v[1] = 0.5 * drij[1]*drij[1]*fpair;
+ v[2] = 0.5 * drij[2]*drij[2]*fpair;
+ v[3] = 0.5 * drij[0]*drij[1]*fpair;
+ v[4] = 0.5 * drij[0]*drij[2]*fpair;
+ v[5] = 0.5 * drij[1]*drij[2]*fpair;
+
+ vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
+ vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
+ vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
+ vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
+}
+
+/* ----------------------------------------------------------------------
+ tally virial into per-atom accumulators
+ called by AIREBO and Tersoff potential, newton_pair is always on
+------------------------------------------------------------------------- */
+
+void ThrOMP::v_tally3_thr(int i, int j, int k, double *fi, double *fj,
+ double *drik, double *drjk, int tid)
+{
+ double v[6];
+
+ v[0] = THIRD * (drik[0]*fi[0] + drjk[0]*fj[0]);
+ v[1] = THIRD * (drik[1]*fi[1] + drjk[1]*fj[1]);
+ v[2] = THIRD * (drik[2]*fi[2] + drjk[2]*fj[2]);
+ v[3] = THIRD * (drik[0]*fi[1] + drjk[0]*fj[1]);
+ v[4] = THIRD * (drik[0]*fi[2] + drjk[0]*fj[2]);
+ v[5] = THIRD * (drik[1]*fi[2] + drjk[1]*fj[2]);
+
+ vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
+ vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
+ vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
+ vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
+ vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
+ vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
+}
+
+/* ----------------------------------------------------------------------
+ tally virial into per-atom accumulators
+ called by AIREBO potential, newton_pair is always on
+------------------------------------------------------------------------- */
+
+void ThrOMP::v_tally4_thr(int i, int j, int k, int m,
+ double *fi, double *fj, double *fk,
+ double *drim, double *drjm, double *drkm, int tid)
+{
+ double v[6];
+
+ v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
+ v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
+ v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
+ v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
+ v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
+ v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
+
+ vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
+ vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
+ vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
+ vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
+ vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
+ vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
+ vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2];
+ vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
+}
+
/* ---------------------------------------------------------------------- */
// set loop range thread id, and force array offset for threaded runs.
@@ -320,56 +767,50 @@ double **ThrOMP::loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
int inum, int nall, int nthreads)
{
#if defined(_OPENMP)
- if (nthreads > 1) {
- tid = omp_get_thread_num();
+ tid = omp_get_thread_num();
- // each thread works on a fixed chunk of atoms.
- const int idelta = 1 + inum/nthreads;
- ifrom = tid*idelta;
- ito = ifrom + idelta;
- if (ito > inum)
- ito = inum;
-
- return f + nall*tid;
-
- } else {
-#endif
- tid = 0;
- ifrom = 0;
+ // each thread works on a fixed chunk of atoms.
+ const int idelta = 1 + inum/nthreads;
+ ifrom = tid*idelta;
+ ito = ifrom + idelta;
+ if (ito > inum)
ito = inum;
- return f;
-#if defined(_OPENMP)
- }
+
+ return f + nall*tid;
+#else
+ tid = 0;
+ ifrom = 0;
+ ito = inum;
+ return f;
#endif
}
/* ---------------------------------------------------------------------- */
-// reduce per thread forces into the first part of the force
+// reduce per thread data into the first part of the data
// array that is used for the non-threaded parts and reset
-// the temporary storage to 0.0. this routine depends on the
-// forces arrays stored in this order x1,y1,z1,x2,y2,z2,...
+// the temporary storage to 0.0. this routine depends on
+// multi-dimensional arrays like force stored in this order
+// x1,y1,z1,x2,y2,z2,...
// we need to post a barrier to wait until all threads are done
-// with computing forces.
-void ThrOMP::force_reduce_thr(double *fall, int nall,
- int nthreads, int tid)
+// with writing to the array .
+void ThrOMP::data_reduce_thr(double *dall, int nall, int nthreads,
+ int ndim, int tid)
{
#if defined(_OPENMP)
// NOOP in non-threaded execution.
if (nthreads == 1) return;
#pragma omp barrier
{
- double *f;
- const int idelta = 1 + nall/nthreads;
- const int ifrom = 3*tid*idelta;
- const int ito = 3*(((ifrom + idelta) > nall) ? nall : (ifrom + idelta));
+ const int nvals = ndim*nall;
+ const int idelta = nvals/nthreads + 1;
+ const int ifrom = tid*idelta;
+ const int ito = ((ifrom + idelta) > nvals) ? nvals : (ifrom + idelta);
- for (int n = 1; n < nthreads; ++n) {
- const int toffs = 3*n*nall;
- f = fall + toffs;
- for (int m = ifrom; m < ito; ++m) {
- fall[m] += f[m];
- f[m] = 0.0;
+ for (int m = ifrom; m < ito; ++m) {
+ for (int n = 1; n < nthreads; ++n) {
+ dall[m] += dall[n*nvals + m];
+ dall[n*nvals + m] = 0.0;
}
}
}
diff --git a/src/USER-OMP/thr_omp.h b/src/USER-OMP/thr_omp.h
index 24963e91d4..9966c9de00 100644
--- a/src/USER-OMP/thr_omp.h
+++ b/src/USER-OMP/thr_omp.h
@@ -27,6 +27,13 @@ class Pair;
class Dihedral;
class ThrOMP {
+ public:
+ struct global {
+ double eng_vdwl;
+ double eng_coul;
+ double eng_bond;
+ double virial[6];
+ };
protected:
const int thr_style;
@@ -43,6 +50,7 @@ class ThrOMP {
double ***vatom_thr; // per thread per atom virial
int maxeatom_thr, maxvatom_thr;
+ int evflag_global, evflag_atom;
public:
ThrOMP(LAMMPS *, int);
@@ -50,6 +58,13 @@ class ThrOMP {
double memory_usage_thr();
+ inline void sync_threads() {
+#if defined(_OPENMP)
+#pragma omp barrier
+#endif
+ { ; }
+ };
+
protected:
// extra ev_tally work for threaded styles
void ev_setup_thr(Pair *);
@@ -60,19 +75,39 @@ class ThrOMP {
private:
// internal method to be used by multiple ev_setup_thr() methods
- void ev_zero_acc_thr(int, int, int, int, int, int);
+ void ev_setup_acc_thr(int, int, int, int, int, int);
protected:
// threading adapted versions of the ev_tally infrastructure
+ // style specific versions (need access to style class flags)
void ev_tally_thr(Pair *, int, int, int, int, double, double,
double, double, double, double, int);
+ void ev_tally_xyz_thr(Pair *, int, int, int, int, double, double,
+ double, double, double, double, double, double, int);
+ void ev_tally3_thr(Pair *, int, int, int, double, double,
+ double *, double *, double *, double *, int);
+ void ev_tally4_thr(Pair *, int, int, int, int, double,
+ double *, double *, double *,
+ double *, double *, double *, int);
+ void ev_tally_list_thr(Pair *, int, int *, double , double *, int);
+
+ void ev_tally_thr(Dihedral *, int, int, int, int, int, int, double,
+ double *, double *, double *, double, double, double,
+ double, double, double, double, double, double, int);
+
+ // style independent versions
+ void v_tally2_thr(int, int, double, double *, int);
+ void v_tally3_thr(int, int, int, double *, double *, double *, double *, int);
+ void v_tally4_thr(int, int, int, int, double *, double *, double *,
+ double *, double *, double *, int);
protected:
// set loop range, thread id, and force array offset for threaded runs.
double **loop_setup_thr(double **, int &, int &, int &, int, int, int);
- // reduce per thread forces into the first part of the force array
- void force_reduce_thr(double *, int, int, int);
+ // reduce per thread data into the first part of the array
+ void data_reduce_thr(double *, int, int, int, int);
+
};
}
From 855e2aa3538e57f1b1adf548b3f742c614efad0c Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:13:19 +0000
Subject: [PATCH 14/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7067
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-OMP/fix_qeq_comb_omp.cpp | 166 ---------
src/USER-OMP/fix_qeq_comb_omp.h | 32 --
src/USER-OMP/pair_comb_omp.cpp | 540 ------------------------------
src/USER-OMP/pair_comb_omp.h | 45 ---
4 files changed, 783 deletions(-)
delete mode 100644 src/USER-OMP/fix_qeq_comb_omp.cpp
delete mode 100644 src/USER-OMP/fix_qeq_comb_omp.h
delete mode 100644 src/USER-OMP/pair_comb_omp.cpp
delete mode 100644 src/USER-OMP/pair_comb_omp.h
diff --git a/src/USER-OMP/fix_qeq_comb_omp.cpp b/src/USER-OMP/fix_qeq_comb_omp.cpp
deleted file mode 100644
index 175bab8986..0000000000
--- a/src/USER-OMP/fix_qeq_comb_omp.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
-------------------------------------------------------------------------- */
-
-#include "lmptype.h"
-#include "mpi.h"
-#include
-#include "fix_qeq_comb_omp.h"
-#include "atom.h"
-#include "force.h"
-#include "group.h"
-#include "memory.h"
-#include "error.h"
-#include "respa.h"
-#include "update.h"
-#include "pair_comb_omp.h"
-
-#include
-
-using namespace LAMMPS_NS;
-
-/* ---------------------------------------------------------------------- */
-
-FixQEQCombOMP::FixQEQCombOMP(LAMMPS *lmp, int narg, char **arg)
- : FixQEQComb(lmp, narg, arg)
-{
- if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb/omp command");
-}
-
-/* ---------------------------------------------------------------------- */
-
-void FixQEQCombOMP::init()
-{
- if (!atom->q_flag)
- error->all(FLERR,"Fix qeq/comb/omp requires atom attribute q");
-
- comb = (PairComb *) force->pair_match("comb/omp",1);
- if (comb == NULL)
- comb = (PairComb *) force->pair_match("comb",1);
- if (comb == NULL) error->all(FLERR,"Must use pair_style comb or comb/omp with fix qeq/comb");
-
- if (strstr(update->integrate_style,"respa"))
- nlevels_respa = ((Respa *) update->integrate)->nlevels;
-
- ngroup = group->count(igroup);
- if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms");
-}
-
-/* ---------------------------------------------------------------------- */
-
-void FixQEQCombOMP::post_force(int vflag)
-{
- int i,iloop,loopmax;
- double heatpq,qmass,dtq,dtq2;
- double enegchkall,enegmaxall;
-
- if (update->ntimestep % nevery) return;
-
- // reallocate work arrays if necessary
- // qf = charge force
- // q1 = charge displacement
- // q2 = tmp storage of charge force for next iteration
-
- if (atom->nmax > nmax) {
- memory->destroy(qf);
- memory->destroy(q1);
- memory->destroy(q2);
- nmax = atom->nmax;
- memory->create(qf,nmax,"qeq:qf");
- memory->create(q1,nmax,"qeq:q1");
- memory->create(q2,nmax,"qeq:q2");
- vector_atom = qf;
- }
-
- // more loops for first-time charge equilibrium
-
- iloop = 0;
- if (firstflag) loopmax = 5000;
- else loopmax = 2000;
-
- // charge-equilibration loop
-
- if (me == 0 && fp)
- fprintf(fp,"Charge equilibration on step " BIGINT_FORMAT "\n",
- update->ntimestep);
-
- heatpq = 0.05;
- qmass = 0.000548580;
- dtq = 0.0006;
- dtq2 = 0.5*dtq*dtq/qmass;
-
- double enegchk = 0.0;
- double enegtot = 0.0;
- double enegmax = 0.0;
-
- double *q = atom->q;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
-
- for (i = 0; i < nlocal; i++)
- q1[i] = q2[i] = qf[i] = 0.0;
-
- for (iloop = 0; iloop < loopmax; iloop ++ ) {
- for (i = 0; i < nlocal; i++)
- if (mask[i] & groupbit) {
- q1[i] += qf[i]*dtq2 - heatpq*q1[i];
- q[i] += q1[i];
- }
-
- enegtot = comb->yasu_char(qf,igroup);
- enegtot /= ngroup;
- enegchk = enegmax = 0.0;
-
-#if defined(_OPENMP)
-#pragma omp parallel for private(i) default(shared)
-#endif
- for (i = 0; i < nlocal ; i++)
- if (mask[i] & groupbit) {
- q2[i] = enegtot-qf[i];
- enegmax = MAX(enegmax,fabs(q2[i]));
- enegchk += fabs(q2[i]);
- qf[i] = q2[i];
- }
-
- MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world);
- enegchk = enegchkall/ngroup;
- MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world);
- enegmax = enegmaxall;
-
- if (enegchk <= precision && enegmax <= 100.0*precision) break;
-
- if (me == 0 && fp)
- fprintf(fp," iteration: %d, enegtot %.6g, "
- "enegmax %.6g, fq deviation: %.6g\n",
- iloop,enegtot,enegmax,enegchk);
-
-#if defined(_OPENMP)
-#pragma omp parallel for private(i) default(shared)
-#endif
- for (i = 0; i < nlocal; i++)
- if (mask[i] & groupbit)
- q1[i] += qf[i]*dtq2 - heatpq*q1[i];
- }
-
- if (me == 0 && fp) {
- if (iloop == loopmax)
- fprintf(fp,"Charges did not converge in %d iterations\n",iloop);
- else
- fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n",
- iloop,enegchk);
- }
-}
-
diff --git a/src/USER-OMP/fix_qeq_comb_omp.h b/src/USER-OMP/fix_qeq_comb_omp.h
deleted file mode 100644
index 0febe6b0aa..0000000000
--- a/src/USER-OMP/fix_qeq_comb_omp.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- ----------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef FIX_CLASS
-
-FixStyle(qeq/comb/omp,FixQEQCombOMP)
-
-#else
-
-#ifndef LMP_FIX_QEQ_COMB_OMP_H
-#define LMP_FIX_QEQ_COMB_OMP_H
-
-#include "fix_qeq_comb.h"
-
-namespace LAMMPS_NS {
-
-class FixQEQCombOMP : public FixQEQComb {
- public:
- FixQEQCombOMP(class LAMMPS *, int, char **);
- virtual void init();
- virtual void post_force(int);
-};
-
-}
-
-#endif
-#endif
diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp
deleted file mode 100644
index 207c122e45..0000000000
--- a/src/USER-OMP/pair_comb_omp.cpp
+++ /dev/null
@@ -1,540 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- This software is distributed under the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
-------------------------------------------------------------------------- */
-
-#include "math.h"
-#include "pair_comb_omp.h"
-#include "atom.h"
-#include "comm.h"
-#include "group.h"
-#include "force.h"
-#include "memory.h"
-#include "neighbor.h"
-#include "neigh_list.h"
-
-using namespace LAMMPS_NS;
-
-/* ---------------------------------------------------------------------- */
-
-PairCombOMP::PairCombOMP(LAMMPS *lmp) :
- PairComb(lmp), ThrOMP(lmp, PAIR)
-{
- respa_enable = 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCombOMP::compute(int eflag, int vflag)
-{
- if (eflag || vflag) {
- ev_setup(eflag,vflag);
- ev_setup_thr(this);
- } else evflag = vflag_fdotr = vflag_atom = 0;
-
- const int nall = atom->nlocal + atom->nghost;
- const int nthreads = comm->nthreads;
- const int inum = list->inum;
-
- // grow coordination array if necessary
-
- if (atom->nmax > nmax) {
- memory->destroy(NCo);
- nmax = atom->nmax;
- memory->create(NCo,nmax,"pair:NCo");
- }
-
-#if defined(_OPENMP)
-#pragma omp parallel default(shared)
-#endif
- {
- int ifrom, ito, tid;
- double **f;
-
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
-
- if (evflag) {
- if (eflag) {
- if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
- } else {
- if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
- }
- } else eval<0,0,0>(f, ifrom, ito, tid);
-
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- } // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
-}
-
-template
-void PairCombOMP::eval(double **f, int iifrom, int iito, int tid)
-{
- int i,j,k,ii,jj,kk,jnum,iparam_i;
- int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
- double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
- double rsq,rsq1,rsq2;
- double delr1[3],delr2[3],fi[3],fj[3],fk[3];
- double zeta_ij,prefactor;
- int *ilist,*jlist,*numneigh,**firstneigh;
- int mr1,mr2,mr3;
- int rsc,inty;
- double elp_ij,filp[3],fjlp[3],fklp[3];
- double iq,jq;
- double yaself;
- double potal,fac11,fac11e;
- double vionij,fvionij,sr1,sr2,sr3,Eov,Fov;
-
- evdwl = ecoul = 0.0;
-
- double **x = atom->x;
- double *q = atom->q;
- int *tag = atom->tag;
- int *type = atom->type;
- int nlocal = atom->nlocal;
-
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
-
- yaself = vionij = fvionij = Eov = Fov = 0.0;
-
- double fxtmp,fytmp,fztmp;
- double fjxtmp,fjytmp,fjztmp;
-
- // self energy correction term: potal
-
- potal_calc(potal,fac11,fac11e);
-
- // loop over full neighbor list of my atoms
-
- for (ii = iifrom; ii < iito; ++ii) {
-
- i = ilist[ii];
- itag = tag[i];
- itype = map[type[i]];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- fxtmp = fytmp = fztmp = 0.0;
-
- iq = q[i];
- NCo[i] = 0;
- iparam_i = elem2param[itype][itype][itype];
-
- // self energy, only on i atom
-
- yaself = self(¶ms[iparam_i],iq,potal);
-
- if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,yaself,
- 0.0,0.0,0.0,0.0,0.0,tid);
-
- // two-body interactions (long and short repulsive)
-
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
- jtag = tag[j];
-
- if (itag > jtag) {
- if ((itag+jtag) % 2 == 0) continue;
- } else if (itag < jtag) {
- if ((itag+jtag) % 2 == 1) continue;
- } else {
- if (x[j][2] < ztmp) continue;
- if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
- if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
- }
-
- // Qj calculates 2-body Coulombic
-
- jtype = map[type[j]];
- jq = q[j];
-
- delx = xtmp - x[j][0];
- dely = ytmp - x[j][1];
- delz = ztmp - x[j][2];
- rsq = delx*delx + dely*dely + delz*delz;
-
- iparam_ij = elem2param[itype][jtype][jtype];
-
- // long range q-dependent
-
- if (rsq > params[iparam_ij].lcutsq) continue;
-
- inty = intype[itype][jtype];
-
- // polynomial three-point interpolation
-
- tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype);
-
- // 1/r energy and forces
-
- direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq,
- potal,fac11,fac11e,vionij,fvionij);
-
- // field correction to self energy
-
- field(¶ms[iparam_ij],rsq,iq,jq,vionij,fvionij);
-
- // polarization field
- // sums up long range forces
-
- fxtmp += delx*fvionij;
- fytmp += dely*fvionij;
- fztmp += delz*fvionij;
- f[j][0] -= delx*fvionij;
- f[j][1] -= dely*fvionij;
- f[j][2] -= delz*fvionij;
-
- if (EVFLAG)
- ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
- 0.0,vionij,fvionij,delx,dely,delz,tid);
-
- // short range q-independent
-
- if (rsq > params[iparam_ij].cutsq) continue;
-
- repulsive(¶ms[iparam_ij],rsq,fpair,EFLAG,evdwl,iq,jq);
-
- // repulsion is pure two-body, sums up pair repulsive forces
-
- fxtmp += delx*fpair;
- fytmp += dely*fpair;
- fztmp += delz*fpair;
- f[j][0] -= delx*fpair;
- f[j][1] -= dely*fpair;
- f[j][2] -= delz*fpair;
-
- if (EVFLAG)
- ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
- evdwl,0.0,fpair,delx,dely,delz,tid);
- }
-
- // accumulate coordination number information
-
- if (cor_flag) {
- int numcoor = 0;
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
- jtype = map[type[j]];
- iparam_ij = elem2param[itype][jtype][jtype];
-
- if(params[iparam_ij].hfocor > 0.0 ) {
- delr1[0] = x[j][0] - xtmp;
- delr1[1] = x[j][1] - ytmp;
- delr1[2] = x[j][2] - ztmp;
- rsq1 = vec3_dot(delr1,delr1);
-
- if (rsq1 > params[iparam_ij].cutsq) continue;
- ++numcoor;
- }
- NCo[i] = numcoor;
- }
- }
-
- // three-body interactions
- // skip immediately if I-J is not within cutoff
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
- jtype = map[type[j]];
- iparam_ij = elem2param[itype][jtype][jtype];
-
- // this Qj for q-dependent BSi
-
- jq = q[j];
-
- delr1[0] = x[j][0] - xtmp;
- delr1[1] = x[j][1] - ytmp;
- delr1[2] = x[j][2] - ztmp;
- rsq1 = vec3_dot(delr1,delr1);
-
- if (rsq1 > params[iparam_ij].cutsq) continue;
-
- // accumulate bondorder zeta for each i-j interaction via loop over k
-
- fjxtmp = fjytmp = fjztmp = 0.0;
- zeta_ij = 0.0;
- cuo_flag1 = 0; cuo_flag2 = 0;
-
- for (kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- k = jlist[kk];
- k &= NEIGHMASK;
- ktype = map[type[k]];
- iparam_ijk = elem2param[itype][jtype][ktype];
-
- delr2[0] = x[k][0] - xtmp;
- delr2[1] = x[k][1] - ytmp;
- delr2[2] = x[k][2] - ztmp;
- rsq2 = vec3_dot(delr2,delr2);
-
- if (rsq2 > params[iparam_ijk].cutsq) continue;
-
- zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
-
- if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1;
- if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1;
- }
-
- if (cuo_flag1 && cuo_flag2) cuo_flag = 1;
- else cuo_flag = 0;
-
- // pairwise force due to zeta
-
- force_zeta(¶ms[iparam_ij],rsq1,zeta_ij,fpair,
- prefactor,EFLAG,evdwl,iq,jq);
-
- // over-coordination correction for HfO2
-
- if (cor_flag && NCo[i] != 0)
- Over_cor(¶ms[iparam_ij],rsq1,NCo[i],Eov, Fov);
- evdwl += Eov;
- fpair += Fov;
-
- fxtmp += delr1[0]*fpair;
- fytmp += delr1[1]*fpair;
- fztmp += delr1[2]*fpair;
- fjxtmp -= delr1[0]*fpair;
- fjytmp -= delr1[1]*fpair;
- fjztmp -= delr1[2]*fpair;
-
- if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0,
- -fpair,-delr1[0],-delr1[1],-delr1[2],tid);
-
- // attractive term via loop over k (3-body forces)
-
- for (kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- k = jlist[kk];
- k &= NEIGHMASK;
- ktype = map[type[k]];
- iparam_ijk = elem2param[itype][jtype][ktype];
-
- delr2[0] = x[k][0] - xtmp;
- delr2[1] = x[k][1] - ytmp;
- delr2[2] = x[k][2] - ztmp;
- rsq2 = vec3_dot(delr2,delr2);
- if (rsq2 > params[iparam_ijk].cutsq) continue;
-
- for (rsc = 0; rsc < 3; rsc++)
- fi[rsc] = fj[rsc] = fk[rsc] = 0.0;
-
- attractive(¶ms[iparam_ijk],prefactor,
- rsq1,rsq2,delr1,delr2,fi,fj,fk);
-
- // 3-body LP and BB correction and forces
-
- elp_ij = elp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
- flp(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp);
-
- fxtmp += fi[0] + filp[0];
- fytmp += fi[1] + filp[1];
- fztmp += fi[2] + filp[2];
- fjxtmp += fj[0] + fjlp[0];
- fjytmp += fj[1] + fjlp[1];
- fjztmp += fj[2] + fjlp[2];
- f[k][0] += fk[0] + fklp[0];
- f[k][1] += fk[1] + fklp[1];
- f[k][2] += fk[2] + fklp[2];
-
- if (EVFLAG)
- ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
- elp_ij,0.0,0.0,0.0,0.0,0.0, tid);
- if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid);
- }
- f[j][0] += fjxtmp;
- f[j][1] += fjytmp;
- f[j][2] += fjztmp;
- }
- f[i][0] += fxtmp;
- f[i][1] += fytmp;
- f[i][2] += fztmp;
-
- if (cuo_flag) params[iparam_i].cutsq *= 0.65;
- }
- cuo_flag = 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairCombOMP::yasu_char(double *qf_fix, int &igroup)
-{
- int ii;
- double potal,fac11,fac11e;
-
- const double * const * const x = atom->x;
- const double * const q = atom->q;
- const int * const type = atom->type;
-
- const int inum = list->inum;
- const int * const ilist = list->ilist;
- const int * const numneigh = list->numneigh;
- const int * const * const firstneigh = list->firstneigh;
-
- const int * const mask = atom->mask;
- const int groupbit = group->bitmask[igroup];
-
- qf = qf_fix;
- for (ii = 0; ii < inum; ii++) {
- const int i = ilist[ii];
- if (mask[i] & groupbit)
- qf[i] = 0.0;
- }
-
- // communicating charge force to all nodes, first forward then reverse
-
- comm->forward_comm_pair(this);
-
- // self energy correction term: potal
-
- potal_calc(potal,fac11,fac11e);
-
- // loop over full neighbor list of my atoms
-#if defined(_OPENMP)
-#pragma omp parallel for private(ii) default(none) shared(potal,fac11e)
-#endif
- for (ii = 0; ii < inum; ii ++) {
- double fqi,fqj,fqij,fqji,fqjj,delr1[3],delr2[3];
- double sr1,sr2,sr3;
- int mr1,mr2,mr3;
-
- const int i = ilist[ii];
-
- if (mask[i] & groupbit) {
- fqi = fqj = fqij = fqji = fqjj = 0.0; // should not be needed.
- int itype = map[type[i]];
- const double xtmp = x[i][0];
- const double ytmp = x[i][1];
- const double ztmp = x[i][2];
- const double iq = q[i];
- const int iparam_i = elem2param[itype][itype][itype];
-
- // charge force from self energy
-
- fqi = qfo_self(¶ms[iparam_i],iq,potal);
-
- // two-body interactions
-
- const int * const jlist = firstneigh[i];
- const int jnum = numneigh[i];
-
- for (int jj = 0; jj < jnum; jj++) {
- const int j = jlist[jj] & NEIGHMASK;
- const int jtype = map[type[j]];
- double jq = q[j];
-
- delr1[0] = x[j][0] - xtmp;
- delr1[1] = x[j][1] - ytmp;
- delr1[2] = x[j][2] - ztmp;
- double rsq1 = vec3_dot(delr1,delr1);
-
- const int iparam_ij = elem2param[itype][jtype][jtype];
-
- // long range q-dependent
-
- if (rsq1 > params[iparam_ij].lcutsq) continue;
-
- const int inty = intype[itype][jtype];
-
- // polynomial three-point interpolation
-
- tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype);
-
- // 1/r charge forces
-
- qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij);
-
- // field correction to self energy and charge force
-
- qfo_field(¶ms[iparam_ij],rsq1,iq,jq,fqji,fqjj);
- fqi += jq * fqij + fqji;
-#if defined(_OPENMP)
-#pragma omp atomic
-#endif
- qf[j] += (iq * fqij + fqjj);
-
- // polarization field charge force
- // three-body interactions
-
- if (rsq1 > params[iparam_ij].cutsq) continue;
-
- double zeta_ij = 0.0;
-
- for (int kk = 0; kk < jnum; kk++) {
- if (jj == kk) continue;
- const int k = jlist[kk] & NEIGHMASK;
- const int ktype = map[type[k]];
- const int iparam_ijk = elem2param[itype][jtype][ktype];
-
- delr2[0] = x[k][0] - xtmp;
- delr2[1] = x[k][1] - ytmp;
- delr2[2] = x[k][2] - ztmp;
- const double rsq2 = vec3_dot(delr2,delr2);
-
- if (rsq2 > params[iparam_ijk].cutsq) continue;
- zeta_ij += zeta(¶ms[iparam_ijk],rsq1,rsq2,delr1,delr2);
- }
-
- // charge force in Aij and Bij
-
- qfo_short(¶ms[iparam_ij],rsq1,zeta_ij,iq,jq,fqij,fqjj);
- fqi += fqij;
-#if defined(_OPENMP)
-#pragma omp atomic
-#endif
- qf[j] += fqjj;
- }
-
-#if defined(_OPENMP)
-#pragma omp atomic
-#endif
- qf[i] += fqi;
-
- }
- }
-
- comm->reverse_comm_pair(this);
-
- // sum charge force on each node and return it
-
- double eneg = 0.0;
- for (ii = 0; ii < inum; ii++) {
- const int i = ilist[ii];
- if (mask[i] & groupbit)
- eneg += qf[i];
- }
- double enegtot;
- MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world);
- return enegtot;
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairCombOMP::memory_usage()
-{
- double bytes = memory_usage_thr();
- bytes += PairComb::memory_usage();
-
- return bytes;
-}
diff --git a/src/USER-OMP/pair_comb_omp.h b/src/USER-OMP/pair_comb_omp.h
deleted file mode 100644
index 6f020ea9ab..0000000000
--- a/src/USER-OMP/pair_comb_omp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- c++ -*- ----------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(comb/omp,PairCombOMP)
-
-#else
-
-#ifndef LMP_PAIR_COMB_OMP_H
-#define LMP_PAIR_COMB_OMP_H
-
-#include "pair_comb.h"
-#include "thr_omp.h"
-
-namespace LAMMPS_NS {
-
-class PairCombOMP : public PairComb, public ThrOMP {
-
- public:
- PairCombOMP(class LAMMPS *);
-
- virtual void compute(int, int);
- virtual double memory_usage();
-
- virtual double yasu_char(double *, int &);
-
- private:
- template
- void eval(double **f, int ifrom, int ito, int tid);
-};
-
-}
-
-#endif
-#endif
From 49573998e7143c15a448619016a87711dca8ad06 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:15:39 +0000
Subject: [PATCH 15/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7068
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-OMP/pair_rebo_omp.cpp | 33 -------------------------------
src/USER-OMP/pair_rebo_omp.h | 36 ----------------------------------
2 files changed, 69 deletions(-)
delete mode 100644 src/USER-OMP/pair_rebo_omp.cpp
delete mode 100644 src/USER-OMP/pair_rebo_omp.h
diff --git a/src/USER-OMP/pair_rebo_omp.cpp b/src/USER-OMP/pair_rebo_omp.cpp
deleted file mode 100644
index 70b5c4e8ae..0000000000
--- a/src/USER-OMP/pair_rebo_omp.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#include "pair_rebo_omp.h"
-#include "error.h"
-
-using namespace LAMMPS_NS;
-
-/* ---------------------------------------------------------------------- */
-
-PairREBOOMP::PairREBOOMP(LAMMPS *lmp) : PairAIREBOOMP(lmp) {}
-
-/* ----------------------------------------------------------------------
- global settings
-------------------------------------------------------------------------- */
-
-void PairREBOOMP::settings(int narg, char **arg)
-{
- if (narg != 0) error->all(FLERR,"Illegal pair_style command");
-
- cutlj = 0.0;
- ljflag = torflag = 0;
-}
diff --git a/src/USER-OMP/pair_rebo_omp.h b/src/USER-OMP/pair_rebo_omp.h
deleted file mode 100644
index 4606e56ae1..0000000000
--- a/src/USER-OMP/pair_rebo_omp.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(rebo/omp,PairREBOOMP)
-
-#else
-
-#ifndef LMP_PAIR_REBO_OMP_H
-#define LMP_PAIR_REBO_OMP_H
-
-#include "pair_airebo_omp.h"
-
-namespace LAMMPS_NS {
-
-class PairREBOOMP : public PairAIREBOOMP {
- public:
- PairREBOOMP(class LAMMPS *);
- virtual void settings(int, char **);
-};
-
-}
-
-#endif
-#endif
From 850a3cf8a4def085ef4d5ca127f050557c5a1be9 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:22:23 +0000
Subject: [PATCH 16/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7069
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-OMP/README | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 src/USER-OMP/README
diff --git a/src/USER-OMP/README b/src/USER-OMP/README
new file mode 100644
index 0000000000..b200fee478
--- /dev/null
+++ b/src/USER-OMP/README
@@ -0,0 +1,10 @@
+This package provides OpenMP multi-threading support and other
+optimizations of various LAMMPS pair styles, dihedral styles, and fix
+styles.
+
+See this section of the manual to get started:
+
+doc/Section_accelerate.html, sub-section 5.2
+
+The person who created this package is Axel Kohlmeyer at Temple U
+(akohlmey at gmail.com). Contact him directly if you have questions.
From d2a730bc4031e05ac80017fd352e104c07fd98ba Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 10 Oct 2011 17:29:10 +0000
Subject: [PATCH 17/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7071
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/version.h b/src/version.h
index 4fc791ad6b..ca89fa4bf8 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "11 Oct 2011"
+#define LAMMPS_VERSION "12 Oct 2011"
From d8df399c7f08b0b6adabf1d521f85b41a57b8f28 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 13 Oct 2011 13:31:47 +0000
Subject: [PATCH 18/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7088
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/Section_modify.html | 194 ++++++++++++++++++++++++----------------
doc/Section_modify.txt | 194 ++++++++++++++++++++++++----------------
2 files changed, 236 insertions(+), 152 deletions(-)
diff --git a/doc/Section_modify.html b/doc/Section_modify.html
index 8a85bd0c39..8e217b40fe 100644
--- a/doc/Section_modify.html
+++ b/doc/Section_modify.html
@@ -142,44 +142,49 @@ features that can be added in the manner just described:
10.1 Atom styles
-Classes that define an atom style are derived from the Atom class.
-The atom style determines what quantities are associated with an atom.
-A new atom style can be created if one of the existing atom styles
-does not define all the arrays you need to store and communicate with
-atoms.
+
Classes that define an atom style are derived from the AtomVec class
+and managed by the Atom class. The atom style determines what
+quantities are associated with an atom. A new atom style can be
+created if one of the existing atom styles does not define all
+the arrays you need to store and communicate with atoms.
Atom_vec_atomic.cpp is a simple example of an atom style.
Here is a brief description of methods you define in your new derived
-class. See atom.h for details.
+class. See atom_vec.h for details.
-| grow | re-allocate atom arrays to longer lengths |
-| copy | copy info for one atom to another atom's array locations |
-| pack_comm | store an atom's info in a buffer communicated every timestep |
-| pack_comm_vel | add velocity info to buffer |
-| pack_comm_one | store extra info unique to this atom style |
-| unpack_comm | retrieve an atom's info from the buffer |
-| unpack_comm_vel | also retrieve velocity info |
-| unpack_comm_one | retreive extra info unique to this atom style |
-| pack_reverse | store an atom's info in a buffer communicating partial forces |
-| pack_reverse_one | store extra info unique to this atom style |
-| unpack_reverse | retrieve an atom's info from the buffer |
-| unpack_reverse_one | retreive extra info unique to this atom style |
-| pack_border | store an atom's info in a buffer communicated on neighbor re-builds |
-| pack_border_vel | add velocity info to buffer |
-| pack_border_one | store extra info unique to this atom style |
-| unpack_border | retrieve an atom's info from the buffer |
-| unpack_border_vel | also retrieve velocity info |
-| unpack_border_one | retreive extra info unique to this atom style |
-| pack_exchange | store all an atom's info to migrate to another processor |
-| unpack_exchange | retrieve an atom's info from the buffer |
-| size_restart | number of restart quantities associated with proc's atoms |
-| pack_restart | pack atom quantities into a buffer |
-| unpack_restart | unpack atom quantities from a buffer |
-| create_atom | create an individual atom of this style |
-| data_atom | parse an atom line from the data file |
-| memory_usage | tally memory allocated by atom arrays
+ |
| init | one time setup (optional) |
+| grow | re-allocate atom arrays to longer lengths (required) |
+| grow_reset | make array pointers in Atom and AtomVec classes consistent (required) |
+| copy | copy info for one atom to another atom's array locations (required) |
+| pack_comm | store an atom's info in a buffer communicated every timestep (required) |
+| pack_comm_vel | add velocity info to communication buffer (required) |
+| pack_comm_hybrid | store extra info unique to this atom style (optional) |
+| unpack_comm | retrieve an atom's info from the buffer (required) |
+| unpack_comm_vel | also retrieve velocity info (required) |
+| unpack_comm_hybrid | retreive extra info unique to this atom style (optional) |
+| pack_reverse | store an atom's info in a buffer communicating partial forces (required) |
+| pack_reverse_hybrid | store extra info unique to this atom style (optional) |
+| unpack_reverse | retrieve an atom's info from the buffer (required) |
+| unpack_reverse_hybrid | retreive extra info unique to this atom style (optional) |
+| pack_border | store an atom's info in a buffer communicated on neighbor re-builds (required) |
+| pack_border_vel | add velocity info to buffer (required) |
+| pack_border_hybrid | store extra info unique to this atom style (optional) |
+| unpack_border | retrieve an atom's info from the buffer (required) |
+| unpack_border_vel | also retrieve velocity info (required) |
+| unpack_border_hybrid | retreive extra info unique to this atom style (optional) |
+| pack_exchange | store all an atom's info to migrate to another processor (required) |
+| unpack_exchange | retrieve an atom's info from the buffer (required) |
+| size_restart | number of restart quantities associated with proc's atoms (required) |
+| pack_restart | pack atom quantities into a buffer (required) |
+| unpack_restart | unpack atom quantities from a buffer (required) |
+| create_atom | create an individual atom of this style (required) |
+| data_atom | parse an atom line from the data file (required) |
+| data_atom_hybrid | parse additional atom info unique to this atom style (optional) |
+| data_vel | parse one line of velocity information from data file (optional) |
+| data_vel_hybrid | parse additional velocity data unique to this atom style (optional) |
+| memory_usage | tally memory allocated by atom arrays (required)
|
The constructor of the derived class sets values for several variables
@@ -200,16 +205,21 @@ add new potentials to LAMMPS.
the harmonic forms of the angle, dihedral, and improper style
commands.
-Here is a brief description of methods you define in your new derived
-bond class. See bond.h, angle.h, dihedral.h, and improper.h for
-details.
+
Here is a brief description of common methods you define in your
+new derived class. See bond.h, angle.h, dihedral.h, and improper.h
+for details and specific additional methods.
-| compute | compute the molecular interactions |
-| coeff | set coefficients for one bond type |
-| equilibrium_distance | length of bond, used by SHAKE |
-| write & read_restart | writes/reads coeffs to restart files |
-| single | force and energy of a single bond
+ |
| init | check if all coefficients are set, calls init_style (optional) |
+| init_style | check if style specific conditions are met (optional) |
+| compute | compute the molecular interactions (required) |
+| settings | apply global settings for all types (optional) |
+| coeff | set coefficients for one type (required) |
+| equilibrium_distance | length of bond, used by SHAKE (required, bond only) |
+| equilibrium_angle | opening of angle, used by SHAKE (required, angle only) |
+| write & read_restart | writes/reads coeffs to restart files (required) |
+| single | force and energy of a single bond or angle (required, bond or angle only) |
+| memory_usage | tally memory allocated by the style (optional)
|
@@ -230,14 +240,21 @@ per-atom kinetic energy.
class. See compute.h for details.
-| compute_scalar | compute a scalar quantity |
-| compute_vector | compute a vector of quantities |
-| compute_peratom | compute one or more quantities per atom |
-| pack_comm | pack a buffer with items to communicate |
-| unpack_comm | unpack the buffer |
-| pack_reverse | pack a buffer with items to reverse communicate |
-| unpack_reverse | unpack the buffer |
-| memory_usage | tally memory usage
+ |
| init | perform one time setup (required) |
+| init_list | neighbor list setup, if needed (optional) |
+| compute_scalar | compute a scalar quantity (optional) |
+| compute_vector | compute a vector of quantities (optional) |
+| compute_peratom | compute one or more quantities per atom (optional) |
+| compute_local | compute one or more quantities per processor (optional) |
+| pack_comm | pack a buffer with items to communicate (optional) |
+| unpack_comm | unpack the buffer (optional) |
+| pack_reverse | pack a buffer with items to reverse communicate (optional) |
+| unpack_reverse | unpack the buffer (optional) |
+| remove_bias | remove velocity bias from one atom (optional) |
+| remove_bias_all | remove velocity bias from all atoms in group (optional) |
+| restore_bias | restore velocity bias for one atom after remove_bias (optional) |
+| restore_bias_all | same as before, but for all atoms in group (optional) |
+| memory_usage | tally memory usage (optional)
|
@@ -295,34 +312,59 @@ implement.
derived class. See fix.h for details.
-| setmask | determines when the fix is called during the timestep |
-| init | initialization before a run |
-| setup | called immediately before the 1st timestep |
-| initial_integrate | called at very beginning of each timestep |
-| pre_exchange | called before atom exchange on re-neighboring steps |
-| pre_neighbor | called before neighbor list build |
-| post_force | called after pair & molecular forces are computed |
-| final_integrate | called at end of each timestep |
-| end_of_step | called at very end of timestep |
-| write_restart | dumps fix info to restart file |
-| restart | uses info from restart file to re-initialize the fix |
-| grow_arrays | allocate memory for atom-based arrays used by fix |
-| copy_arrays | copy atom info when an atom migrates to a new processor |
-| memory_usage | report memory used by fix |
-| pack_exchange | store atom's data in a buffer |
-| unpack_exchange | retrieve atom's data from a buffer |
-| pack_restart | store atom's data for writing to restart file |
-| unpack_restart | retrieve atom's data from a restart file buffer |
-| size_restart | size of atom's data |
-| maxsize_restart | max size of atom's data |
-| initial_integrate_respa | same as initial_integrate, but for rRESPA |
-| post_force_respa | same as post_force, but for rRESPA |
-| final_integrate_respa | same as final_integrate, but for rRESPA |
-| pack_comm | pack a buffer to communicate a per-atom quantity |
-| unpack_comm | unpack a buffer to communicate a per-atom quantity |
-| pack_reverse_comm | pack a buffer to reverse communicate a per-atom quantity |
-| unpack_reverse_comm | unpack a buffer to reverse communicate a per-atom quantity |
-| thermo | compute quantities for thermodynamic output
+ |
| setmask | determines when the fix is called during the timestep (required) |
+| init | initialization before a run (optional) |
+| setup_pre_exchange | called before atom exchange in setup (optional) |
+| setup_pre_force | called before force computation in setup (optional) |
+| setup | called immediately before the 1st timestep and after forces are computed (optional) |
+| min_setup_pre_force | like setup_pre_force, but for minimizations instead of MD runs (optional) |
+| min_setup | like setup, but for minimizations instead of MD runs (optional) |
+| initial_integrate | called at very beginning of each timestep (optional) |
+| pre_exchange | called before atom exchange on re-neighboring steps (optional) |
+| pre_neighbor | called before neighbor list build (optional) |
+| pre_force | called after pair & molecular forces are computed (optional) |
+| post_force | called after pair & molecular forces are computed and communicated (optional) |
+| final_integrate | called at end of each timestep (optional) |
+| end_of_step | called at very end of timestep (optional) |
+| write_restart | dumps fix info to restart file (optional) |
+| restart | uses info from restart file to re-initialize the fix (optional) |
+| grow_arrays | allocate memory for atom-based arrays used by fix (optional) |
+| copy_arrays | copy atom info when an atom migrates to a new processor (optional) |
+| pack_exchange | store atom's data in a buffer (optional) |
+| unpack_exchange | retrieve atom's data from a buffer (optional) |
+| pack_restart | store atom's data for writing to restart file (optional) |
+| unpack_restart | retrieve atom's data from a restart file buffer (optional) |
+| size_restart | size of atom's data (optional) |
+| maxsize_restart | max size of atom's data (optional) |
+| setup_pre_force_respa | same as setup_pre_force, but for rRESPA (optional) |
+| initial_integrate_respa | same as initial_integrate, but for rRESPA (optional) |
+| post_integrate_respa | called after the first half integration step is done in rRESPA (optional) |
+| pre_force_respa | same as pre_force, but for rRESPA (optional) |
+| post_force_respa | same as post_force, but for rRESPA (optional) |
+| final_integrate_respa | same as final_integrate, but for rRESPA (optional) |
+| min_pre_force | called after pair & molecular forces are computed in minimizer (optional) |
+| min_post_force | called after pair & molecular forces are computed and communicated in minmizer (optional) |
+| min_store | store extra data for linesearch based minimization on a LIFO stack (optional) |
+| min_pushstore | push the minimization LIFO stack one element down (optional) |
+| min_popstore | pop the minimization LIFO stack one element up (optional) |
+| min_clearstore | clear minimization LIFO stack (optional) |
+| min_step | reset or move forward on line search minimization (optional) |
+| min_dof | report number of degrees of freedom added by this fix in minimization (optional) |
+| max_alpha | report maximum allowed step size during linesearch minimization (optional) |
+| pack_comm | pack a buffer to communicate a per-atom quantity (optional) |
+| unpack_comm | unpack a buffer to communicate a per-atom quantity (optional) |
+| pack_reverse_comm | pack a buffer to reverse communicate a per-atom quantity (optional) |
+| unpack_reverse_comm | unpack a buffer to reverse communicate a per-atom quantity (optional) |
+| dof | report number of degrees of freedom removed by this fix during MD (optional) |
+| compute_scalar | return a global scalar property that the fix computes (optional) |
+| compute_vector | return a component of a vector property that the fix computes (optional) |
+| compute_array | return a component of an array property that the fix computes (optional) |
+| deform | called when the box size is changed (optional) |
+| reset_target | called when a change of the target temperature is requested during a run (optional) |
+| reset_dt | is called when a change of the time step is requested during a run (optional) |
+| modify_param | called when a fix_modify request is executed (optional) |
+| memory_usage | report memory used by fix (optional) |
+| thermo | compute quantities for thermodynamic output (optional)
|
Typically, only a small fraction of these methods are defined for a
diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt
index 662a1729a8..789761cbb2 100644
--- a/doc/Section_modify.txt
+++ b/doc/Section_modify.txt
@@ -140,43 +140,48 @@ features that can be added in the manner just described:
10.1 Atom styles :link(mod_1),h4
-Classes that define an atom style are derived from the Atom class.
-The atom style determines what quantities are associated with an atom.
-A new atom style can be created if one of the existing atom styles
-does not define all the arrays you need to store and communicate with
-atoms.
+Classes that define an atom style are derived from the AtomVec class
+and managed by the Atom class. The atom style determines what
+quantities are associated with an atom. A new atom style can be
+created if one of the existing atom styles does not define all
+the arrays you need to store and communicate with atoms.
Atom_vec_atomic.cpp is a simple example of an atom style.
Here is a brief description of methods you define in your new derived
-class. See atom.h for details.
+class. See atom_vec.h for details.
-grow: re-allocate atom arrays to longer lengths
-copy: copy info for one atom to another atom's array locations
-pack_comm: store an atom's info in a buffer communicated every timestep
-pack_comm_vel: add velocity info to buffer
-pack_comm_one: store extra info unique to this atom style
-unpack_comm: retrieve an atom's info from the buffer
-unpack_comm_vel: also retrieve velocity info
-unpack_comm_one: retreive extra info unique to this atom style
-pack_reverse: store an atom's info in a buffer communicating partial forces
-pack_reverse_one: store extra info unique to this atom style
-unpack_reverse: retrieve an atom's info from the buffer
-unpack_reverse_one: retreive extra info unique to this atom style
-pack_border: store an atom's info in a buffer communicated on neighbor re-builds
-pack_border_vel: add velocity info to buffer
-pack_border_one: store extra info unique to this atom style
-unpack_border: retrieve an atom's info from the buffer
-unpack_border_vel: also retrieve velocity info
-unpack_border_one: retreive extra info unique to this atom style
-pack_exchange: store all an atom's info to migrate to another processor
-unpack_exchange: retrieve an atom's info from the buffer
-size_restart: number of restart quantities associated with proc's atoms
-pack_restart: pack atom quantities into a buffer
-unpack_restart: unpack atom quantities from a buffer
-create_atom: create an individual atom of this style
-data_atom: parse an atom line from the data file
-memory_usage: tally memory allocated by atom arrays :tb(s=:)
+init: one time setup (optional)
+grow: re-allocate atom arrays to longer lengths (required)
+grow_reset: make array pointers in Atom and AtomVec classes consistent (required)
+copy: copy info for one atom to another atom's array locations (required)
+pack_comm: store an atom's info in a buffer communicated every timestep (required)
+pack_comm_vel: add velocity info to communication buffer (required)
+pack_comm_hybrid: store extra info unique to this atom style (optional)
+unpack_comm: retrieve an atom's info from the buffer (required)
+unpack_comm_vel: also retrieve velocity info (required)
+unpack_comm_hybrid: retreive extra info unique to this atom style (optional)
+pack_reverse: store an atom's info in a buffer communicating partial forces (required)
+pack_reverse_hybrid: store extra info unique to this atom style (optional)
+unpack_reverse: retrieve an atom's info from the buffer (required)
+unpack_reverse_hybrid: retreive extra info unique to this atom style (optional)
+pack_border: store an atom's info in a buffer communicated on neighbor re-builds (required)
+pack_border_vel: add velocity info to buffer (required)
+pack_border_hybrid: store extra info unique to this atom style (optional)
+unpack_border: retrieve an atom's info from the buffer (required)
+unpack_border_vel: also retrieve velocity info (required)
+unpack_border_hybrid: retreive extra info unique to this atom style (optional)
+pack_exchange: store all an atom's info to migrate to another processor (required)
+unpack_exchange: retrieve an atom's info from the buffer (required)
+size_restart: number of restart quantities associated with proc's atoms (required)
+pack_restart: pack atom quantities into a buffer (required)
+unpack_restart: unpack atom quantities from a buffer (required)
+create_atom: create an individual atom of this style (required)
+data_atom: parse an atom line from the data file (required)
+data_atom_hybrid: parse additional atom info unique to this atom style (optional)
+data_vel: parse one line of velocity information from data file (optional)
+data_vel_hybrid: parse additional velocity data unique to this atom style (optional)
+memory_usage: tally memory allocated by atom arrays (required) :tb(s=:)
The constructor of the derived class sets values for several variables
that you must set when defining a new atom style, which are documented
@@ -196,15 +201,20 @@ Bond_harmonic.cpp is the simplest example of a bond style. Ditto for
the harmonic forms of the angle, dihedral, and improper style
commands.
-Here is a brief description of methods you define in your new derived
-bond class. See bond.h, angle.h, dihedral.h, and improper.h for
-details.
+Here is a brief description of common methods you define in your
+new derived class. See bond.h, angle.h, dihedral.h, and improper.h
+for details and specific additional methods.
-compute: compute the molecular interactions
-coeff: set coefficients for one bond type
-equilibrium_distance: length of bond, used by SHAKE
-write & read_restart: writes/reads coeffs to restart files
-single: force and energy of a single bond :tb(s=:)
+init: check if all coefficients are set, calls {init_style} (optional)
+init_style: check if style specific conditions are met (optional)
+compute: compute the molecular interactions (required)
+settings: apply global settings for all types (optional)
+coeff: set coefficients for one type (required)
+equilibrium_distance: length of bond, used by SHAKE (required, bond only)
+equilibrium_angle: opening of angle, used by SHAKE (required, angle only)
+write & read_restart: writes/reads coeffs to restart files (required)
+single: force and energy of a single bond or angle (required, bond or angle only)
+memory_usage: tally memory allocated by the style (optional) :tb(s=:)
:line
@@ -223,14 +233,21 @@ per-atom kinetic energy.
Here is a brief description of methods you define in your new derived
class. See compute.h for details.
-compute_scalar: compute a scalar quantity
-compute_vector: compute a vector of quantities
-compute_peratom: compute one or more quantities per atom
-pack_comm: pack a buffer with items to communicate
-unpack_comm: unpack the buffer
-pack_reverse: pack a buffer with items to reverse communicate
-unpack_reverse: unpack the buffer
-memory_usage: tally memory usage :tb(s=:)
+init: perform one time setup (required)
+init_list: neighbor list setup, if needed (optional)
+compute_scalar: compute a scalar quantity (optional)
+compute_vector: compute a vector of quantities (optional)
+compute_peratom: compute one or more quantities per atom (optional)
+compute_local: compute one or more quantities per processor (optional)
+pack_comm: pack a buffer with items to communicate (optional)
+unpack_comm: unpack the buffer (optional)
+pack_reverse: pack a buffer with items to reverse communicate (optional)
+unpack_reverse: unpack the buffer (optional)
+remove_bias: remove velocity bias from one atom (optional)
+remove_bias_all: remove velocity bias from all atoms in group (optional)
+restore_bias: restore velocity bias for one atom after remove_bias (optional)
+restore_bias_all: same as before, but for all atoms in group (optional)
+memory_usage: tally memory usage (optional) :tb(s=:)
:line
@@ -283,34 +300,59 @@ implement.
Here is a brief description of methods you can define in your new
derived class. See fix.h for details.
-setmask: determines when the fix is called during the timestep
-init: initialization before a run
-setup: called immediately before the 1st timestep
-initial_integrate: called at very beginning of each timestep
-pre_exchange: called before atom exchange on re-neighboring steps
-pre_neighbor: called before neighbor list build
-post_force: called after pair & molecular forces are computed
-final_integrate: called at end of each timestep
-end_of_step: called at very end of timestep
-write_restart: dumps fix info to restart file
-restart: uses info from restart file to re-initialize the fix
-grow_arrays: allocate memory for atom-based arrays used by fix
-copy_arrays: copy atom info when an atom migrates to a new processor
-memory_usage: report memory used by fix
-pack_exchange: store atom's data in a buffer
-unpack_exchange: retrieve atom's data from a buffer
-pack_restart: store atom's data for writing to restart file
-unpack_restart: retrieve atom's data from a restart file buffer
-size_restart: size of atom's data
-maxsize_restart: max size of atom's data
-initial_integrate_respa: same as initial_integrate, but for rRESPA
-post_force_respa: same as post_force, but for rRESPA
-final_integrate_respa: same as final_integrate, but for rRESPA
-pack_comm: pack a buffer to communicate a per-atom quantity
-unpack_comm: unpack a buffer to communicate a per-atom quantity
-pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity
-unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity
-thermo: compute quantities for thermodynamic output :tb(s=:)
+setmask: determines when the fix is called during the timestep (required)
+init: initialization before a run (optional)
+setup_pre_exchange: called before atom exchange in setup (optional)
+setup_pre_force: called before force computation in setup (optional)
+setup: called immediately before the 1st timestep and after forces are computed (optional)
+min_setup_pre_force: like setup_pre_force, but for minimizations instead of MD runs (optional)
+min_setup: like setup, but for minimizations instead of MD runs (optional)
+initial_integrate: called at very beginning of each timestep (optional)
+pre_exchange: called before atom exchange on re-neighboring steps (optional)
+pre_neighbor: called before neighbor list build (optional)
+pre_force: called after pair & molecular forces are computed (optional)
+post_force: called after pair & molecular forces are computed and communicated (optional)
+final_integrate: called at end of each timestep (optional)
+end_of_step: called at very end of timestep (optional)
+write_restart: dumps fix info to restart file (optional)
+restart: uses info from restart file to re-initialize the fix (optional)
+grow_arrays: allocate memory for atom-based arrays used by fix (optional)
+copy_arrays: copy atom info when an atom migrates to a new processor (optional)
+pack_exchange: store atom's data in a buffer (optional)
+unpack_exchange: retrieve atom's data from a buffer (optional)
+pack_restart: store atom's data for writing to restart file (optional)
+unpack_restart: retrieve atom's data from a restart file buffer (optional)
+size_restart: size of atom's data (optional)
+maxsize_restart: max size of atom's data (optional)
+setup_pre_force_respa: same as setup_pre_force, but for rRESPA (optional)
+initial_integrate_respa: same as initial_integrate, but for rRESPA (optional)
+post_integrate_respa: called after the first half integration step is done in rRESPA (optional)
+pre_force_respa: same as pre_force, but for rRESPA (optional)
+post_force_respa: same as post_force, but for rRESPA (optional)
+final_integrate_respa: same as final_integrate, but for rRESPA (optional)
+min_pre_force: called after pair & molecular forces are computed in minimizer (optional)
+min_post_force: called after pair & molecular forces are computed and communicated in minmizer (optional)
+min_store: store extra data for linesearch based minimization on a LIFO stack (optional)
+min_pushstore: push the minimization LIFO stack one element down (optional)
+min_popstore: pop the minimization LIFO stack one element up (optional)
+min_clearstore: clear minimization LIFO stack (optional)
+min_step: reset or move forward on line search minimization (optional)
+min_dof: report number of degrees of freedom {added} by this fix in minimization (optional)
+max_alpha: report maximum allowed step size during linesearch minimization (optional)
+pack_comm: pack a buffer to communicate a per-atom quantity (optional)
+unpack_comm: unpack a buffer to communicate a per-atom quantity (optional)
+pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity (optional)
+unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity (optional)
+dof: report number of degrees of freedom {removed} by this fix during MD (optional)
+compute_scalar: return a global scalar property that the fix computes (optional)
+compute_vector: return a component of a vector property that the fix computes (optional)
+compute_array: return a component of an array property that the fix computes (optional)
+deform: called when the box size is changed (optional)
+reset_target: called when a change of the target temperature is requested during a run (optional)
+reset_dt: is called when a change of the time step is requested during a run (optional)
+modify_param: called when a fix_modify request is executed (optional)
+memory_usage: report memory used by fix (optional)
+thermo: compute quantities for thermodynamic output (optional) :tb(s=:)
Typically, only a small fraction of these methods are defined for a
particular fix. Setmask is mandatory, as it determines when the fix
From eae3431926f0e6ab48cc024ac4d35fee2d6cd4bd Mon Sep 17 00:00:00 2001
From: athomps
Date: Fri, 14 Oct 2011 20:16:41 +0000
Subject: [PATCH 19/47] Added note about omega
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7091 f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/pair_tersoff.html | 2 +-
doc/pair_tersoff.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html
index 96f629494a..ecab9b3a4f 100644
--- a/doc/pair_tersoff.html
+++ b/doc/pair_tersoff.html
@@ -133,7 +133,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2
potential (Tersoff_2).
LAMMPS parameter values for Tersoff_2 can be obtained as follows:
-gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of
+gamma_ijk = omega_ik, lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt
index 2f0f539e95..7150c06b91 100644
--- a/doc/pair_tersoff.txt
+++ b/doc/pair_tersoff.txt
@@ -129,7 +129,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2
potential "(Tersoff_2)"_#Tersoff_2.
LAMMPS parameter values for Tersoff_2 can be obtained as follows:
-gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of
+gamma_ijk = omega_ik, lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
From df52f93e5ebfb1dd3602520060b01e803a87ed25 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Mon, 17 Oct 2011 15:22:40 +0000
Subject: [PATCH 20/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7098
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/set.cpp | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/set.cpp b/src/set.cpp
index 507fa812f5..4e76dfa2b4 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -28,9 +28,8 @@
#include "pair.h"
#include "random_park.h"
#include "math_extra.h"
-#include "error.h"
-
#include "math_const.h"
+#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
@@ -95,7 +94,8 @@ void Set::command(int narg, char **arg)
error->all(FLERR,"Invalid value in set command");
if (fraction < 0.0 || fraction > 1.0)
error->all(FLERR,"Invalid value in set command");
- if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command");
+ if (ivalue <= 0)
+ error->all(FLERR,"Invalid random number seed in set command");
setrandom(TYPE_FRACTION);
iarg += 4;
} else if (strcmp(arg[iarg],"mol") == 0) {
@@ -165,8 +165,10 @@ void Set::command(int narg, char **arg)
dvalue = atof(arg[iarg+2]);
if (!atom->mu_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
- if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command");
- if (dvalue <= 0.0) error->all(FLERR,"Invalid dipole length in set command");
+ if (ivalue <= 0)
+ error->all(FLERR,"Invalid random number seed in set command");
+ if (dvalue <= 0.0)
+ error->all(FLERR,"Invalid dipole length in set command");
setrandom(DIPOLE_RANDOM);
iarg += 3;
} else if (strcmp(arg[iarg],"quat") == 0) {
@@ -184,7 +186,8 @@ void Set::command(int narg, char **arg)
ivalue = atoi(arg[iarg+1]);
if (!atom->ellipsoid_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
- if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command");
+ if (ivalue <= 0)
+ error->all(FLERR,"Invalid random number seed in set command");
setrandom(QUAT_RANDOM);
iarg += 2;
} else if (strcmp(arg[iarg],"diameter") == 0) {
@@ -225,11 +228,14 @@ void Set::command(int narg, char **arg)
zimage = atoi(arg[iarg+3]);
}
if (ximageflag && ximage && !domain->xperiodic)
- error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension");
+ error->all(FLERR,
+ "Cannot set non-zero image flag for non-periodic dimension");
if (yimageflag && yimage && !domain->yperiodic)
- error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension");
+ error->all(FLERR,
+ "Cannot set non-zero image flag for non-periodic dimension");
if (zimageflag && zimage && !domain->zperiodic)
- error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension");
+ error->all(FLERR,
+ "Cannot set non-zero image flag for non-periodic dimension");
set(IMAGE);
iarg += 4;
} else if (strcmp(arg[iarg],"bond") == 0) {
@@ -444,7 +450,8 @@ void Set::set(int keyword)
} else if (keyword == QUAT) {
if (atom->ellipsoid[i] < 0)
- error->one(FLERR,"Cannot set quaternion for atom that is not an ellipsoid");
+ error->one(FLERR,
+ "Cannot set quaternion for atom that is not an ellipsoid");
double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
double theta2 = MY_PI2 * wvalue/180.0;
double sintheta2 = sin(theta2);
From 55b951bed074302482b7037f8ba7e33cf76f6d8e Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Wed, 19 Oct 2011 22:43:40 +0000
Subject: [PATCH 21/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7128
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/compute_property_atom.html | 11 ++++++-----
doc/compute_property_atom.txt | 11 ++++++-----
doc/read_data.html | 13 +++++--------
doc/read_data.txt | 8 +++-----
4 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/doc/compute_property_atom.html b/doc/compute_property_atom.html
index 6390d3e029..aec547b978 100644
--- a/doc/compute_property_atom.html
+++ b/doc/compute_property_atom.html
@@ -79,12 +79,13 @@ additional quantities that are only defined for certain dump custom command are as follows.
+The additional quantities only accessible via this command, and not
+directly via the dump custom command, are as follows.
Shapex, shapey, and shapez are defined for ellipsoidal particles
and define the 3d shape of each particle. Quatw, quati, quatj,
diff --git a/doc/compute_property_atom.txt b/doc/compute_property_atom.txt
index bae2846f4e..f2a088be34 100644
--- a/doc/compute_property_atom.txt
+++ b/doc/compute_property_atom.txt
@@ -72,12 +72,13 @@ additional quantities that are only defined for certain "atom
styles"_atom_style.html. Basically, this list gives your input script
access to any per-atom quantity stored by LAMMPS.
-The values are stored in a per-atom vector or array as
-discussed below. Zeroes are stored for atoms not in the specified
-group.
+The values are stored in a per-atom vector or array as discussed
+below. Zeroes are stored for atoms not in the specified group or for
+quantities that are not defined for a particular particle in the group
+(e.g. {shapex} if the particle is not an ellipsoid).
-The additional quantities only accessible via this command (and not
-directly via the "dump custom"_dump.html command are as follows.
+The additional quantities only accessible via this command, and not
+directly via the "dump custom"_dump.html command, are as follows.
{Shapex}, {shapey}, and {shapez} are defined for ellipsoidal particles
and define the 3d shape of each particle. {Quatw}, {quati}, {quatj},
diff --git a/doc/read_data.html b/doc/read_data.html
index bd2e87918f..2eced78fe0 100644
--- a/doc/read_data.html
+++ b/doc/read_data.html
@@ -159,7 +159,7 @@ space in LAMMPS data structures for storing the new bonds.
The "ellipsoids setting is only used with atom_style
ellipsoid and specifies how many of the atoms are
finite-size ellipsoids; the remainder are point particles. See the
-discussion of ellipseflag and the Ellipsoids section below.
+discussion of ellipsoidflag and the Ellipsoids section below.
@@ -342,7 +342,7 @@ keep track of molecule assignments.
The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
-The ellipseflag determines whether the particle is a finite-size
+
The ellipsoidflag determines whether the particle is a finite-size
ellipsoid of finite size, or a point particle. Additional attributes
must be defined for each ellipsoid in the Ellipsoids section.
@@ -530,15 +530,12 @@ section must be integers (1, not 1.0).
line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk
- atom-ID = ID of atom which is an ellipsoid
+
atom-ID = ID of atom which is an ellipsoid
shapex,shapey,shapez = 3 diameters of ellipsoid (distance units)
quatw,quati,quatj,quatk = quaternion components for orientation of atom
-type = bond type (1-Nbondtype)
- atom1,atom2 = IDs of 1st,2nd atoms in bond
-
-example:
+example:
- 12 3 17 29
+ 12 1 2 1 1 0 0 0
diff --git a/doc/read_data.txt b/doc/read_data.txt
index e2d1c0437c..d023d5de6e 100644
--- a/doc/read_data.txt
+++ b/doc/read_data.txt
@@ -156,7 +156,7 @@ space in LAMMPS data structures for storing the new bonds.
The "ellipsoids" setting is only used with atom_style
ellipsoid"_atom_style.html and specifies how many of the atoms are
finite-size ellipsoids; the remainder are point particles. See the
-discussion of ellipseflag and the {Ellipsoids} section below.
+discussion of ellipsoidflag and the {Ellipsoids} section below.
:line
@@ -321,7 +321,7 @@ keep track of molecule assignments.
The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
-The ellipseflag determines whether the particle is a finite-size
+The ellipsoidflag determines whether the particle is a finite-size
ellipsoid of finite size, or a point particle. Additional attributes
must be defined for each ellipsoid in the {Ellipsoids} section.
@@ -481,10 +481,8 @@ line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk :l
atom-ID = ID of atom which is an ellipsoid
shapex,shapey,shapez = 3 diameters of ellipsoid (distance units)
quatw,quati,quatj,quatk = quaternion components for orientation of atom
-type = bond type (1-Nbondtype)
- atom1,atom2 = IDs of 1st,2nd atoms in bond :pre
example: :l
- 12 3 17 29 :pre
+ 12 1 2 1 1 0 0 0 :pre
:ule
The {Ellipsoids} section must appear if "atom_style
From f90ce18f3db4c688d7bf07cc17bf21d0e11cd250 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 00:11:49 +0000
Subject: [PATCH 22/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7133
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/CLASS2/angle_class2.cpp | 4 ++-
src/CLASS2/dihedral_class2.cpp | 21 +++++++-------
src/CLASS2/dihedral_class2.h | 1 -
src/CLASS2/improper_class2.cpp | 15 +++++-----
src/CLASS2/improper_class2.h | 1 -
src/CLASS2/pair_lj_class2.cpp | 7 +++--
src/CLASS2/pair_lj_class2_coul_cut.cpp | 7 +++--
src/CLASS2/pair_lj_class2_coul_long.cpp | 7 +++--
src/COLLOID/pair_lubricate.cpp | 15 +++++-----
src/GPU/pppm_gpu.cpp | 6 ++--
src/GRANULAR/fix_pour.cpp | 12 ++++----
src/GRANULAR/fix_pour.h | 1 -
src/GRANULAR/fix_wall_gran.cpp | 7 ++---
src/KSPACE/ewald.cpp | 24 ++++++++--------
src/KSPACE/ewald.h | 1 -
src/KSPACE/pair_born_coul_long.cpp | 7 +++--
src/KSPACE/pair_buck_coul_long.cpp | 7 +++--
src/KSPACE/pair_lj_cut_coul_long.cpp | 7 +++--
src/MANYBODY/pair_airebo.cpp | 8 +++---
src/MANYBODY/pair_airebo.h | 1 -
src/MANYBODY/pair_comb.cpp | 33 ++++++++++------------
src/MANYBODY/pair_comb.h | 1 -
src/MC/fix_gcmc.cpp | 5 ++--
src/MOLECULE/angle_charmm.cpp | 4 ++-
src/MOLECULE/angle_cosine.cpp | 4 ++-
src/MOLECULE/angle_cosine_periodic.cpp | 4 ++-
src/MOLECULE/angle_cosine_squared.cpp | 4 ++-
src/MOLECULE/angle_harmonic.cpp | 4 ++-
src/MOLECULE/angle_table.cpp | 12 ++++----
src/MOLECULE/dihedral_charmm.cpp | 13 ++++-----
src/MOLECULE/dihedral_helix.cpp | 6 ++--
src/MOLECULE/improper_harmonic.cpp | 4 ++-
src/MOLECULE/improper_umbrella.cpp | 4 ++-
src/MOLECULE/pair_hbond_dreiding_lj.cpp | 14 ++++-----
src/MOLECULE/pair_hbond_dreiding_lj.h | 1 -
src/MOLECULE/pair_hbond_dreiding_morse.cpp | 10 ++++---
src/SRD/fix_srd.cpp | 12 ++++----
src/USER-CG-CMM/angle_cg_cmm.cpp | 4 ++-
src/USER-CG-CMM/pair_cmm_common.cpp | 7 +++--
src/USER-CUDA/fix_gravity_cuda.cpp | 8 +++---
src/USER-CUDA/fix_shake_cuda.cpp | 5 ++--
src/USER-CUDA/fix_shake_cuda.h | 1 -
src/USER-CUDA/pppm_cuda.cpp | 21 +++++++-------
src/USER-EFF/atom_vec_electron.h | 1 -
src/USER-OMP/dihedral_helix_omp.cpp | 6 ++--
src/USER-OMP/pair_soft_omp.cpp | 4 ++-
src/angle.cpp | 4 +--
src/angle.h | 2 --
src/atom_vec_ellipsoid.cpp | 6 ++--
src/atom_vec_ellipsoid.h | 1 -
src/atom_vec_sphere.cpp | 10 +++----
src/atom_vec_sphere.h | 1 -
src/compute_angle_local.cpp | 5 ++--
src/compute_dihedral_local.cpp | 6 ++--
src/compute_improper_local.cpp | 6 ++--
src/compute_rdf.cpp | 7 +++--
src/dihedral.cpp | 1 -
src/dihedral.h | 2 --
src/dump_image.cpp | 32 ++++++++++-----------
src/dump_image.h | 2 --
src/fix_adapt.cpp | 9 ++++--
src/fix_deform.cpp | 4 ++-
src/fix_gravity.cpp | 5 ++--
src/fix_move.cpp | 7 ++---
src/fix_orient_fcc.cpp | 9 +++---
src/fix_orient_fcc.h | 1 -
src/fix_restrain.cpp | 5 ++--
src/fix_shake.cpp | 6 ++--
src/fix_shake.h | 1 -
src/improper.cpp | 1 -
src/improper.h | 2 --
src/pair_born.cpp | 7 +++--
src/pair_buck.cpp | 7 +++--
src/pair_buck_coul_cut.cpp | 7 +++--
src/pair_lj96_cut.cpp | 7 +++--
src/pair_lj_cut.cpp | 7 +++--
src/pair_lj_cut_coul_cut.cpp | 7 +++--
src/pair_lj_expand.cpp | 7 +++--
src/pair_soft.cpp | 15 +++++-----
src/pair_soft.h | 1 -
src/set.h | 1 -
src/thermo.cpp | 10 +++----
src/thermo.h | 2 --
83 files changed, 293 insertions(+), 271 deletions(-)
diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp
index ca69cca5b2..ac74f441f7 100644
--- a/src/CLASS2/angle_class2.cpp
+++ b/src/CLASS2/angle_class2.cpp
@@ -24,10 +24,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -318,7 +320,7 @@ void AngleClass2::coeff(int narg, char **arg)
// convert theta0 from degrees to radians
for (int i = ilo; i <= ihi; i++) {
- theta0[i] = theta0_one/180.0 * PI;
+ theta0[i] = theta0_one/180.0 * MY_PI;
k2[i] = k2_one;
k3[i] = k3_one;
k4[i] = k4_one;
diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp
index d6e31696d7..f9c04126d8 100644
--- a/src/CLASS2/dihedral_class2.cpp
+++ b/src/CLASS2/dihedral_class2.cpp
@@ -26,20 +26,19 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.0000001
/* ---------------------------------------------------------------------- */
-DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp)
-{
- PI = 4.0*atan(1.0);
-}
+DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
@@ -697,8 +696,8 @@ void DihedralClass2::coeff(int narg, char **arg)
at_f1_2[i] = f1_2_one;
at_f2_2[i] = f2_2_one;
at_f3_2[i] = f3_2_one;
- at_theta0_1[i] = theta0_1_one/180.0 * PI;
- at_theta0_2[i] = theta0_2_one/180.0 * PI;
+ at_theta0_1[i] = theta0_1_one/180.0 * MY_PI;
+ at_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
setflag_at[i] = 1;
count++;
}
@@ -714,8 +713,8 @@ void DihedralClass2::coeff(int narg, char **arg)
for (int i = ilo; i <= ihi; i++) {
aat_k[i] = k_one;
- aat_theta0_1[i] = theta0_1_one/180.0 * PI;
- aat_theta0_2[i] = theta0_2_one/180.0 * PI;
+ aat_theta0_1[i] = theta0_1_one/180.0 * MY_PI;
+ aat_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
setflag_aat[i] = 1;
count++;
}
@@ -749,11 +748,11 @@ void DihedralClass2::coeff(int narg, char **arg)
for (int i = ilo; i <= ihi; i++) {
k1[i] = k1_one;
- phi1[i] = phi1_one/180.0 * PI;
+ phi1[i] = phi1_one/180.0 * MY_PI;
k2[i] = k2_one;
- phi2[i] = phi2_one/180.0 * PI;
+ phi2[i] = phi2_one/180.0 * MY_PI;
k3[i] = k3_one;
- phi3[i] = phi3_one/180.0 * PI;
+ phi3[i] = phi3_one/180.0 * MY_PI;
setflag_d[i] = 1;
count++;
}
diff --git a/src/CLASS2/dihedral_class2.h b/src/CLASS2/dihedral_class2.h
index c99258a627..b7a519a27d 100644
--- a/src/CLASS2/dihedral_class2.h
+++ b/src/CLASS2/dihedral_class2.h
@@ -46,7 +46,6 @@ class DihedralClass2 : public Dihedral {
double *bb13t_k,*bb13t_r10,*bb13t_r30;
int *setflag_d,*setflag_mbt,*setflag_ebt;
int *setflag_at,*setflag_aat,*setflag_bb13t;
- double PI;
void allocate();
};
diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp
index 7329870aec..c1331c607e 100644
--- a/src/CLASS2/improper_class2.cpp
+++ b/src/CLASS2/improper_class2.cpp
@@ -26,19 +26,18 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
-ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp)
-{
- PI = 4.0*atan(1.0);
-}
+ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
@@ -550,9 +549,9 @@ void ImproperClass2::coeff(int narg, char **arg)
aa_k1[i] = k1_one;
aa_k2[i] = k2_one;
aa_k3[i] = k3_one;
- aa_theta0_1[i] = theta0_1_one/180.0 * PI;
- aa_theta0_2[i] = theta0_2_one/180.0 * PI;
- aa_theta0_3[i] = theta0_3_one/180.0 * PI;
+ aa_theta0_1[i] = theta0_1_one/180.0 * MY_PI;
+ aa_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
+ aa_theta0_3[i] = theta0_3_one/180.0 * MY_PI;
setflag_aa[i] = 1;
count++;
}
@@ -567,7 +566,7 @@ void ImproperClass2::coeff(int narg, char **arg)
for (int i = ilo; i <= ihi; i++) {
k0[i] = k0_one;
- chi0[i] = chi0_one/180.0 * PI;
+ chi0[i] = chi0_one/180.0 * MY_PI;
setflag_i[i] = 1;
count++;
}
diff --git a/src/CLASS2/improper_class2.h b/src/CLASS2/improper_class2.h
index 56c7c9d14a..9a86e9cd86 100644
--- a/src/CLASS2/improper_class2.h
+++ b/src/CLASS2/improper_class2.h
@@ -38,7 +38,6 @@ class ImproperClass2 : public Improper {
double *k0,*chi0;
double *aa_k1,*aa_k2,*aa_k3,*aa_theta0_1,*aa_theta0_2,*aa_theta0_3;
int *setflag_i,*setflag_aa;
- double PI;
void allocate();
void angleangle(int, int);
diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp
index aba3715cc1..ee5d7d3e32 100644
--- a/src/CLASS2/pair_lj_class2.cpp
+++ b/src/CLASS2/pair_lj_class2.cpp
@@ -19,10 +19,12 @@
#include "comm.h"
#include "force.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -254,14 +256,13 @@ double PairLJClass2::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j];
double sig6 = sig3*sig3;
double rc3 = cut[i][j]*cut[i][j]*cut[i][j];
double rc6 = rc3*rc3;
- etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 3.0*rc3) / (3.0*rc6);
- ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 2.0*rc3) / rc6;
}
diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp
index b6dc7d8018..9cd784ff58 100644
--- a/src/CLASS2/pair_lj_class2_coul_cut.cpp
+++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp
@@ -20,10 +20,12 @@
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -307,14 +309,13 @@ double PairLJClass2CoulCut::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j];
double sig6 = sig3*sig3;
double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j];
double rc6 = rc3*rc3;
- etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 3.0*rc3) / (3.0*rc6);
- ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 2.0*rc3) / rc6;
}
diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp
index b9423c4728..34ff47d804 100644
--- a/src/CLASS2/pair_lj_class2_coul_long.cpp
+++ b/src/CLASS2/pair_lj_class2_coul_long.cpp
@@ -22,10 +22,12 @@
#include "kspace.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
@@ -321,14 +323,13 @@ double PairLJClass2CoulLong::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j];
double sig6 = sig3*sig3;
double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j];
double rc6 = rc3*rc3;
- etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 3.0*rc3) / (3.0*rc6);
- ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] *
+ ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 2.0*rc3) / rc6;
}
diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp
index 5eb072b93e..f3c9a0dc06 100644
--- a/src/COLLOID/pair_lubricate.cpp
+++ b/src/COLLOID/pair_lubricate.cpp
@@ -28,11 +28,13 @@
#include "neigh_list.h"
#include "neigh_request.h"
#include "update.h"
-#include "memory.h"
#include "random_mars.h"
+#include "math_const.h"
+#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -73,7 +75,6 @@ void PairLubricate::compute(int eflag, int vflag)
double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3;
double a_squeeze,a_shear,a_pump,a_twist;
int *ilist,*jlist,*numneigh,**firstneigh;
- double PI = 4.0*atan(1.0);
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
@@ -190,16 +191,16 @@ void PairLubricate::compute(int eflag, int vflag)
h_sep = r - 2.0*radi;
if (flag1)
- a_squeeze = (3.0*PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep);
+ a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep);
if (flag2)
- a_shear = (PI*mu*2.*radi/2.0) *
+ a_shear = (MY_PI*mu*2.*radi/2.0) *
log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0;
if (flag3)
- a_pump = (PI*mu*pow(2.0*radi,4)/8.0) *
+ a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) *
((3.0/20.0) * log(2.0*radi/2.0/h_sep) +
(63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep));
if (flag4)
- a_twist = (PI*mu*pow(2.0*radi,4)/4.0) *
+ a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) *
(h_sep/2.0/radi) * log(2.0/(2.0*h_sep));
if (h_sep >= cut_inner[itype][jtype]) {
@@ -231,7 +232,7 @@ void PairLubricate::compute(int eflag, int vflag)
torque[i][2] += vxmu2f * tz;
} else {
- a_squeeze = (3.0*PI*mu*2.0*radi/2.0) *
+ a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) *
(2.0*radi/4.0/cut_inner[itype][jtype]);
fpair = -a_squeeze*vnnr;
fpair *= vxmu2f;
diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp
index 044d018c28..0fa91a2518 100644
--- a/src/GPU/pppm_gpu.cpp
+++ b/src/GPU/pppm_gpu.cpp
@@ -32,11 +32,13 @@
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
+#include "gpu_extra.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
-#include "gpu_extra.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXORDER 7
#define OFFSET 16384
@@ -189,7 +191,7 @@ void PPPMGPU::compute(int eflag, int vflag)
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e*scale;
}
diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp
index 4dcf9fc3bc..03a1c3a62a 100644
--- a/src/GRANULAR/fix_pour.cpp
+++ b/src/GRANULAR/fix_pour.cpp
@@ -27,10 +27,12 @@
#include "region_block.h"
#include "region_cylinder.h"
#include "random_park.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define EPSILON 0.001
@@ -54,8 +56,6 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
if (seed <= 0) error->all(FLERR,"Illegal fix pour command");
- PI = 4.0*atan(1.0);
-
// option defaults
int iregion = -1;
@@ -214,11 +214,11 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
double dy = yhi - ylo;
if (dy < 1.0) dy = 1.0;
volume = (xhi-xlo) * dy * (zhi-zlo);
- } else volume = PI*rc*rc * (zhi-zlo);
- volume_one = 4.0/3.0 * PI * radius_hi*radius_hi*radius_hi;
+ } else volume = MY_PI*rc*rc * (zhi-zlo);
+ volume_one = 4.0/3.0 * MY_PI * radius_hi*radius_hi*radius_hi;
} else {
volume = (xhi-xlo) * (yhi-ylo);
- volume_one = PI * radius_hi*radius_hi;
+ volume_one = MY_PI * radius_hi*radius_hi;
}
nper = static_cast (volfrac*volume/volume_one);
@@ -472,7 +472,7 @@ void FixPour::pre_exchange()
m = atom->nlocal - 1;
atom->type[m] = ntype;
atom->radius[m] = radtmp;
- atom->rmass[m] = 4.0*PI/3.0 * radtmp*radtmp*radtmp * denstmp;
+ atom->rmass[m] = 4.0*MY_PI/3.0 * radtmp*radtmp*radtmp * denstmp;
atom->mask[m] = 1 | groupbit;
atom->v[m][0] = vxtmp;
atom->v[m][1] = vytmp;
diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h
index ec9590b276..1880597139 100644
--- a/src/GRANULAR/fix_pour.h
+++ b/src/GRANULAR/fix_pour.h
@@ -56,7 +56,6 @@ class FixPour : public Fix {
int me,nprocs;
int *recvcounts,*displs;
- double PI;
int nfreq,nfirst,ninserted,nper;
double lo_current,hi_current;
class FixShearHistory *fix_history;
diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp
index 0345274cb0..020425d110 100644
--- a/src/GRANULAR/fix_wall_gran.cpp
+++ b/src/GRANULAR/fix_wall_gran.cpp
@@ -26,10 +26,12 @@
#include "pair.h"
#include "modify.h"
#include "respa.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{XPLANE,YPLANE,ZPLANE,ZCYLINDER}; // XYZ PLANE need to be 0,1,2
enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY};
@@ -159,10 +161,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) :
// setup oscillations
- if (wiggle) {
- double PI = 4.0 * atan(1.0);
- omega = 2.0*PI / period;
- }
+ if (wiggle) omega = 2.0*MY_PI / period;
// perform initial allocation of atom-based arrays
// register with Atom class
diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp
index 5b6d46750a..edd030b55b 100644
--- a/src/KSPACE/ewald.cpp
+++ b/src/KSPACE/ewald.cpp
@@ -26,10 +26,12 @@
#include "force.h"
#include "pair.h"
#include "domain.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.00001
@@ -40,7 +42,6 @@ Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command");
precision = atof(arg[0]);
- PI = 4.0*atan(1.0);
kmax = 0;
kxvecs = kyvecs = kzvecs = NULL;
@@ -165,17 +166,17 @@ void Ewald::setup()
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;
+ unitk[0] = 2.0*MY_PI/xprd;
+ unitk[1] = 2.0*MY_PI/yprd;
+ unitk[2] = 2.0*MY_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 nkxmx = static_cast ((g_ewald*xprd/MY_PI) * sqrt(-log(precision)));
+ int nkymx = static_cast ((g_ewald*yprd/MY_PI) * sqrt(-log(precision)));
int nkzmx =
- static_cast ((g_ewald*zprd_slab/PI) * sqrt(-log(precision)));
+ static_cast ((g_ewald*zprd_slab/MY_PI) * sqrt(-log(precision)));
int kmax_old = kmax;
kmax = MAX(nkxmx,nkymx);
@@ -281,9 +282,8 @@ void Ewald::compute(int eflag, int vflag)
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);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e*scale;
}
@@ -495,7 +495,7 @@ void Ewald::coeffs()
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;
+ double preu = 4.0*MY_PI/volume;
kcount = 0;
@@ -817,13 +817,13 @@ void Ewald::slabcorr(int eflag)
// compute corrections
- double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume;
+ double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
if (eflag) energy += qqrd2e*scale * e_slabcorr;
// add on force corrections
- double ffact = -4.0*PI*dipole_all/volume;
+ double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact;
diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h
index 250b524de0..95482cfbfe 100644
--- a/src/KSPACE/ewald.h
+++ b/src/KSPACE/ewald.h
@@ -34,7 +34,6 @@ class Ewald : public KSpace {
double memory_usage();
private:
- double PI;
double precision;
int kcount,kmax,kmax3d,kmax_created;
double qqrd2e;
diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp
index dca8532d35..2e607cd74d 100644
--- a/src/KSPACE/pair_born_coul_long.cpp
+++ b/src/KSPACE/pair_born_coul_long.cpp
@@ -26,10 +26,12 @@
#include "kspace.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
@@ -313,7 +315,6 @@ double PairBornCoulLong::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double rho1 = rho[i][j];
double rho2 = rho1*rho1;
double rho3 = rho2*rho1;
@@ -321,11 +322,11 @@ double PairBornCoulLong::init_one(int i, int j)
double rc2 = rc*rc;
double rc3 = rc2*rc;
double rc5 = rc3*rc2;
- etail_ij = 2.0*PI*all[0]*all[1] *
+ etail_ij = 2.0*MY_PI*all[0]*all[1] *
(a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1*
(rc2 + 2.0*rho1*rc + 2.0*rho2) -
c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5));
- ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] *
+ ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] *
(-a[i][j]*exp((sigma[i][j]-rc)/rho1) *
(rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) +
2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5));
diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp
index 813b3b025a..a68029f367 100644
--- a/src/KSPACE/pair_buck_coul_long.cpp
+++ b/src/KSPACE/pair_buck_coul_long.cpp
@@ -22,10 +22,12 @@
#include "kspace.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
@@ -293,17 +295,16 @@ double PairBuckCoulLong::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double rho1 = rho[i][j];
double rho2 = rho1*rho1;
double rho3 = rho2*rho1;
double rc = cut_lj[i][j];
double rc2 = rc*rc;
double rc3 = rc2*rc;
- etail_ij = 2.0*PI*all[0]*all[1]*
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*
(a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) -
c[i][j]/(3.0*rc3));
- ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]*
+ ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]*
(-a[i][j]*exp(-rc/rho1)*
(rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3);
}
diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp
index ba9e390baa..ff8fb1fd22 100644
--- a/src/KSPACE/pair_lj_cut_coul_long.cpp
+++ b/src/KSPACE/pair_lj_cut_coul_long.cpp
@@ -30,10 +30,12 @@
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
@@ -770,15 +772,14 @@ double PairLJCutCoulLong::init_one(int i, int j)
}
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] *
+ etail_ij = 8.0*MY_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] *
+ ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9);
}
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp
index e8c623b47b..3f0cb6e253 100644
--- a/src/MANYBODY/pair_airebo.cpp
+++ b/src/MANYBODY/pair_airebo.cpp
@@ -29,10 +29,12 @@
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXLINE 1024
#define TOL 1.0e-9
@@ -52,8 +54,6 @@ PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp)
maxpage = 0;
pages = NULL;
nC = nH = NULL;
-
- PI = 4.0*atan(1.0);
}
/* ----------------------------------------------------------------------
@@ -1218,8 +1218,8 @@ double PairAIREBO::Sp(double Xij, double Xmin, double Xmax, double &dX)
dX = 0.0;
}
else {
- cutoff = 0.5 * (1.0+cos(PI*t));
- dX = (-0.5*PI*sin(PI*t)) / (Xmax-Xmin);
+ cutoff = 0.5 * (1.0+cos(MY_PI*t));
+ dX = (-MY_PI2*sin(MY_PI*t)) / (Xmax-Xmin);
}
return cutoff;
}
diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h
index b51c00bf2b..166e1ed4ed 100644
--- a/src/MANYBODY/pair_airebo.h
+++ b/src/MANYBODY/pair_airebo.h
@@ -46,7 +46,6 @@ class PairAIREBO : public Pair {
int npage; // current page in page list
int *map; // 0 (C), 1 (H), or -1 (NULL) for each type
- double PI;
double cutlj; // user-specified LJ cutoff
double cutljrebosq; // cut for when to compute
// REBO neighs of ghost atoms
diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp
index 5c47b8dcf1..2311ea8d1e 100644
--- a/src/MANYBODY/pair_comb.cpp
+++ b/src/MANYBODY/pair_comb.cpp
@@ -29,12 +29,14 @@
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
-#include "memory.h"
-#include "error.h"
#include "group.h"
#include "update.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXLINE 1024
#define DELTA 4
@@ -47,11 +49,6 @@ PairComb::PairComb(LAMMPS *lmp) : Pair(lmp)
single_enable = 0;
one_coeff = 1;
- PI = 4.0*atan(1.0);
- PI2 = 2.0*atan(1.0);
- PI4 = atan(1.0);
- PIsq = sqrt(PI);
-
nmax = 0;
NCo = NULL;
bbij = NULL;
@@ -930,7 +927,7 @@ double PairComb::elp(Param *param, double rsqij, double rsqik,
double rij,rik,costheta,lp1,lp3,lp6;
double rmu,rmu2,comtt,fck;
double pplp1 = param->plp1, pplp3 = param->plp3, pplp6 = param->plp6;
- double c123 = cos(param->a123*PI/180.0);
+ double c123 = cos(param->a123*MY_PI/180.0);
// cos(theta) of the i-j-k
// cutoff function of rik
@@ -984,7 +981,7 @@ void PairComb::flp(Param *param, double rsqij, double rsqik,
double pplp1 = param->plp1;
double pplp3 = param->plp3;
double pplp6 = param->plp6;
- double c123 = cos(param->a123*PI/180.0);
+ double c123 = cos(param->a123*MY_PI/180.0);
// fck_d = derivative of cutoff function
@@ -1083,7 +1080,7 @@ double PairComb::comb_fc(double r, Param *param)
if (r < comb_R-comb_D) return 1.0;
if (r > comb_R+comb_D) return 0.0;
- return 0.5*(1.0 + cos(PI*(r - comb_R)/comb_D));
+ return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/comb_D));
}
/* ---------------------------------------------------------------------- */
@@ -1095,7 +1092,7 @@ double PairComb::comb_fc_d(double r, Param *param)
if (r < comb_R-comb_D) return 0.0;
if (r > comb_R+comb_D) return 0.0;
- return -(PI2/comb_D) * sin(PI*(r - comb_R)/comb_D);
+ return -(MY_PI2/comb_D) * sin(MY_PI*(r - comb_R)/comb_D);
}
/* ---------------------------------------------------------------------- */
@@ -1107,7 +1104,7 @@ double PairComb::comb_fc2(double r)
if (r < comb_R) return 0.0;
if (r > comb_D) return 1.0;
- return 0.5*(1.0 + cos(PI*(r - comb_R)/(comb_D-comb_R)));
+ return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R)));
}
/* ---------------------------------------------------------------------- */
@@ -1119,7 +1116,7 @@ double PairComb::comb_fc2_d(double r)
if (r < comb_R) return 0.0;
if (r > comb_D) return 0.0;
- return -(PI2/(comb_D-comb_R)) * sin(PI*(r - comb_R)/(comb_D-comb_R));
+ return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R));
}
/* ---------------------------------------------------------------------- */
@@ -1131,7 +1128,7 @@ double PairComb::comb_fc3(double r)
if (r < comb_R) return 1.0;
if (r > comb_D) return 0.0;
- return 0.5*(1.0 + cos(PI*(r - comb_R)/(comb_D-comb_R)));
+ return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R)));
}
/* ---------------------------------------------------------------------- */
@@ -1143,7 +1140,7 @@ double PairComb::comb_fc3_d(double r)
if (r < comb_R) return 0.0;
if (r > comb_D) return 0.0;
- return -(PI2/(comb_D-comb_R)) * sin(PI*(r - comb_R)/(comb_D-comb_R));
+ return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R));
}
/* ---------------------------------------------------------------------- */
@@ -1541,10 +1538,10 @@ void PairComb::potal_calc(double &calc1, double &calc2, double &calc3)
alf = 0.20;
esucon = force->qqr2e;
- calc2 = (erfc(rcoul*alf)/rcoul/rcoul+2.0*alf/PIsq*
+ calc2 = (erfc(rcoul*alf)/rcoul/rcoul+2.0*alf/MY_PIS*
exp(-alf*alf*rcoul*rcoul)/rcoul)*esucon/rcoul;
calc3 = (erfc(rcoul*alf)/rcoul)*esucon;
- calc1 = -(alf/PIsq*esucon+calc3*0.5);
+ calc1 = -(alf/MY_PIS*esucon+calc3*0.5);
}
/* ---------------------------------------------------------------------- */
@@ -1590,7 +1587,7 @@ void PairComb::direct(int inty, int mr1, int mr2, int mr3, double rsq,
r = sqrt(rsq);
r3 = r * rsq;
alf = 0.20;
- alfdpi = 2.0*alf/PIsq;
+ alfdpi = 2.0*alf/MY_PIS;
esucon = force->qqr2e;
pot_tmp = 0.0;
pot_d = 0.0;
diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h
index c8782b4bbf..bda2805d56 100644
--- a/src/MANYBODY/pair_comb.h
+++ b/src/MANYBODY/pair_comb.h
@@ -58,7 +58,6 @@ class PairComb : public Pair {
int powermint;
};
- double PI,PI2,PI4,PIsq;
double cutmax; // max cutoff for all elements
int nelements; // # of unique elements
char **elements; // names of unique elements
diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp
index 9016a26b28..9c8654100d 100644
--- a/src/MC/fix_gcmc.cpp
+++ b/src/MC/fix_gcmc.cpp
@@ -30,10 +30,12 @@
#include "random_park.h"
#include "force.h"
#include "pair.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -71,10 +73,9 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
// compute beta, lambda, sigma, and the zz factor
beta = 1.0/(force->boltz*reservoir_temperature);
- double PI = 4.0*atan(1.0);
double gas_mass = atom->mass[ntype];
double lambda = sqrt(force->hplanck*force->hplanck/
- (2.0*PI*gas_mass*force->mvv2e*
+ (2.0*MY_PI*gas_mass*force->mvv2e*
force->boltz*reservoir_temperature));
sigma = sqrt(force->boltz*reservoir_temperature/gas_mass/force->mvv2e);
zz = exp(beta*chemical_potential)/(pow(lambda,3));
diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp
index 5dd81580cc..0361209e66 100644
--- a/src/MOLECULE/angle_charmm.cpp
+++ b/src/MOLECULE/angle_charmm.cpp
@@ -23,10 +23,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -209,7 +211,7 @@ void AngleCharmm::coeff(int narg, char **arg)
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
- theta0[i] = theta0_one/180.0 * PI;
+ theta0[i] = theta0_one/180.0 * MY_PI;
k_ub[i] = k_ub_one;
r_ub[i] = r_ub_one;
setflag[i] = 1;
diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp
index 6c6fa4fc87..dc82378083 100644
--- a/src/MOLECULE/angle_cosine.cpp
+++ b/src/MOLECULE/angle_cosine.cpp
@@ -19,10 +19,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -174,7 +176,7 @@ void AngleCosine::coeff(int narg, char **arg)
double AngleCosine::equilibrium_angle(int i)
{
- return PI;
+ return MY_PI;
}
/* ----------------------------------------------------------------------
diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp
index d401c1fffc..8aaf54cb9f 100644
--- a/src/MOLECULE/angle_cosine_periodic.cpp
+++ b/src/MOLECULE/angle_cosine_periodic.cpp
@@ -23,10 +23,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -226,7 +228,7 @@ void AngleCosinePeriodic::coeff(int narg, char **arg)
double AngleCosinePeriodic::equilibrium_angle(int i)
{
- return PI;
+ return MY_PI;
}
/* ----------------------------------------------------------------------
diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp
index 9262700679..95c1a3b922 100644
--- a/src/MOLECULE/angle_cosine_squared.cpp
+++ b/src/MOLECULE/angle_cosine_squared.cpp
@@ -23,10 +23,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -178,7 +180,7 @@ void AngleCosineSquared::coeff(int narg, char **arg)
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
- theta0[i] = theta0_one/180.0 * PI;
+ theta0[i] = theta0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp
index e3def97499..8a462abaed 100644
--- a/src/MOLECULE/angle_harmonic.cpp
+++ b/src/MOLECULE/angle_harmonic.cpp
@@ -19,10 +19,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -178,7 +180,7 @@ void AngleHarmonic::coeff(int narg, char **arg)
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
- theta0[i] = theta0_one/180.0 * PI;
+ theta0[i] = theta0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp
index 4395c20413..a8e6254500 100644
--- a/src/MOLECULE/angle_table.cpp
+++ b/src/MOLECULE/angle_table.cpp
@@ -24,10 +24,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{LINEAR,SPLINE};
@@ -238,8 +240,8 @@ void AngleTable::coeff(int narg, char **arg)
// convert theta from degrees to radians
for (int i = 0; i < tb->ninput; i++){
- tb->afile[i] *= PI/180.0;
- tb->ffile[i] *= 180.0/PI;
+ tb->afile[i] *= MY_PI/180.0;
+ tb->ffile[i] *= 180.0/MY_PI;
}
// spline read-in and compute a,e,f vectors within table
@@ -442,7 +444,7 @@ void AngleTable::compute_table(Table *tb)
// delta = table spacing in angle for N-1 bins
int tlm1 = tablength-1;
- tb->delta = PI/ tlm1;
+ tb->delta = MY_PI / tlm1;
tb->invdelta = 1.0/tb->delta;
tb->deltasq6 = tb->delta*tb->delta / 6.0;
@@ -501,8 +503,8 @@ void AngleTable::param_extract(Table *tb, char *line)
tb->fplo = atof(word);
word = strtok(NULL," \t\n\r\f");
tb->fphi = atof(word);
- tb->fplo *= (180.0/PI)*(180.0/PI);
- tb->fphi *= (180.0/PI)*(180.0/PI);
+ tb->fplo *= (180.0/MY_PI)*(180.0/MY_PI);
+ tb->fphi *= (180.0/MY_PI)*(180.0/MY_PI);
} else if (strcmp(word,"EQ") == 0) {
word = strtok(NULL," \t\n\r\f");
tb->theta0 = atof(word);
diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp
index a404311150..c762a56ad5 100644
--- a/src/MOLECULE/dihedral_charmm.cpp
+++ b/src/MOLECULE/dihedral_charmm.cpp
@@ -27,10 +27,12 @@
#include "force.h"
#include "pair.h"
#include "update.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
@@ -344,14 +346,12 @@ void DihedralCharmm::coeff(int narg, char **arg)
if (weight_one < 0.0 || weight_one > 1.0)
error->all(FLERR,"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);
+ cos_shift[i] = cos(MY_PI*shift_one/180.0);
+ sin_shift[i] = sin(MY_PI*shift_one/180.0);
multiplicity[i] = multiplicity_one;
weight[i] = weight_one;
setflag[i] = 1;
@@ -420,10 +420,9 @@ void DihedralCharmm::read_restart(FILE *fp)
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);
+ cos_shift[i] = cos(MY_PI*shift[i]/180.0);
+ sin_shift[i] = sin(MY_PI*shift[i]/180.0);
}
}
diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp
index 7a50eb4fc0..ee93d2a08d 100644
--- a/src/MOLECULE/dihedral_helix.cpp
+++ b/src/MOLECULE/dihedral_helix.cpp
@@ -27,10 +27,12 @@
#include "comm.h"
#include "force.h"
#include "update.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
@@ -192,9 +194,9 @@ void DihedralHelix::compute(int eflag, int vflag)
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));
+ cphi[type]*(1.0 + cos(phi + MY_PI4));
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
- cphi[type]*sin(phi + 0.25*PI)*siinv;
+ cphi[type]*sin(phi + MY_PI4)*siinv;
if (eflag) edihedral = p;
diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp
index 62d5cd54b6..87d94079bd 100644
--- a/src/MOLECULE/improper_harmonic.cpp
+++ b/src/MOLECULE/improper_harmonic.cpp
@@ -22,10 +22,12 @@
#include "domain.h"
#include "force.h"
#include "update.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
@@ -248,7 +250,7 @@ void ImproperHarmonic::coeff(int narg, char **arg)
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
- chi[i] = chi_one/180.0 * PI;
+ chi[i] = chi_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp
index 34fddf708a..97a127b318 100644
--- a/src/MOLECULE/improper_umbrella.cpp
+++ b/src/MOLECULE/improper_umbrella.cpp
@@ -25,10 +25,12 @@
#include "domain.h"
#include "force.h"
#include "update.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
@@ -269,7 +271,7 @@ void ImproperUmbrella::coeff(int narg, char **arg)
int count = 0;
for (int i = ilo; i <= ihi; i++) {
kw[i] = k_one;
- w0[i] = w_one/180.0 * PI;
+ w0[i] = w_one/180.0 * MY_PI;
if (w_one == 0) C[i] = 1.0;
else C[i] = kw[i]/(pow(sin(w0[i]),2));
setflag[i] = 1;
diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
index eae9e4aa83..104cf83e6d 100644
--- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
@@ -26,11 +26,13 @@
#include "neighbor.h"
#include "neigh_request.h"
#include "neigh_list.h"
+#include "domain.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
-#include "domain.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
#define CHUNK 8
@@ -44,8 +46,6 @@ PairHbondDreidingLJ::PairHbondDreidingLJ(LAMMPS *lmp) : Pair(lmp)
no_virial_fdotr_compute = 1;
- PI = 4.0*atan(1.0);
-
nparams = maxparam = 0;
params = NULL;
@@ -159,7 +159,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
if (c < -1.0) c = -1.0;
ac = acos(c);
- if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) {
+ if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
@@ -279,7 +279,7 @@ void PairHbondDreidingLJ::settings(int narg, char **arg)
ap_global = force->inumeric(arg[0]);
cut_inner_global = force->numeric(arg[1]);
cut_outer_global = force->numeric(arg[2]);
- cut_angle_global = force->numeric(arg[3]) * PI/180.0;
+ cut_angle_global = force->numeric(arg[3]) * MY_PI/180.0;
}
/* ----------------------------------------------------------------------
@@ -316,7 +316,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg)
if (cut_inner_one>cut_outer_one)
error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff");
double cut_angle_one = cut_angle_global;
- if (narg == 10) cut_angle_one = force->numeric(arg[9]) * PI/180.0;
+ if (narg == 10) cut_angle_one = force->numeric(arg[9]) * MY_PI/180.0;
// grow params array if necessary
if (nparams == maxparam) {
@@ -500,7 +500,7 @@ double PairHbondDreidingLJ::single(int i, int j, int itype, int jtype,
if (c < -1.0) c = -1.0;
ac = acos(c);
- if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0;
+ if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0;
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.h b/src/MOLECULE/pair_hbond_dreiding_lj.h
index 387cd3f095..1304743b8d 100644
--- a/src/MOLECULE/pair_hbond_dreiding_lj.h
+++ b/src/MOLECULE/pair_hbond_dreiding_lj.h
@@ -38,7 +38,6 @@ class PairHbondDreidingLJ : public Pair {
protected:
double cut_inner_global,cut_outer_global,cut_angle_global;
int ap_global;
- double PI;
struct Param {
double epsilon,sigma;
diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
index ebd3b27ef0..e7f9c1e7c5 100644
--- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
@@ -26,11 +26,13 @@
#include "neighbor.h"
#include "neigh_request.h"
#include "neigh_list.h"
+#include "domain.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
-#include "domain.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
#define CHUNK 8
@@ -128,7 +130,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
if (c < -1.0) c = -1.0;
ac = acos(c);
- if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) {
+ if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
@@ -242,7 +244,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg)
if (cut_inner_one>cut_outer_one)
error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff");
double cut_angle_one = cut_angle_global;
- if (narg > 10) cut_angle_one = force->numeric(arg[10]) * PI/180.0;
+ if (narg > 10) cut_angle_one = force->numeric(arg[10]) * MY_PI/180.0;
// grow params array if necessary
@@ -404,7 +406,7 @@ double PairHbondDreidingMorse::single(int i, int j, int itype, int jtype,
if (c < -1.0) c = -1.0;
ac = acos(c);
- if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0;
+ if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0;
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp
index ec0d07d20d..411beb9c9d 100644
--- a/src/SRD/fix_srd.cpp
+++ b/src/SRD/fix_srd.cpp
@@ -34,10 +34,12 @@
#include "fix_wall_srd.h"
#include "random_mars.h"
#include "random_park.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{SLIP,NOSLIP};
enum{SPHERE,ELLIPSOID,WALL};
@@ -2087,8 +2089,6 @@ int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew,
void FixSRD::parameterize()
{
- double PI = 4.0*atan(1.0);
-
// timesteps
dt_big = update->dt;
@@ -2194,20 +2194,20 @@ void FixSRD::parameterize()
for (int i = 0; i < nlocal; i++)
if (mask[i] & biggroupbit) {
if (radius && radius[i] > 0.0)
- volbig += 4.0/3.0*PI*radius[i]*radius[i]*radius[i];
+ volbig += 4.0/3.0*MY_PI*radius[i]*radius[i]*radius[i];
else if (ellipsoid && ellipsoid[i] >= 0) {
double *shape = ebonus[ellipsoid[i]].shape;
- volbig += 4.0/3.0*PI * shape[0]*shape[1]*shape[2];
+ volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2];
}
}
} else {
for (int i = 0; i < nlocal; i++)
if (mask[i] & biggroupbit) {
if (radius && radius[i] > 0.0)
- volbig += PI*radius[i]*radius[i];
+ volbig += MY_PI*radius[i]*radius[i];
else if (ellipsoid && ellipsoid[i] >= 0) {
double *shape = ebonus[ellipsoid[i]].shape;
- volbig += PI*shape[0]*shape[1];
+ volbig += MY_PI*shape[0]*shape[1];
}
}
}
diff --git a/src/USER-CG-CMM/angle_cg_cmm.cpp b/src/USER-CG-CMM/angle_cg_cmm.cpp
index 7d9800808a..070d65c5b8 100644
--- a/src/USER-CG-CMM/angle_cg_cmm.cpp
+++ b/src/USER-CG-CMM/angle_cg_cmm.cpp
@@ -24,10 +24,12 @@
#include "domain.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 0.001
@@ -323,7 +325,7 @@ void AngleCGCMM::coeff(int narg, char **arg)
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
// convert theta0 from degrees to radians
- theta0[i] = theta0_one/180.0 * PI;
+ theta0[i] = theta0_one/180.0 * MY_PI;
epsilon[i] = epsilon_one;
sigma[i] = sigma_one;
rcut[i] = rcut_one;
diff --git a/src/USER-CG-CMM/pair_cmm_common.cpp b/src/USER-CG-CMM/pair_cmm_common.cpp
index 81d142f568..4e1606d587 100644
--- a/src/USER-CG-CMM/pair_cmm_common.cpp
+++ b/src/USER-CG-CMM/pair_cmm_common.cpp
@@ -23,8 +23,10 @@
#include "string.h"
#include "ctype.h"
#include "math.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 1.0e-6
@@ -302,15 +304,14 @@ double PairCMMCommon::init_one(int i, int j)
}
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[i][j]*cut[i][j]*cut[i][j];
double rc6 = rc3*rc3;
double rc9 = rc3*rc6;
- etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 8.0*MY_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] *
+ ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9);
#endif
}
diff --git a/src/USER-CUDA/fix_gravity_cuda.cpp b/src/USER-CUDA/fix_gravity_cuda.cpp
index 8c6d8488c8..36d7022fa3 100644
--- a/src/USER-CUDA/fix_gravity_cuda.cpp
+++ b/src/USER-CUDA/fix_gravity_cuda.cpp
@@ -30,12 +30,13 @@
#include "update.h"
#include "domain.h"
#include "respa.h"
-#include "error.h"
#include "cuda.h"
#include "cuda_modify_flags.h"
-
+#include "math_const.h"
+#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{CHUTE,SPHERICAL,GRADIENT,VECTOR};
@@ -79,8 +80,7 @@ FixGravityCuda::FixGravityCuda(LAMMPS *lmp, int narg, char **arg) :
zdir = atof(arg[7]);
} else error->all(FLERR,"Illegal fix gravity command");
- double PI = 4.0*atan(1.0);
- degree2rad = PI/180.0;
+ degree2rad = MY_PI/180.0;
if (style == CHUTE || style == SPHERICAL || style == GRADIENT) {
if (domain->dimension == 3) {
diff --git a/src/USER-CUDA/fix_shake_cuda.cpp b/src/USER-CUDA/fix_shake_cuda.cpp
index 219ac679bd..cbcb9acaef 100644
--- a/src/USER-CUDA/fix_shake_cuda.cpp
+++ b/src/USER-CUDA/fix_shake_cuda.cpp
@@ -34,8 +34,10 @@
#include "error.h"
#include "cuda.h"
#include "cuda_modify_flags.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define BIG 1.0e20
#define MASSDELTA 0.1
@@ -53,7 +55,6 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) :
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
neighbor_step=true;
- PI = 4.0*atan(1.0);
virial_flag = 1;
create_attribute = 1;
@@ -2183,7 +2184,7 @@ void FixShakeCuda::stats()
r3 = sqrt(delx*delx + dely*dely + delz*delz);
angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2));
- angle *= 180.0/PI;
+ angle *= 180.0/MY_PI;
m = shake_type[i][2];
a_count[m]++;
a_ave[m] += angle;
diff --git a/src/USER-CUDA/fix_shake_cuda.h b/src/USER-CUDA/fix_shake_cuda.h
index 18ea64f983..b0ebe584d7 100644
--- a/src/USER-CUDA/fix_shake_cuda.h
+++ b/src/USER-CUDA/fix_shake_cuda.h
@@ -53,7 +53,6 @@ class FixShakeCuda : public Fix {
private:
class Cuda *cuda;
int me,nprocs;
- double PI;
double tolerance; // SHAKE tolerance
int max_iter; // max # of SHAKE iterations
int output_every; // SHAKE stat output every so often
diff --git a/src/USER-CUDA/pppm_cuda.cpp b/src/USER-CUDA/pppm_cuda.cpp
index 8167eb1d72..5fd8406fbe 100644
--- a/src/USER-CUDA/pppm_cuda.cpp
+++ b/src/USER-CUDA/pppm_cuda.cpp
@@ -61,8 +61,10 @@
#include "cuda_wrapper_cu.h"
#include "pppm_cuda_cu.h"
#include "cuda.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define MAXORDER 7
#define OFFSET 4096
@@ -109,7 +111,6 @@ PPPMCuda::PPPMCuda(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, (narg==2?1:nar
if(narg>1)
precisionmodify=arg[1][0];
else precisionmodify='=';
- PI = 4.0*atan(1.0);
nfactors = 3;
factors = new int[nfactors];
@@ -648,9 +649,9 @@ void PPPMCuda::setup()
delvolinv = delxinv*delyinv*delzinv;
- double unitkx = (2.0*PI/xprd);
- double unitky = (2.0*PI/yprd);
- double unitkz = (2.0*PI/zprd_slab);
+ double unitkx = (2.0*MY_PI/xprd);
+ double unitky = (2.0*MY_PI/yprd);
+ double unitkz = (2.0*MY_PI/zprd_slab);
// fkx,fky,fkz for my FFT grid pts
Cuda_PPPM_Setup_fkxyz_vg(nx_pppm, ny_pppm,nz_pppm,unitkx,unitky,unitkz,g_ewald);
@@ -747,11 +748,11 @@ double sqk;
double sum1,dot1,dot2;
double numerator,denominator;
- int nbx = static_cast ((g_ewald*xprd/(PI*nx_pppm)) *
+ int nbx = static_cast ((g_ewald*xprd/(MY_PI*nx_pppm)) *
pow(-log(EPS_HOC),0.25));
- int nby = static_cast ((g_ewald*yprd/(PI*ny_pppm)) *
+ int nby = static_cast ((g_ewald*yprd/(MY_PI*ny_pppm)) *
pow(-log(EPS_HOC),0.25));
- int nbz = static_cast ((g_ewald*zprd_slab/(PI*nz_pppm)) *
+ int nbz = static_cast ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) *
pow(-log(EPS_HOC),0.25));
Cuda_PPPM_setup_greensfn(nx_pppm,ny_pppm,nz_pppm,unitkx,unitky,unitkz,g_ewald,
nbx,nby,nbz,xprd,yprd,zprd_slab);
@@ -967,7 +968,7 @@ else
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e;
}
@@ -1728,11 +1729,11 @@ void PPPMCuda::slabcorr(int eflag)
// compute corrections
- double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume;
+ double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
if (eflag) energy += qqrd2e*scale * e_slabcorr;
- double ffact = -4.0*PI*dipole_all/volume;
+ double ffact = -4.0*MY_PI*dipole_all/volume;
cuda_slabcorr_force(&cuda->shared_data,ffact);
}
diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h
index b9372f62a6..6c527cacdd 100644
--- a/src/USER-EFF/atom_vec_electron.h
+++ b/src/USER-EFF/atom_vec_electron.h
@@ -60,7 +60,6 @@ class AtomVecElectron : public AtomVec {
bigint memory_usage();
private:
- double PI;
int *tag,*type,*mask,*image;
double **x,**v,**f;
int *spin;
diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp
index a3ca969ef3..4ec701a0cb 100644
--- a/src/USER-OMP/dihedral_helix_omp.cpp
+++ b/src/USER-OMP/dihedral_helix_omp.cpp
@@ -25,9 +25,11 @@
#include "domain.h"
#include "force.h"
#include "update.h"
+#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
@@ -211,10 +213,10 @@ void DihedralHelixOMP::eval(double **f, int nfrom, int nto, int tid)
siinv = 1.0/si;
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
- cphi[type]*sin(phi + 0.25*PI)*siinv;
+ cphi[type]*sin(phi + MY_PI4)*siinv;
if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) +
- cphi[type]*(1.0 + cos(phi + 0.25*PI));
+ cphi[type]*(1.0 + cos(phi + MY_PI4));
;
a = pd;
diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp
index 7667efa983..9f9673a28b 100644
--- a/src/USER-OMP/pair_soft_omp.cpp
+++ b/src/USER-OMP/pair_soft_omp.cpp
@@ -19,8 +19,10 @@
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define SMALL 1.0e-4
@@ -122,7 +124,7 @@ void PairSoftOMP::eval(double **f, int iifrom, int iito, int tid)
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
- arg = PI/cut[itype][jtype];
+ arg = MY_PI/cut[itype][jtype];
if (r > SMALL) fpair = factor_lj * prefactor[itype][jtype] *
sin(arg*r) * arg/r;
else fpair = 0.0;
diff --git a/src/angle.cpp b/src/angle.cpp
index fbed9116a9..58ba679948 100644
--- a/src/angle.cpp
+++ b/src/angle.cpp
@@ -15,10 +15,12 @@
#include "angle.h"
#include "atom.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -27,8 +29,6 @@ Angle::Angle(LAMMPS *lmp) : Pointers(lmp)
energy = 0.0;
allocated = 0;
- PI = 4.0*atan(1.0);
- THIRD = 1.0/3.0;
maxeatom = maxvatom = 0;
eatom = NULL;
diff --git a/src/angle.h b/src/angle.h
index 99d8dc105f..7f25f38289 100644
--- a/src/angle.h
+++ b/src/angle.h
@@ -40,8 +40,6 @@ class Angle : protected Pointers {
virtual double memory_usage();
protected:
- double PI,THIRD;
-
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp
index 47c9ef97f6..4baff5b602 100755
--- a/src/atom_vec_ellipsoid.cpp
+++ b/src/atom_vec_ellipsoid.cpp
@@ -25,10 +25,12 @@
#include "domain.h"
#include "modify.h"
#include "fix.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define DELTA 10000
#define DELTA_BONUS 10000
@@ -53,8 +55,6 @@ AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) :
atom->ellipsoid_flag = 1;
atom->rmass_flag = atom->angmom_flag = atom->torque_flag = 1;
- PI = 4.0*atan(1.0);
-
nlocal_bonus = nghost_bonus = nmax_bonus = 0;
bonus = NULL;
}
@@ -1200,7 +1200,7 @@ void AtomVecEllipsoid::data_atom_bonus(int m, char **values)
// reset ellipsoid mass
// previously stored density in rmass
- rmass[m] *= 4.0*PI/3.0 * shape[0]*shape[1]*shape[2];
+ rmass[m] *= 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2];
bonus[nlocal_bonus].ilocal = m;
ellipsoid[m] = nlocal_bonus++;
diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h
index 537f1eaab7..0020eb5f28 100755
--- a/src/atom_vec_ellipsoid.h
+++ b/src/atom_vec_ellipsoid.h
@@ -76,7 +76,6 @@ class AtomVecEllipsoid : public AtomVec {
void set_shape(int, double, double, double);
private:
- double PI;
int *tag,*type,*mask,*image;
double **x,**v,**f;
double *rmass;
diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp
index a3e2c34772..96b2d766d8 100644
--- a/src/atom_vec_sphere.cpp
+++ b/src/atom_vec_sphere.cpp
@@ -23,10 +23,12 @@
#include "force.h"
#include "fix.h"
#include "fix_adapt.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define DELTA 10000
@@ -50,8 +52,6 @@ AtomVecSphere::AtomVecSphere(LAMMPS *lmp, int narg, char **arg) :
atom->sphere_flag = 1;
atom->radius_flag = atom->rmass_flag = atom->omega_flag =
atom->torque_flag = 1;
-
- PI = 4.0*atan(1.0);
}
/* ---------------------------------------------------------------------- */
@@ -929,7 +929,7 @@ void AtomVecSphere::create_atom(int itype, double *coord)
v[nlocal][2] = 0.0;
radius[nlocal] = 0.5;
- rmass[nlocal] = 4.0*PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal];
+ rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal];
omega[nlocal][0] = 0.0;
omega[nlocal][1] = 0.0;
omega[nlocal][2] = 0.0;
@@ -965,7 +965,7 @@ void AtomVecSphere::data_atom(double *coord, int imagetmp, char **values)
if (radius[nlocal] == 0.0) rmass[nlocal] = density;
else
- rmass[nlocal] = 4.0*PI/3.0 *
+ rmass[nlocal] = 4.0*MY_PI/3.0 *
radius[nlocal]*radius[nlocal]*radius[nlocal] * density;
x[nlocal][0] = coord[0];
@@ -1002,7 +1002,7 @@ int AtomVecSphere::data_atom_hybrid(int nlocal, char **values)
if (radius[nlocal] == 0.0) rmass[nlocal] = density;
else
- rmass[nlocal] = 4.0*PI/3.0 *
+ rmass[nlocal] = 4.0*MY_PI/3.0 *
radius[nlocal]*radius[nlocal]*radius[nlocal] * density;
return 2;
diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h
index 8157029615..78357b7d1a 100644
--- a/src/atom_vec_sphere.h
+++ b/src/atom_vec_sphere.h
@@ -61,7 +61,6 @@ class AtomVecSphere : public AtomVec {
bigint memory_usage();
private:
- double PI;
int *tag,*type,*mask,*image;
double **x,**v,**f;
double *radius,*density,*rmass;
diff --git a/src/compute_angle_local.cpp b/src/compute_angle_local.cpp
index a126348d31..d19b7e71aa 100644
--- a/src/compute_angle_local.cpp
+++ b/src/compute_angle_local.cpp
@@ -20,10 +20,12 @@
#include "domain.h"
#include "force.h"
#include "angle.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define DELTA 10000
@@ -133,7 +135,6 @@ int ComputeAngleLocal::compute_angles(int flag)
}
Angle *angle = force->angle;
- double PI = 4.0*atan(1.0);
m = n = 0;
for (atom2 = 0; atom2 < nlocal; atom2++) {
@@ -170,7 +171,7 @@ int ComputeAngleLocal::compute_angles(int flag)
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
- tbuf[n] = 180.0*acos(c)/PI;
+ tbuf[n] = 180.0*acos(c)/MY_PI;
}
if (eflag >= 0) {
diff --git a/src/compute_dihedral_local.cpp b/src/compute_dihedral_local.cpp
index 6215346717..10cac6f607 100644
--- a/src/compute_dihedral_local.cpp
+++ b/src/compute_dihedral_local.cpp
@@ -20,10 +20,12 @@
#include "domain.h"
#include "force.h"
#include "dihedral.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define DELTA 10000
#define SMALL 0.001
@@ -128,8 +130,6 @@ int ComputeDihedralLocal::compute_dihedrals(int flag)
}
}
- double PI = 4.0*atan(1.0);
-
m = n = 0;
for (atom2 = 0; atom2 < nlocal; atom2++) {
if (!(mask[atom2] & groupbit)) continue;
@@ -190,7 +190,7 @@ int ComputeDihedralLocal::compute_dihedrals(int flag)
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
- pbuf[n] = 180.0*atan2(s,c)/PI;
+ pbuf[n] = 180.0*atan2(s,c)/MY_PI;
}
n += nvalues;
}
diff --git a/src/compute_improper_local.cpp b/src/compute_improper_local.cpp
index 7162277c39..3285f2561c 100644
--- a/src/compute_improper_local.cpp
+++ b/src/compute_improper_local.cpp
@@ -20,10 +20,12 @@
#include "domain.h"
#include "force.h"
#include "improper.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define DELTA 10000
@@ -129,8 +131,6 @@ int ComputeImproperLocal::compute_impropers(int flag)
}
}
- double PI = 4.0*atan(1.0);
-
m = n = 0;
for (atom2 = 0; atom2 < nlocal; atom2++) {
if (!(mask[atom2] & groupbit)) continue;
@@ -188,7 +188,7 @@ int ComputeImproperLocal::compute_impropers(int flag)
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
- cbuf[n] = 180.0*acos(c)/PI;
+ cbuf[n] = 180.0*acos(c)/MY_PI;
}
n += nvalues;
}
diff --git a/src/compute_rdf.cpp b/src/compute_rdf.cpp
index 9dbe3aded0..31776f9473 100644
--- a/src/compute_rdf.cpp
+++ b/src/compute_rdf.cpp
@@ -28,10 +28,12 @@
#include "neigh_request.h"
#include "neigh_list.h"
#include "group.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -267,10 +269,9 @@ void ComputeRDF::compute_array()
// assuming J atoms are at uniform density
double constant,nideal,gr,ncoord,rlower,rupper;
- double PI = 4.0*atan(1.0);
if (domain->dimension == 3) {
- constant = 4.0*PI / (3.0*domain->xprd*domain->yprd*domain->zprd);
+ constant = 4.0*MY_PI / (3.0*domain->xprd*domain->yprd*domain->zprd);
for (m = 0; m < npairs; m++) {
ncoord = 0.0;
@@ -289,7 +290,7 @@ void ComputeRDF::compute_array()
}
} else {
- constant = PI / (domain->xprd*domain->yprd);
+ constant = MY_PI / (domain->xprd*domain->yprd);
for (m = 0; m < npairs; m++) {
ncoord = 0.0;
diff --git a/src/dihedral.cpp b/src/dihedral.cpp
index a3edadc0c0..974df81b14 100644
--- a/src/dihedral.cpp
+++ b/src/dihedral.cpp
@@ -32,7 +32,6 @@ Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp)
energy = 0.0;
allocated = 0;
- PI = 4.0*atan(1.0);
maxeatom = maxvatom = 0;
eatom = NULL;
diff --git a/src/dihedral.h b/src/dihedral.h
index c41cedad03..b41272b7ba 100644
--- a/src/dihedral.h
+++ b/src/dihedral.h
@@ -41,8 +41,6 @@ class Dihedral : protected Pointers {
virtual double memory_usage();
protected:
- double PI;
-
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
diff --git a/src/dump_image.cpp b/src/dump_image.cpp
index 25dc36109f..16f677327e 100644
--- a/src/dump_image.cpp
+++ b/src/dump_image.cpp
@@ -30,6 +30,7 @@
#include "input.h"
#include "variable.h"
#include "random_mars.h"
+#include "math_const.h"
#include "error.h"
#include "memory.h"
@@ -38,6 +39,7 @@
#endif
using namespace LAMMPS_NS;
+using namespace MathConst;
#define NCOLORS 140
#define NELEMENTS 109
@@ -57,8 +59,6 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
{
if (binary || multiproc) error->all(FLERR,"Invalid dump image filename");
- PI = 4.0*atan(1.0);
-
// set filetype based on filename suffix
int n = strlen(filename);
@@ -95,8 +95,8 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
bdiamvalue = 0.5;
}
width = height = 512;
- theta = 60.0 * PI/180.0;
- phi = 30.0 * PI/180.0;
+ theta = 60.0 * MY_PI/180.0;
+ phi = 30.0 * MY_PI/180.0;
thetastr = phistr = NULL;
cflag = STATIC;
cx = cy = cz = 0.5;
@@ -171,7 +171,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
theta = atof(arg[iarg+1]);
if (theta < 0.0 || theta > 180.0)
error->all(FLERR,"Invalid dump image theta value");
- theta *= PI/180.0;
+ theta *= MY_PI/180.0;
}
if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) {
int n = strlen(&arg[iarg+2][2]) + 1;
@@ -179,7 +179,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
strcpy(phistr,&arg[iarg+2][2]);
} else {
phi = atof(arg[iarg+2]);
- phi *= PI/180.0;
+ phi *= MY_PI/180.0;
}
iarg += 3;
@@ -358,25 +358,25 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
// static parameters
- FOV = PI/6.0; // 30 degrees
+ FOV = MY_PI/6.0; // 30 degrees
ambientColor[0] = 0.0;
ambientColor[1] = 0.0;
ambientColor[2] = 0.0;
- keyLightPhi = -PI/4.0; // -45 degrees
- keyLightTheta = PI/6.0; // 30 degrees
+ keyLightPhi = -MY_PI4; // -45 degrees
+ keyLightTheta = MY_PI/6.0; // 30 degrees
keyLightColor[0] = 0.9;
keyLightColor[1] = 0.9;
keyLightColor[2] = 0.9;
- fillLightPhi = PI/6.0; // 30 degrees
+ fillLightPhi = MY_PI/6.0; // 30 degrees
fillLightTheta = 0;
fillLightColor[0] = 0.45;
fillLightColor[1] = 0.45;
fillLightColor[2] = 0.45;
- backLightPhi = PI; // 180 degrees
- backLightTheta = PI/12.0; // 15 degrees
+ backLightPhi = MY_PI; // 180 degrees
+ backLightTheta = MY_PI/12.0; // 15 degrees
backLightColor[0] = 0.9;
backLightColor[1] = 0.9;
backLightColor[2] = 0.9;
@@ -676,11 +676,11 @@ void DumpImage::view_params()
theta = input->variable->compute_equal(thetavar);
if (theta < 0.0 || theta > 180.0)
error->all(FLERR,"Invalid dump image theta value");
- theta *= PI/180.0;
+ theta *= MY_PI/180.0;
}
if (phistr) {
phi = input->variable->compute_equal(phivar);
- phi *= PI/180.0;
+ phi *= MY_PI/180.0;
}
camDir[0] = sin(theta)*cos(phi);
@@ -764,7 +764,7 @@ void DumpImage::view_params()
if (ssao) {
SSAORadius = maxdel * 0.05 * ssaoint;
SSAOSamples = static_cast (8.0 + 32.0*ssaoint);
- SSAOJitter = PI / 12;
+ SSAOJitter = MY_PI / 12;
ambientColor[0] = 0.5;
ambientColor[1] = 0.5;
ambientColor[2] = 0.5;
@@ -1358,7 +1358,7 @@ void DumpImage::compute_SSAO()
{
// used for rasterizing the spheres
- double delTheta = 2.0*PI / SSAOSamples;
+ double delTheta = 2.0*MY_PI / SSAOSamples;
// typical neighborhood value for shading
diff --git a/src/dump_image.h b/src/dump_image.h
index 866fc32e89..844ba1c112 100644
--- a/src/dump_image.h
+++ b/src/dump_image.h
@@ -69,8 +69,6 @@ class DumpImage : public DumpCustom {
// constant view params
- double PI;
-
double FOV;
double ambientColor[3];
diff --git a/src/fix_adapt.cpp b/src/fix_adapt.cpp
index fd1a256b8a..59af597bc3 100644
--- a/src/fix_adapt.cpp
+++ b/src/fix_adapt.cpp
@@ -24,10 +24,12 @@
#include "kspace.h"
#include "input.h"
#include "variable.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{PAIR,KSPACE,ATOM};
enum{DIAMETER};
@@ -309,7 +311,6 @@ void FixAdapt::change_settings()
if (ad->aparam == DIAMETER) {
int mflag = 0;
if (atom->rmass_flag) mflag = 1;
- double PI = 4.0*atan(1.0);
double density;
double *radius = atom->radius;
@@ -324,9 +325,11 @@ void FixAdapt::change_settings()
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
- density = rmass[i] / (4.0*PI/3.0 * radius[i]*radius[i]*radius[i]);
+ density = rmass[i] / (4.0*MY_PI/3.0 *
+ radius[i]*radius[i]*radius[i]);
radius[i] = 0.5*value;
- rmass[i] = 4.0*PI/3.0 * radius[i]*radius[i]*radius[i] * density;
+ rmass[i] = 4.0*MY_PI/3.0 *
+ radius[i]*radius[i]*radius[i] * density;
}
}
}
diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp
index 039bba40b2..097683ad23 100644
--- a/src/fix_deform.cpp
+++ b/src/fix_deform.cpp
@@ -27,10 +27,12 @@
#include "lattice.h"
#include "force.h"
#include "modify.h"
+#include "math_const.h"
#include "kspace.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE};
enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE};
@@ -305,7 +307,7 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
if (force_reneighbor) irregular = new Irregular(lmp);
else irregular = NULL;
- TWOPI = 8.0*atan(1.0);
+ TWOPI = 2.0*MY_PI;
}
/* ---------------------------------------------------------------------- */
diff --git a/src/fix_gravity.cpp b/src/fix_gravity.cpp
index 09a2e2c7f1..de71e6bd79 100644
--- a/src/fix_gravity.cpp
+++ b/src/fix_gravity.cpp
@@ -20,9 +20,11 @@
#include "update.h"
#include "domain.h"
#include "respa.h"
+#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{CHUTE,SPHERICAL,GRADIENT,VECTOR};
@@ -65,8 +67,7 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
zdir = atof(arg[7]);
} else error->all(FLERR,"Illegal fix gravity command");
- double PI = 4.0*atan(1.0);
- degree2rad = PI/180.0;
+ degree2rad = MY_PI/180.0;
if (style == CHUTE || style == SPHERICAL || style == GRADIENT) {
if (domain->dimension == 3) {
diff --git a/src/fix_move.cpp b/src/fix_move.cpp
index afd087772e..74657fa86e 100644
--- a/src/fix_move.cpp
+++ b/src/fix_move.cpp
@@ -26,10 +26,12 @@
#include "respa.h"
#include "input.h"
#include "variable.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{LINEAR,WIGGLE,ROTATE,VARIABLE};
enum{EQUAL,ATOM};
@@ -216,10 +218,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) :
// set omega_rotate from period
- if (mstyle == WIGGLE || mstyle == ROTATE) {
- double PI = 4.0 * atan(1.0);
- omega_rotate = 2.0*PI / period;
- }
+ if (mstyle == WIGGLE || mstyle == ROTATE) omega_rotate = 2.0*MY_PI / period;
// runit = unit vector along rotation axis
diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp
index d0269acddb..109373add7 100644
--- a/src/fix_orient_fcc.cpp
+++ b/src/fix_orient_fcc.cpp
@@ -28,10 +28,12 @@
#include "neigh_request.h"
#include "comm.h"
#include "output.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define BIG 1000000000
@@ -77,7 +79,6 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) :
// initializations
- PI = 4.0*atan(1.0);
half_fcc_nn = 6;
use_xismooth = false;
double xicutoff = 1.57;
@@ -344,10 +345,10 @@ void FixOrientFCC::post_force(int vflag)
edelta = Vxi;
order[i][1] = 1.0;
} else {
- omega = (0.5*PI)*(xi_total-xi0) / (xi1-xi0);
- nbr[i].duxi = PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0));
+ omega = MY_PI2*(xi_total-xi0) / (xi1-xi0);
+ nbr[i].duxi = MY_PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0));
edelta = Vxi*(1 - cos(2.0*omega)) / 2.0;
- order[i][1] = omega / (0.5*PI);
+ order[i][1] = omega / MY_PI2;
}
added_energy += edelta;
}
diff --git a/src/fix_orient_fcc.h b/src/fix_orient_fcc.h
index f401d30855..b83753619b 100644
--- a/src/fix_orient_fcc.h
+++ b/src/fix_orient_fcc.h
@@ -58,7 +58,6 @@ class FixOrientFCC : public Fix {
private:
int me;
- double PI;
int nlevels_respa;
int direction_of_motion; // 1 = center shrinks, 0 = center grows
diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp
index 43f7f61087..f3048cc18d 100644
--- a/src/fix_restrain.cpp
+++ b/src/fix_restrain.cpp
@@ -26,10 +26,12 @@
#include "comm.h"
#include "respa.h"
#include "input.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
enum{DIHEDRAL};
@@ -83,13 +85,12 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) :
// special treatment for dihedral restraints
if (rstyle == DIHEDRAL) {
- double PI = 4.0*atan(1.0);
cos_shift = (double *)
memory->smalloc(n_bonds * sizeof(double), "restrain:cos_shift");
sin_shift = (double *)
memory->smalloc(n_bonds * sizeof(double), "restrain:sin_shift");
for (ibond = 0; ibond < n_bonds; ibond++) {
- double my_arg = PI * (180.0 + target[ibond]) / 180.0;
+ double my_arg = MY_PI * (180.0 + target[ibond]) / 180.0;
cos_shift[ibond] = cos(my_arg);
sin_shift[ibond] = sin(my_arg);
}
diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp
index e00e84e424..5cdce3ad25 100644
--- a/src/fix_shake.cpp
+++ b/src/fix_shake.cpp
@@ -30,10 +30,12 @@
#include "comm.h"
#include "group.h"
#include "fix_respa.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define BIG 1.0e20
#define MASSDELTA 0.1
@@ -46,8 +48,6 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
- PI = 4.0*atan(1.0);
-
virial_flag = 1;
create_attribute = 1;
@@ -2114,7 +2114,7 @@ void FixShake::stats()
r3 = sqrt(delx*delx + dely*dely + delz*delz);
angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2));
- angle *= 180.0/PI;
+ angle *= 180.0/MY_PI;
m = shake_type[i][2];
a_count[m]++;
a_ave[m] += angle;
diff --git a/src/fix_shake.h b/src/fix_shake.h
index eaf39837cb..b0aa5c63d2 100644
--- a/src/fix_shake.h
+++ b/src/fix_shake.h
@@ -49,7 +49,6 @@ class FixShake : public Fix {
private:
int me,nprocs;
- double PI;
double tolerance; // SHAKE tolerance
int max_iter; // max # of SHAKE iterations
int output_every; // SHAKE stat output every so often
diff --git a/src/improper.cpp b/src/improper.cpp
index 3c65e8c89c..8f5ab4d6e3 100644
--- a/src/improper.cpp
+++ b/src/improper.cpp
@@ -27,7 +27,6 @@ Improper::Improper(LAMMPS *lmp) : Pointers(lmp)
energy = 0.0;
allocated = 0;
- PI = 4.0*atan(1.0);
maxeatom = maxvatom = 0;
eatom = NULL;
diff --git a/src/improper.h b/src/improper.h
index 711f124c20..d8310b2475 100644
--- a/src/improper.h
+++ b/src/improper.h
@@ -38,8 +38,6 @@ class Improper : protected Pointers {
virtual double memory_usage();
protected:
- double PI;
-
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
diff --git a/src/pair_born.cpp b/src/pair_born.cpp
index 406b95a0cc..271b7b1f7a 100644
--- a/src/pair_born.cpp
+++ b/src/pair_born.cpp
@@ -24,10 +24,12 @@
#include "comm.h"
#include "force.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -269,7 +271,6 @@ double PairBorn::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double rho1 = rho[i][j];
double rho2 = rho1*rho1;
double rho3 = rho2*rho1;
@@ -277,11 +278,11 @@ double PairBorn::init_one(int i, int j)
double rc2 = rc*rc;
double rc3 = rc2*rc;
double rc5 = rc3*rc2;
- etail_ij = 2.0*PI*all[0]*all[1] *
+ etail_ij = 2.0*MY_PI*all[0]*all[1] *
(a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1*
(rc2 + 2.0*rho1*rc + 2.0*rho2) -
c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5));
- ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] *
+ ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] *
(-a[i][j]*exp((sigma[i][j]-rc)/rho1) *
(rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) +
2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5));
diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp
index 0490f80eea..1a3464e27e 100644
--- a/src/pair_buck.cpp
+++ b/src/pair_buck.cpp
@@ -20,10 +20,12 @@
#include "comm.h"
#include "force.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -249,17 +251,16 @@ double PairBuck::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double rho1 = rho[i][j];
double rho2 = rho1*rho1;
double rho3 = rho2*rho1;
double rc = cut[i][j];
double rc2 = rc*rc;
double rc3 = rc2*rc;
- etail_ij = 2.0*PI*all[0]*all[1]*
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*
(a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) -
c[i][j]/(3.0*rc3));
- ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]*
+ ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]*
(-a[i][j]*exp(-rc/rho1)*
(rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3);
}
diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp
index 51c179b889..a2f0784a3d 100644
--- a/src/pair_buck_coul_cut.cpp
+++ b/src/pair_buck_coul_cut.cpp
@@ -24,10 +24,12 @@
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -304,17 +306,16 @@ double PairBuckCoulCut::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double rho1 = rho[i][j];
double rho2 = rho1*rho1;
double rho3 = rho2*rho1;
double rc = cut_lj[i][j];
double rc2 = rc*rc;
double rc3 = rc2*rc;
- etail_ij = 2.0*PI*all[0]*all[1]*
+ etail_ij = 2.0*MY_PI*all[0]*all[1]*
(a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) -
c[i][j]/(3.0*rc3));
- ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]*
+ ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]*
(-a[i][j]*exp(-rc/rho1)*
(rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3);
}
diff --git a/src/pair_lj96_cut.cpp b/src/pair_lj96_cut.cpp
index 76f808dd03..8eb9a3d9d5 100644
--- a/src/pair_lj96_cut.cpp
+++ b/src/pair_lj96_cut.cpp
@@ -29,10 +29,12 @@
#include "update.h"
#include "integrate.h"
#include "respa.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -589,15 +591,14 @@ double PairLJ96Cut::init_one(int i, int j)
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
- double PI = 4.0*atan(1.0);
double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j];
double sig6 = sig3*sig3;
double rc3 = cut[i][j]*cut[i][j]*cut[i][j];
double rc6 = rc3*rc3;
- etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig3 - 2.0*rc3) / (6.0*rc6);
- ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (3.0*sig3 - 4.0*rc3) / (6.0*rc6);
}
diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp
index 671d6420cf..44d86990df 100644
--- a/src/pair_lj_cut.cpp
+++ b/src/pair_lj_cut.cpp
@@ -29,10 +29,12 @@
#include "update.h"
#include "integrate.h"
#include "respa.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -583,15 +585,14 @@ double PairLJCut::init_one(int i, int j)
}
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[i][j]*cut[i][j]*cut[i][j];
double rc6 = rc3*rc3;
double rc9 = rc3*rc6;
- etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 8.0*MY_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] *
+ ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9);
}
diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp
index 1d311d4b72..c6973b2580 100644
--- a/src/pair_lj_cut_coul_cut.cpp
+++ b/src/pair_lj_cut_coul_cut.cpp
@@ -21,10 +21,12 @@
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -300,15 +302,14 @@ double PairLJCutCoulCut::init_one(int i, int j)
}
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] *
+ etail_ij = 8.0*MY_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] *
+ ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9);
}
diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp
index 57110ac81c..10e69ba977 100644
--- a/src/pair_lj_expand.cpp
+++ b/src/pair_lj_expand.cpp
@@ -19,10 +19,12 @@
#include "comm.h"
#include "force.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -259,7 +261,6 @@ double PairLJExpand::init_one(int i, int j)
}
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 shiftcut = shift[i][j] - cut[i][j];
@@ -273,11 +274,11 @@ double PairLJExpand::init_one(int i, int j)
double rc12 = rc11*shiftcut;
double shift2 = shift[i][j]*shift[i][j];
double shift3 = shift2*shift[i][j];
- etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6*((-1.0/(9.0*rc9) + shift[i][j]/(5.0*rc10) -
shift2/(11.0*rc11))*sig6 +
1.0/(3.0*rc3) - shift[i][j]/(2.0*rc4) + shift2/(5.0*rc5));
- ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] *
+ ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6* ((-4.0/(3.0*rc9) + 18.0*shift[i][j]/(5.0*rc10) -
36.0*shift2/(11.0*rc11) + shift3/rc12)*sig6 +
2.0/rc3 - 9.0*shift[i][j]/(2.0*rc4) +
diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp
index ce25f4a782..63f0b72b05 100644
--- a/src/pair_soft.cpp
+++ b/src/pair_soft.cpp
@@ -21,17 +21,16 @@
#include "force.h"
#include "update.h"
#include "neigh_list.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
-PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp)
-{
- PI = 4.0*atan(1.0);
-}
+PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) {}
/* ---------------------------------------------------------------------- */
@@ -95,9 +94,9 @@ void PairSoft::compute(int eflag, int vflag)
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
- arg = PI*r/cut[itype][jtype];
+ arg = MY_PI*r/cut[itype][jtype];
if (r > 0.0) fpair = factor_lj * prefactor[itype][jtype] *
- sin(arg) * PI/cut[itype][jtype]/r;
+ sin(arg) * MY_PI/cut[itype][jtype]/r;
else fpair = 0.0;
f[i][0] += delx*fpair;
@@ -290,9 +289,9 @@ double PairSoft::single(int i, int j, int itype, int jtype, double rsq,
double r,arg,philj;
r = sqrt(rsq);
- arg = PI*r/cut[itype][jtype];
+ arg = MY_PI*r/cut[itype][jtype];
fforce = factor_lj * prefactor[itype][jtype] *
- sin(arg) * PI/cut[itype][jtype]/r;
+ sin(arg) * MY_PI/cut[itype][jtype]/r;
philj = prefactor[itype][jtype] * (1.0+cos(arg));
return factor_lj*philj;
diff --git a/src/pair_soft.h b/src/pair_soft.h
index 1558f899bc..5cb8950659 100644
--- a/src/pair_soft.h
+++ b/src/pair_soft.h
@@ -43,7 +43,6 @@ class PairSoft : public Pair {
void *extract(char *, int &);
protected:
- double PI;
double cut_global;
double **prefactor;
double **cut;
diff --git a/src/set.h b/src/set.h
index 5e1fd4e8c7..00e0c77de1 100644
--- a/src/set.h
+++ b/src/set.h
@@ -35,7 +35,6 @@ class Set : protected Pointers {
int style,ivalue,newtype,count;
int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag;
double dvalue,xvalue,yvalue,zvalue,wvalue,fraction;
- double PI;
void selection(int);
void set(int);
diff --git a/src/thermo.cpp b/src/thermo.cpp
index 5bd877191a..b52a5f3c9c 100644
--- a/src/thermo.cpp
+++ b/src/thermo.cpp
@@ -36,10 +36,12 @@
#include "kspace.h"
#include "output.h"
#include "timer.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
// customize a new keyword by adding to this list:
@@ -147,8 +149,6 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
format_float_user = NULL;
format_int_user = NULL;
format_bigint_user = NULL;
-
- PI = 4.0*atan(1.0);
}
/* ---------------------------------------------------------------------- */
@@ -1894,7 +1894,7 @@ void Thermo::compute_cellalpha()
double* h = domain->h;
double cosalpha = (h[5]*h[4]+h[1]*h[3])/
sqrt((h[1]*h[1]+h[5]*h[5])*(h[2]*h[2]+h[3]*h[3]+h[4]*h[4]));
- dvalue = acos(cosalpha)*180.0/PI;
+ dvalue = acos(cosalpha)*180.0/MY_PI;
}
}
@@ -1910,7 +1910,7 @@ void Thermo::compute_cellbeta()
double* h = domain->h;
double cosbeta = h[4]/sqrt(h[2]*h[2]+h[3]*h[3]+h[4]*h[4]);
- dvalue = acos(cosbeta)*180.0/PI;
+ dvalue = acos(cosbeta)*180.0/MY_PI;
}
}
@@ -1926,6 +1926,6 @@ void Thermo::compute_cellgamma()
double* h = domain->h;
double cosgamma = h[5]/sqrt(h[1]*h[1]+h[5]*h[5]);
- dvalue = acos(cosgamma)*180.0/PI;
+ dvalue = acos(cosgamma)*180.0/MY_PI;
}
}
diff --git a/src/thermo.h b/src/thermo.h
index 352209cb35..eeb758b8e7 100644
--- a/src/thermo.h
+++ b/src/thermo.h
@@ -96,8 +96,6 @@ class Thermo : protected Pointers {
char **id_variable; // list of variable names
int *variables; // list of Variable indices
- double PI;
-
// private methods
void allocate();
From ae247d982aec3bc859224055c27196455f3bd25c Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:24:16 +0000
Subject: [PATCH 23/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7137
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/pair_hybrid.cpp | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp
index c23d694275..206782be27 100644
--- a/src/pair_hybrid.cpp
+++ b/src/pair_hybrid.cpp
@@ -195,10 +195,11 @@ void PairHybrid::settings(int narg, char **arg)
allocated = 0;
// count sub-styles by skipping numeric args
- // exception is 1st arg of style "table", which is non-numeric word
- // exception is 1st two args of style "lj/coul", which are non-numeric
- // exception is 1st two args of style "buck/coul", which are non-numeric
+ // exception is 1st arg of table style, which is non-numeric word
+ // exception is 1st two args of lj/coul style, which are non-numeric
+ // exception is 1st two args of buck/coul, which are non-numeric
// exception is 1st arg of reax/c style, which is non-numeric
+ // execption is 1st 6 args of gran styles, which can have NULLs
// need a better way to skip these exceptions
nstyles = 0;
@@ -208,6 +209,8 @@ void PairHybrid::settings(int narg, char **arg)
if (strcmp(arg[i],"lj/coul") == 0) i += 2;
if (strcmp(arg[i],"buck/coul") == 0) i += 2;
if (strcmp(arg[i],"reax/c") == 0) i++;
+ if (strstr(arg[i],"gran/hooke")) i += 6;
+ if (strstr(arg[i],"gran/hertz")) i += 6;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
nstyles++;
@@ -220,10 +223,11 @@ void PairHybrid::settings(int narg, char **arg)
// allocate each sub-style and call its settings() with subset of args
// define subset of args for a sub-style by skipping numeric args
- // exception is 1st arg of style "table", which is non-numeric
- // exception is 1st two args of style "lj/coul", which are non-numeric
- // exception is 1st two args of style "buck/coul", which are non-numeric
+ // exception is 1st arg of table style, which is non-numeric word
+ // exception is 1st two args of lj/coul style, which are non-numeric
+ // exception is 1st two args of buck/coul, which are non-numeric
// exception is 1st arg of reax/c style, which is non-numeric
+ // execption is 1st 6 args of gran styles, which can have NULLs
// need a better way to skip these exceptions
int dummy;
@@ -246,6 +250,8 @@ void PairHybrid::settings(int narg, char **arg)
if (strcmp(arg[i],"lj/coul") == 0) i += 2;
if (strcmp(arg[i],"buck/coul") == 0) i += 2;
if (strcmp(arg[i],"reax/c") == 0) i++;
+ if (strstr(arg[i],"gran/hooke")) i += 6;
+ if (strstr(arg[i],"gran/hertz")) i += 6;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]);
From 497290eadc9c14902a964956129cf929c8c6cf75 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:25:36 +0000
Subject: [PATCH 24/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7138
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/version.h b/src/version.h
index ca89fa4bf8..78212f2ce3 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "12 Oct 2011"
+#define LAMMPS_VERSION "19 Oct 2011"
From 1049b963d7aad64f55a6410d4fd5748f0b5379d2 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:32:41 +0000
Subject: [PATCH 25/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7140
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
lib/cuda/cuda_pair.cu | 6 ++++++
lib/cuda/cuda_pair_kernel.cu | 30 ++++++++++++++------------
lib/cuda/cuda_pair_virial_kernel_nc.cu | 2 +-
lib/cuda/cuda_precision.h | 25 ++++++++++++++++-----
lib/cuda/cuda_shared.h | 3 ++-
lib/cuda/neighbor.cu | 4 ++--
lib/cuda/neighbor_kernel.cu | 21 ++++++++++--------
7 files changed, 59 insertions(+), 32 deletions(-)
diff --git a/lib/cuda/cuda_pair.cu b/lib/cuda/cuda_pair.cu
index 531db7e2b3..b7b2523529 100644
--- a/lib/cuda/cuda_pair.cu
+++ b/lib/cuda/cuda_pair.cu
@@ -36,6 +36,9 @@ enum COUL_FORCES {COUL_NONE,COUL_CHARMM,COUL_CHARMM_IMPLICIT,COUL_CUT,COUL_LONG,
#define DATA_V_RADIUS 512
#define DATA_OMEGA_RMASS 1024
+#define SBBITS 30
+#define NEIGHMASK 0x3FFFFFFF
+
#define MY_PREFIX cuda_pair
#define IncludeCommonNeigh
#include "cuda_shared.h"
@@ -858,6 +861,9 @@ void Cuda_Pair_PostKernel_AllStyles(cuda_shared_data* sdata, dim3& grid, int& sh
#include "cuda_pair_kernel.cu"
+#include "pair_manybody_const.h"
+#include "pair_tersoff_cuda.cu"
+#include "pair_sw_cuda.cu"
void Cuda_Pair_UpdateNmax(cuda_shared_data* sdata)
{
diff --git a/lib/cuda/cuda_pair_kernel.cu b/lib/cuda/cuda_pair_kernel.cu
index fe7a38a782..35a0ef1f1a 100644
--- a/lib/cuda/cuda_pair_kernel.cu
+++ b/lib/cuda/cuda_pair_kernel.cu
@@ -20,7 +20,6 @@
This software is distributed under the GNU General Public License.
------------------------------------------------------------------------- */
-
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
@@ -29,6 +28,10 @@
#define A4 -1.453152027
#define A5 1.061405429
+inline __device__ int sbmask(int j) {
+ return j >> SBBITS & 3;
+}
+
template
__global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_atom)
{
@@ -88,8 +91,8 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at
fytmp = F_F(0.0);
fztmp = F_F(0.0);
- if(coul_type!=COUL_NONE)
- qtmp = fetchQ(i);
+ if(coul_type!=COUL_NONE)
+ qtmp = fetchQ(i);
jnum = _numneigh[i];
jlist = &_neighbors[i];
@@ -103,10 +106,10 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at
{
fpair=F_F(0.0);
j = jlist[jj*_nlocal];
- factor_lj = j<_nall ? F_F(1.0) : _special_lj[j/_nall];
- if(coul_type!=COUL_NONE)
- factor_coul = j<_nall ? F_F(1.0) : _special_coul[j/_nall];
- j = j<_nall ? j : j % _nall;
+ factor_lj = _special_lj[sbmask(j)];
+ if(coul_type!=COUL_NONE)
+ factor_coul = _special_coul[sbmask(j)];
+ j &= NEIGHMASK;
myxtype = fetchXType(j);
delx = xtmp - myxtype.x;
@@ -230,7 +233,6 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at
fpair += forcecoul*r2inv;
}
break;
-
}
}
in_cutoff=in_cutoff || in_coul_cutoff;
@@ -388,12 +390,12 @@ template nex_mol|sneighlist->nex_group|sneighlist->nex_type;
if(exclude)
NeighborBuildFullBin_Kernel<1><<>>
- (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom);
+ (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall);
else
NeighborBuildFullBin_Kernel<0><<>>
- (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom);
+ (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall);
}
//NeighborBuildFullBin_Kernel_Restrict<<>>
// (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff);
diff --git a/lib/cuda/neighbor_kernel.cu b/lib/cuda/neighbor_kernel.cu
index ad1a6a8fe7..965aa2b1cf 100644
--- a/lib/cuda/neighbor_kernel.cu
+++ b/lib/cuda/neighbor_kernel.cu
@@ -21,6 +21,8 @@
This software is distributed under the GNU General Public License.
------------------------------------------------------------------------- */
+#define SBBITS 30
+
__global__ void Binning_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,int bin_dim_z,
CUDA_FLOAT rez_bin_size_x,CUDA_FLOAT rez_bin_size_y,CUDA_FLOAT rez_bin_size_z)
{
@@ -109,8 +111,9 @@ __device__ inline int find_special(int3 &n, int* list,int & tag,int3 flag)
}
template
-__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style)
+__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style, bool neighall)
{
+ int natoms = neighall?_nall:_nlocal;
//const bool domol=false;
int bin_dim_z=gridDim.y;
CUDA_FLOAT* binned_x=(CUDA_FLOAT*) _buffer;
@@ -152,7 +155,7 @@ __global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_
int jnum=0;
int itype;
- if(i<_nlocal)
+ if(i _maxneighbors) ((int*)_buffer)[0] = -jnum;
- if(i<_nlocal)
+ if(i0)
{
if(block_style)
- _neighbors[i*_maxneighbors+k]=j+which*_nall;
+ _neighbors[i*_maxneighbors+k]=j ^ (which << SBBITS);
else
- _neighbors[i+k*_nlocal]=j+which*_nall;
+ _neighbors[i+k*_nlocal]=j ^ (which << SBBITS);
}
else if(which<0)
{
From dcbe4d90bac3d1b6d7215e691ce48dea395a55f7 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:32:57 +0000
Subject: [PATCH 26/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7141
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
lib/cuda/pair_sw_cuda.cu | 140 +++
lib/cuda/pair_sw_cuda_cu.h | 39 +
lib/cuda/pair_sw_cuda_kernel_nc.cu | 449 ++++++++++
lib/cuda/pair_tersoff_cuda.cu | 155 ++++
lib/cuda/pair_tersoff_cuda_cu.h | 42 +
lib/cuda/pair_tersoff_cuda_kernel_nc.cu | 1054 +++++++++++++++++++++++
6 files changed, 1879 insertions(+)
create mode 100644 lib/cuda/pair_sw_cuda.cu
create mode 100644 lib/cuda/pair_sw_cuda_cu.h
create mode 100644 lib/cuda/pair_sw_cuda_kernel_nc.cu
create mode 100644 lib/cuda/pair_tersoff_cuda.cu
create mode 100644 lib/cuda/pair_tersoff_cuda_cu.h
create mode 100644 lib/cuda/pair_tersoff_cuda_kernel_nc.cu
diff --git a/lib/cuda/pair_sw_cuda.cu b/lib/cuda/pair_sw_cuda.cu
new file mode 100644
index 0000000000..f5b0807fcd
--- /dev/null
+++ b/lib/cuda/pair_sw_cuda.cu
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#include
+
+#include "pair_sw_cuda_cu.h"
+__device__ __constant__ ParamSW_Float params_sw[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR];
+
+#include "pair_sw_cuda_kernel_nc.cu"
+
+#include
+
+
+void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h)
+{
+ unsigned cuda_ntypes = sdata->atom.ntypes + 1;
+ X_FLOAT box_size[3] =
+ {
+ sdata->domain.subhi[0] - sdata->domain.sublo[0],
+ sdata->domain.subhi[1] - sdata->domain.sublo[1],
+ sdata->domain.subhi[2] - sdata->domain.sublo[2]
+ };
+
+ cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3);
+ cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) );
+ cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) );
+ cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) );
+ cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 );
+ cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) );
+ cudaMemcpyToSymbol("params_sw", params_host , sizeof(ParamSW_Float)*nelements_h*nelements_h*nelements_h );
+ cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h );
+ cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes );
+ cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int));
+}
+
+void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom)
+{
+ static int glob_ij_size=0;
+ static F_FLOAT4* glob_r_ij=NULL;
+ static int* glob_numneigh_red=NULL;
+ static int* glob_neighbors_red=NULL;
+ static int* glob_neightype_red=NULL;
+
+ if(glob_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT))
+ {
+ glob_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT);
+ cudaFree(glob_r_ij);
+ cudaFree(glob_numneigh_red);
+ cudaFree(glob_neighbors_red);
+ cudaFree(glob_neightype_red);
+ cudaMalloc(&glob_r_ij,glob_ij_size*4);
+ cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int));
+ cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int));
+ cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int));
+ cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) );
+ }
+ dim3 grid,threads;
+ int sharedperproc;
+
+ Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64);
+ cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams();
+
+
+
+ dim3 grid2;
+ if(sdata->atom.nall<=256*64000){
+ grid2.x = (sdata->atom.nall+255)/256;
+ grid2.y = 1;
+ } else {
+ grid2.x = (sdata->atom.nall+256*128-1)/(256*128);
+ grid2.y = 128;
+ }
+ grid2.z = 1;
+ dim3 threads2;
+ threads2.x = 256;
+ threads2.y = 1;
+ threads2.z = 1;
+
+ timespec time1,time2;
+
+ //pre-calculate all neighbordistances and zeta_ij
+ clock_gettime(CLOCK_REALTIME,&time1);
+ Pair_SW_Kernel_TpA_RIJ<<>>();
+ cudaThreadSynchronize();
+ clock_gettime(CLOCK_REALTIME,&time2);
+ sdata->cuda_timings.test1+=
+ time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000;
+ clock_gettime(CLOCK_REALTIME,&time1);
+
+ //actual force calculation
+ unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure
+ if(eflag)
+ {
+ if(vflag)
+ Pair_SW_Kernel_TpA<1,1><<>>
+ (eflag_atom,vflag_atom);
+ else
+ Pair_SW_Kernel_TpA<1,0><<>>
+ (eflag_atom,vflag_atom);
+ }
+ else
+ {
+ if(vflag)
+ Pair_SW_Kernel_TpA<0,1><<>>
+ (eflag_atom,vflag_atom);
+ else
+ Pair_SW_Kernel_TpA<0,0><<>>
+ (eflag_atom,vflag_atom);
+ }
+ cudaThreadSynchronize();
+ clock_gettime(CLOCK_REALTIME,&time2);
+ sdata->cuda_timings.test2+=
+ time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000;
+
+ Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag);
+}
+
diff --git a/lib/cuda/pair_sw_cuda_cu.h b/lib/cuda/pair_sw_cuda_cu.h
new file mode 100644
index 0000000000..24e92689ff
--- /dev/null
+++ b/lib/cuda/pair_sw_cuda_cu.h
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#include "cuda_shared.h"
+
+ struct ParamSW_Float {
+ F_FLOAT epsilon,sigma;
+ F_FLOAT littlea,lambda,gamma,costheta;
+ F_FLOAT biga,bigb;
+ F_FLOAT powerp,powerq;
+ F_FLOAT tol;
+ F_FLOAT cut,cutsq;
+ F_FLOAT sigma_gamma,lambda_epsilon,lambda_epsilon2;
+ F_FLOAT c1,c2,c3,c4,c5,c6;
+ int ielement,jelement,kelement;
+ };
+
+extern "C" void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h);
+extern "C" void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom);
diff --git a/lib/cuda/pair_sw_cuda_kernel_nc.cu b/lib/cuda/pair_sw_cuda_kernel_nc.cu
new file mode 100644
index 0000000000..8072822559
--- /dev/null
+++ b/lib/cuda/pair_sw_cuda_kernel_nc.cu
@@ -0,0 +1,449 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+#define Pi F_F(3.1415926535897932384626433832795)
+#define PI Pi
+#define PI2 F_F(0.5)*Pi
+#define PI4 F_F(0.25)*Pi
+
+
+
+__device__ void twobody(int iparam, F_FLOAT rsq, F_FLOAT &fforce,
+ int eflag, ENERGY_FLOAT &eng)
+{
+ F_FLOAT r,rp,rq,rainv,expsrainv;
+
+ r = sqrt(rsq);
+ rp = pow(r,-params_sw[iparam].powerp);
+ rq = pow(r,-params_sw[iparam].powerq);
+ rainv = 1.0 / (r - params_sw[iparam].cut);
+ expsrainv = exp(params_sw[iparam].sigma * rainv);
+ fforce = (params_sw[iparam].c1*rp - params_sw[iparam].c2*rq +
+ (params_sw[iparam].c3*rp -params_sw[iparam].c4*rq) * rainv*rainv*r) * expsrainv / rsq;
+ if (eflag) eng += (params_sw[iparam].c5*rp - params_sw[iparam].c6*rq) * expsrainv;
+}
+
+__device__ void threebody(int paramij, int paramik, int paramijk,
+ F_FLOAT4& delr1,
+ F_FLOAT4& delr2,
+ F_FLOAT3& fj, F_FLOAT3& fk, int eflag,ENERGY_FLOAT &eng)
+{
+ F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1;
+ F_FLOAT r2,rinvsq2,rainv2,gsrainv2,gsrainvsq2,expgsrainv2;
+ F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1,frad2;
+ F_FLOAT facang,facang12,csfacang,csfac1,csfac2;
+
+ r1 = sqrt(delr1.w);
+ rinvsq1 = F_F(1.0)/delr1.w;
+ rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut);
+ gsrainv1 = params_sw[paramij].sigma_gamma * rainv1;
+ gsrainvsq1 = gsrainv1*rainv1/r1;
+ expgsrainv1 = exp(gsrainv1);
+
+ r2 = sqrt(delr2.w);
+ rinvsq2 = F_F(1.0)/delr2.w;
+ rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut);
+ gsrainv2 = params_sw[paramik].sigma_gamma * rainv2;
+ gsrainvsq2 = gsrainv2*rainv2/r2;
+ expgsrainv2 = exp(gsrainv2);
+
+ rinv12 = F_F(1.0)/(r1*r2);
+ cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12;
+ delcs = cs - params_sw[paramijk].costheta;
+ delcssq = delcs*delcs;
+
+ facexp = expgsrainv1*expgsrainv2;
+
+ // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) *
+ // facexp*delcssq;
+
+ facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq;
+ frad1 = facrad*gsrainvsq1;
+ frad2 = facrad*gsrainvsq2;
+ facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs;
+ facang12 = rinv12*facang;
+ csfacang = cs*facang;
+ csfac1 = rinvsq1*csfacang;
+
+ fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12;
+ fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12;
+ fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12;
+
+ csfac2 = rinvsq2*csfacang;
+
+ fk.x = delr2.x*(frad2+csfac2)-delr1.x*facang12;
+ fk.y = delr2.y*(frad2+csfac2)-delr1.y*facang12;
+ fk.z = delr2.z*(frad2+csfac2)-delr1.z*facang12;
+
+ if (eflag) eng+= F_F(2.0)*facrad;
+}
+
+__device__ void threebody_fj(int paramij, int paramik, int paramijk,
+ F_FLOAT4& delr1,
+ F_FLOAT4& delr2,
+ F_FLOAT3& fj)
+{
+ F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1;
+ F_FLOAT r2,rainv2,gsrainv2,expgsrainv2;
+ F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1;
+ F_FLOAT facang,facang12,csfacang,csfac1;
+
+ r1 = sqrt(delr1.w);
+ rinvsq1 = F_F(1.0)/delr1.w;
+ rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut);
+ gsrainv1 = params_sw[paramij].sigma_gamma * rainv1;
+ gsrainvsq1 = gsrainv1*rainv1/r1;
+ expgsrainv1 = exp(gsrainv1);
+
+ r2 = sqrt(delr2.w);
+ rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut);
+ gsrainv2 = params_sw[paramik].sigma_gamma * rainv2;
+ expgsrainv2 = exp(gsrainv2);
+
+ rinv12 = F_F(1.0)/(r1*r2);
+ cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12;
+ delcs = cs - params_sw[paramijk].costheta;
+ delcssq = delcs*delcs;
+
+ facexp = expgsrainv1*expgsrainv2;
+
+ // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) *
+ // facexp*delcssq;
+
+ facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq;
+ frad1 = facrad*gsrainvsq1;
+ facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs;
+ facang12 = rinv12*facang;
+ csfacang = cs*facang;
+ csfac1 = rinvsq1*csfacang;
+
+ fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12;
+ fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12;
+ fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12;
+}
+
+
+__global__ void Pair_SW_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red)
+{
+ int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+ if( ii >= _nall ) return;
+
+ X_FLOAT4 myxtype;
+ F_FLOAT4 delij;
+ F_FLOAT xtmp,ytmp,ztmp;
+ int itype,jnum,i,j;
+ int* jlist;
+ int neigh_red = 0;
+ i = ii;//_ilist[ii];
+ myxtype = fetchXType(i);
+
+ xtmp=myxtype.x;
+ ytmp=myxtype.y;
+ ztmp=myxtype.z;
+ itype=map[(static_cast (myxtype.w))];
+
+ jnum = _numneigh[i];
+ jlist = &_neighbors[i];
+
+ __syncthreads();
+ for (int jj = 0; jj < jnum; jj++)
+ {
+ if(jj (myxtype.w))];
+ int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype];
+ delij.w = vec3_dot(delij,delij);
+ if (delij.w < params_sw[iparam_ij].cutsq)
+ {
+ _glob_neighbors_red[i+neigh_red*_nall]=j;
+ _glob_neightype_red[i+neigh_red*_nall]=jtype;
+ _glob_r_ij[i+neigh_red*_nall]=delij;
+ neigh_red++;
+ }
+ }
+ }
+ _glob_numneigh_red[i]=neigh_red;
+}
+
+
+ template
+ __global__ void Pair_SW_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red)
+{
+ ENERGY_FLOAT evdwl = ENERGY_F(0.0);
+
+ ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x];
+ ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x];
+
+ F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem;
+ if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x];
+ else
+ if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x];
+ else
+ if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x];
+ shared_F_F+=threadIdx.x;
+
+ if(eflag_atom||eflag)
+ {
+ sharedE[0] = ENERGY_F(0.0);
+ sharedV += blockDim.x;
+ }
+
+ if(vflagm||vflag_atom)
+ {
+ sharedV[0*blockDim.x] = ENERGY_F(0.0);
+ sharedV[1*blockDim.x] = ENERGY_F(0.0);
+ sharedV[2*blockDim.x] = ENERGY_F(0.0);
+ sharedV[3*blockDim.x] = ENERGY_F(0.0);
+ sharedV[4*blockDim.x] = ENERGY_F(0.0);
+ sharedV[5*blockDim.x] = ENERGY_F(0.0);
+ }
+
+ int jnum_red=0;
+#define fxtmp shared_F_F[0]
+#define fytmp shared_F_F[blockDim.x]
+#define fztmp shared_F_F[2*blockDim.x]
+//#define jnum_red (static_cast (shared_F_F[3*blockDim.x]))
+
+ int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+ X_FLOAT4 myxtype_i,myxtype_j,myxtype_k;
+ F_FLOAT4 delij,delik,deljk;
+ F_FLOAT fpair;
+
+ int itype,i,j;
+ int* jlist_red;
+
+ if(ii < _inum)
+ {
+ i = _ilist[ii];
+
+ if(vflagm)
+ myxtype_i=fetchXType(i);
+ //itype=map[(static_cast (myxtype_i.w))];
+ itype=map[_type[i]];
+
+
+ fxtmp = F_F(0.0);
+ fytmp = F_F(0.0);
+ fztmp = F_F(0.0);
+
+
+ //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i];
+ jnum_red = _glob_numneigh_red[i];
+ jlist_red = &_glob_neighbors_red[i];
+ }
+ __syncthreads();
+#pragma unroll 1
+ for (int jj = 0; jj < jnum_red; jj++)
+ {
+ if(i < _nlocal)
+ {
+ fpair=F_F(0.0);
+ j = jlist_red[jj*_nall];
+ j &= NEIGHMASK;
+
+ if(vflagm)
+ myxtype_j = fetchXType(j);
+
+ int jtype = _glob_neightype_red[i+jj*_nall];
+ delij = _glob_r_ij[i+jj*_nall];
+
+ volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype];
+ volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype];
+
+ if (delij.w();
+#undef fxtmp
+#undef fytmp
+#undef fztmp
+//#undef jnum_red
+}
diff --git a/lib/cuda/pair_tersoff_cuda.cu b/lib/cuda/pair_tersoff_cuda.cu
new file mode 100644
index 0000000000..abbf39ecf0
--- /dev/null
+++ b/lib/cuda/pair_tersoff_cuda.cu
@@ -0,0 +1,155 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#include
+
+
+#include "pair_tersoff_cuda_cu.h"
+__device__ __constant__ Param_Float params[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR];
+__device__ __constant__ F_FLOAT* _glob_zeta_ij; //zeta_ij
+__device__ __constant__ F_FLOAT4* _glob_r_ij; //r_ij (x,y,z,r^2) for pairs within force cutoff
+__device__ __constant__ bool _zbl; //is tersoff zbl?
+
+
+#include "pair_tersoff_cuda_kernel_nc.cu"
+
+#include
+
+
+void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl)
+{
+ unsigned cuda_ntypes = sdata->atom.ntypes + 1;
+ X_FLOAT box_size[3] =
+ {
+ sdata->domain.subhi[0] - sdata->domain.sublo[0],
+ sdata->domain.subhi[1] - sdata->domain.sublo[1],
+ sdata->domain.subhi[2] - sdata->domain.sublo[2]
+ };
+
+ cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3);
+ cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) );
+ cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) );
+ cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) );
+ cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 );
+ cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) );
+ cudaMemcpyToSymbol("params", params_host , sizeof(Param_Float)*nelements_h*nelements_h*nelements_h );
+ cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h );
+ cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes );
+ cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int));
+ cudaMemcpyToSymbol("_zbl",&zbl,sizeof(bool));
+
+}
+
+void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom)
+{
+ static F_FLOAT* glob_zeta_ij=NULL;
+ static int glob_zeta_ij_size=0;
+ static F_FLOAT4* glob_r_ij=NULL;
+ static int* glob_numneigh_red=NULL;
+ static int* glob_neighbors_red=NULL;
+ static int* glob_neightype_red=NULL;
+
+ if(glob_zeta_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT))
+ {
+ glob_zeta_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT);
+ cudaFree(glob_zeta_ij);
+ cudaFree(glob_r_ij);
+ cudaFree(glob_numneigh_red);
+ cudaFree(glob_neighbors_red);
+ cudaFree(glob_neightype_red);
+ cudaMalloc(&glob_zeta_ij,glob_zeta_ij_size);
+ cudaMalloc(&glob_r_ij,glob_zeta_ij_size*4);
+ cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int));
+ cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int));
+ cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int));
+ cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) );
+ cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) );
+ cudaMemcpyToSymbol("_glob_zeta_ij", &glob_zeta_ij , sizeof(F_FLOAT*) );
+ }
+ dim3 grid,threads;
+ int sharedperproc;
+
+ Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64);
+ cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams();
+
+
+
+ dim3 grid2;
+ if(sdata->atom.nall<=256*64000){
+ grid2.x = (sdata->atom.nall+255)/256;
+ grid2.y = 1;
+ } else {
+ grid2.x = (sdata->atom.nall+256*128-1)/(256*128);
+ grid2.y = 128;
+ }
+ grid2.z = 1;
+ dim3 threads2;
+ threads2.x = 256;
+ threads2.y = 1;
+ threads2.z = 1;
+
+ timespec time1,time2;
+
+ //pre-calculate all neighbordistances and zeta_ij
+ clock_gettime(CLOCK_REALTIME,&time1);
+ Pair_Tersoff_Kernel_TpA_RIJ<<>>
+ ();
+ cudaThreadSynchronize();
+ Pair_Tersoff_Kernel_TpA_ZetaIJ<<>>
+ ();
+ cudaThreadSynchronize();
+ clock_gettime(CLOCK_REALTIME,&time2);
+ sdata->cuda_timings.test1+=
+ time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000;
+ clock_gettime(CLOCK_REALTIME,&time1);
+
+ //actual force calculation
+ unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure
+ if(eflag)
+ {
+ if(vflag)
+ Pair_Tersoff_Kernel_TpA<1,1><<>>
+ (eflag_atom,vflag_atom);
+ else
+ Pair_Tersoff_Kernel_TpA<1,0><<>>
+ (eflag_atom,vflag_atom);
+ }
+ else
+ {
+ if(vflag)
+ Pair_Tersoff_Kernel_TpA<0,1><<>>
+ (eflag_atom,vflag_atom);
+ else
+ Pair_Tersoff_Kernel_TpA<0,0><<>>
+ (eflag_atom,vflag_atom);
+ }
+ cudaThreadSynchronize();
+ clock_gettime(CLOCK_REALTIME,&time2);
+ sdata->cuda_timings.test2+=
+ time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000;
+
+ Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag);
+}
+
diff --git a/lib/cuda/pair_tersoff_cuda_cu.h b/lib/cuda/pair_tersoff_cuda_cu.h
new file mode 100644
index 0000000000..5276cd1c35
--- /dev/null
+++ b/lib/cuda/pair_tersoff_cuda_cu.h
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#include "cuda_shared.h"
+
+ struct Param_Float {
+ F_FLOAT lam1,lam2,lam3;
+ F_FLOAT c,d,h;
+ F_FLOAT gamma,powerm;
+ F_FLOAT powern,beta;
+ F_FLOAT biga,bigb,bigd,bigr;
+ F_FLOAT cut,cutsq;
+ F_FLOAT c1,c2,c3,c4;
+ int ielement,jelement,kelement;
+ int powermint;
+ //F_FLOAT Z_i,Z_j;
+ F_FLOAT ZBLcut,ZBLexpscale;
+ F_FLOAT a_ij,premult;
+ };
+
+extern "C" void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl);
+extern "C" void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom);
diff --git a/lib/cuda/pair_tersoff_cuda_kernel_nc.cu b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu
new file mode 100644
index 0000000000..f94f35a587
--- /dev/null
+++ b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu
@@ -0,0 +1,1054 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+#define Pi F_F(3.1415926535897932384626433832795)
+#define PI Pi
+#define PI2 F_F(0.5)*Pi
+#define PI4 F_F(0.25)*Pi
+template
+static inline __device__ void PairVirialCompute_A_Kernel_Template()
+{
+ __syncthreads();
+ ENERGY_FLOAT* shared=sharedmem;
+
+ if(eflag)
+ {
+ reduceBlock(shared);
+ shared+=blockDim.x;
+ }
+ if(vflag)
+ {
+ reduceBlock(shared + 0 * blockDim.x);
+ reduceBlock(shared + 1 * blockDim.x);
+ reduceBlock(shared + 2 * blockDim.x);
+ reduceBlock(shared + 3 * blockDim.x);
+ reduceBlock(shared + 4 * blockDim.x);
+ reduceBlock(shared + 5 * blockDim.x);
+ }
+ if(threadIdx.x == 0)
+ {
+ shared=sharedmem;
+ ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer;
+ if(eflag)
+ {
+ buffer[blockIdx.x * gridDim.y + blockIdx.y] = ENERGY_F(0.5)*shared[0];
+ shared+=blockDim.x; buffer+=gridDim.x * gridDim.y;
+ }
+ if(vflag)
+ {
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 0 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[0 * blockDim.x];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 1 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[1 * blockDim.x];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 2 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[2 * blockDim.x];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 3 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[3 * blockDim.x];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 4 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[4 * blockDim.x];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + 5 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[5 * blockDim.x];
+ }
+ }
+ __syncthreads();
+}
+
+__global__ void virial_fdotr_compute_kernel(int eflag)
+{
+ int i = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+ ENERGY_FLOAT* sharedE = (ENERGY_FLOAT*) &sharedmem[0];
+ ENERGY_FLOAT* sharedVirial = (ENERGY_FLOAT*) &sharedE[blockDim.x];
+ sharedE+=threadIdx.x;
+ sharedVirial+=threadIdx.x;
+ if(i<_nlocal)
+ {
+
+ F_FLOAT x = _x[i];
+ F_FLOAT y = _x[i+_nmax];
+ F_FLOAT z = _x[i+2*_nmax];
+ F_FLOAT fx = _f[i];
+ F_FLOAT fy = _f[i+_nmax];
+ F_FLOAT fz = _f[i+2*_nmax];
+ //if(fz*z*fz*z>1e-5) printf("V %i %i %e %e %e %e %e %e\n",i,_tag[i],x,y,z,fx,fy,fz);
+ sharedVirial[0] = fx*x;
+ sharedVirial[1*blockDim.x] = fy*y;
+ sharedVirial[2*blockDim.x] = fz*z;
+ sharedVirial[3*blockDim.x] = fy*x;
+ sharedVirial[4*blockDim.x] = fz*x;
+ sharedVirial[5*blockDim.x] = fz*y;
+ } else {
+ sharedVirial[0] = 0;
+ sharedVirial[1*blockDim.x] = 0;
+ sharedVirial[2*blockDim.x] = 0;
+ sharedVirial[3*blockDim.x] = 0;
+ sharedVirial[4*blockDim.x] = 0;
+ sharedVirial[5*blockDim.x] = 0;
+ }
+ sharedVirial = (ENERGY_FLOAT*) &sharedmem[0];
+ sharedVirial += blockDim.x;
+ reduceBlockP2(sharedVirial);
+ reduceBlockP2(&sharedVirial[1*blockDim.x]);
+ reduceBlockP2(&sharedVirial[2*blockDim.x]);
+ reduceBlockP2(&sharedVirial[3*blockDim.x]);
+ reduceBlockP2(&sharedVirial[4*blockDim.x]);
+ reduceBlockP2(&sharedVirial[5*blockDim.x]);
+ if(threadIdx.x<6)
+ {
+ ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer;
+ if(eflag) buffer = &buffer[gridDim.x*gridDim.y];
+ buffer[blockIdx.x * gridDim.y + blockIdx.y + threadIdx.x * gridDim.x * gridDim.y]= sharedVirial[threadIdx.x*blockDim.x];
+ }
+}
+
+/*#define vec3_scale(K,X,Y) Y.x = K*X.x; Y.y = K*X.y; Y.z = K*X.z;
+#define vec3_scaleadd(K,X,Y,Z) Z.x = K*X.x+Y.x; Z.y = K*X.y+Y.y; Z.z = K*X.z+Y.z;
+#define vec3_add(X,Y,Z) Z.x = X.x+Y.x; Z.y = X.y+Y.y; Z.z = X.z+Y.z;
+#define vec3_dot(X,Y) (X.x*Y.x + X.y*Y.y + X.z*Y.z)*/
+
+__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y) {
+ y.x = k*x.x; y.y = k*x.y; y.z = k*x.z;
+}
+
+__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT3& y) {
+ y.x = k*x.x; y.y = k*x.y; y.z = k*x.z;
+}
+
+__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT4& y) {
+ y.x = k*x.x; y.y = k*x.y; y.z = k*x.z;
+}
+
+__device__ inline void vec3_scaleadd(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) {
+ z.x = k*x.x+y.x; z.y = k*x.y+y.y; z.z = k*x.z+y.z;
+}
+
+__device__ inline void vec3_add(F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) {
+ z.x = x.x+y.x; z.y = x.y+y.y; z.z = x.z+y.z;
+}
+
+__device__ inline F_FLOAT vec3_dot(F_FLOAT3 x, F_FLOAT3 y) {
+ return x.x*y.x + x.y*y.y + x.z*y.z;
+}
+
+__device__ inline F_FLOAT vec3_dot(F_FLOAT4 x, F_FLOAT4 y) {
+ return x.x*y.x + x.y*y.y + x.z*y.z;
+}
+
+/* ----------------------------------------------------------------------
+ Fermi-like smoothing function
+------------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT F_fermi(F_FLOAT &r, int &iparam)
+{
+ return F_F(1.0) / (F_F(1.0) + exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut)));
+}
+
+/* ----------------------------------------------------------------------
+ Fermi-like smoothing function derivative with respect to r
+------------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT F_fermi_d(F_FLOAT &r, int &iparam)
+{
+ volatile const F_FLOAT tmp = exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut));
+ return params[iparam].ZBLexpscale*tmp /
+ ((F_F(1.0) +tmp)*(F_F(1.0) +tmp));
+}
+
+__device__ inline F_FLOAT ters_fc(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D)
+{
+ return (r < ters_R-ters_D)?F_F(1.0):((r > ters_R+ters_D)?
+ F_F(0.0):F_F(0.5)*(F_F(1.0) - sin(PI2*(r - ters_R)/ters_D)));
+}
+
+__device__ inline F_FLOAT ters_fc_d(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D)
+{
+ return ((r < ters_R-ters_D)||(r > ters_R+ters_D))?
+ F_F(0.0):-(PI4/ters_D) * cos(PI2*(r - ters_R)/ters_D);
+}
+
+
+__device__ inline F_FLOAT ters_gijk(F_FLOAT& cos_theta, int iparam)
+{
+ F_FLOAT ters_c = params[iparam].c;
+ F_FLOAT ters_d = params[iparam].d;
+
+ return params[iparam].gamma*(F_F(1.0) + pow(params[iparam].c/params[iparam].d,F_F(2.0)) -
+ pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0))));
+}
+
+__device__ F_FLOAT ters_gijk2(F_FLOAT& cos_theta, int iparam)
+{
+ F_FLOAT ters_c = params[iparam].c;
+ F_FLOAT ters_d = params[iparam].d;
+
+ return params[iparam].gamma*(F_F(1.0) + pow(ters_c/ters_d,F_F(2.0)) -
+ pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0))));
+}
+
+__device__ inline F_FLOAT ters_gijk_d(F_FLOAT costheta, int iparam)
+{
+ F_FLOAT numerator = -F_F(2.0) * pow(params[iparam].c,F_F(2.0)) * (params[iparam].h - costheta);
+ F_FLOAT denominator = pow(pow(params[iparam].d,F_F(2.0)) +
+ pow(params[iparam].h - costheta,F_F(2.0)),F_F(2.0));
+ return params[iparam].gamma*numerator/denominator;
+}
+
+__device__ inline F_FLOAT zeta(int iparam, const F_FLOAT rsqij, const F_FLOAT rsqik,
+ F_FLOAT3& delij, F_FLOAT3& delik)
+{
+ F_FLOAT rij,rik,costheta,arg,ex_delr;
+
+ rij = sqrt(rsqij);
+ rik = sqrt(rsqik);
+ costheta = vec3_dot(delij,delik) / (rij*rik);
+
+ arg = (params[iparam].powermint == 3)? (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)) : params[iparam].lam3 * (rij-rik);
+
+ if (arg > F_F(69.0776)) ex_delr = F_F(1.e30);
+ else if (arg < -F_F(69.0776)) ex_delr = F_F(0.0);
+ else ex_delr = exp(arg);
+
+ return ters_fc(rik,params[iparam].bigr,params[iparam].bigd) * ex_delr * params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c/(params[iparam].d*params[iparam].d)) -
+ (params[iparam].c*params[iparam].c) / ((params[iparam].d*params[iparam].d) + (params[iparam].h - costheta)*(params[iparam].h - costheta)));
+}
+
+__device__ void repulsive(int iparam, F_FLOAT rsq, F_FLOAT &fforce,
+ int eflag, ENERGY_FLOAT &eng)
+{
+ F_FLOAT r,tmp_fc,tmp_fc_d,tmp_exp;
+
+ F_FLOAT ters_R = params[iparam].bigr;
+ F_FLOAT ters_D = params[iparam].bigd;
+ r = sqrt(rsq);
+ tmp_fc = ters_fc(r,ters_R,ters_D);
+ tmp_fc_d = ters_fc_d(r,ters_R,ters_D);
+ tmp_exp = exp(-params[iparam].lam1 * r);
+ if(!_zbl)
+ {
+ fforce = -params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1) / r;
+ if (eflag) eng += tmp_fc * params[iparam].biga * tmp_exp;
+ }
+ else
+ {
+ F_FLOAT const fforce_ters = params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1);
+ ENERGY_FLOAT eng_ters = tmp_fc * params[iparam].biga * tmp_exp;
+
+ F_FLOAT r_ov_a = r/params[iparam].a_ij;
+ F_FLOAT phi = F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) + F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) +
+ F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) + F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a);
+ F_FLOAT dphi = (F_F(1.0)/params[iparam].a_ij) * (-F_F(3.2)*F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) -
+ F_F(0.9423)*F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) -
+ F_F(0.4029)*F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) -
+ F_F(0.2016)*F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a));
+ F_FLOAT fforce_ZBL = params[iparam].premult/(-r*r)* phi + params[iparam].premult/r*dphi;
+ ENERGY_FLOAT eng_ZBL = params[iparam].premult*(F_F(1.0)/r)*phi;
+
+ fforce = -(-F_fermi_d(r,iparam) * (eng_ZBL - eng_ters) + fforce_ZBL + F_fermi(r,iparam)*(fforce_ters-fforce_ZBL))/r;
+ if(eflag)
+ eng += eng_ZBL + F_fermi(r,iparam)*(eng_ters-eng_ZBL);
+ }
+
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT ters_fa(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D)
+{
+ if (r > ters_R + ters_D) return F_F(0.0);
+ if(_zbl)
+ return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D) * F_fermi(r,iparam);
+ else
+ return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D);
+}
+
+/* ---------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT ters_fa_d(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D)
+{
+ if (r > ters_R + ters_D) return F_F(0.0);
+ if(_zbl)
+ return params[iparam].bigb * exp(-params[iparam].lam2 * r) *
+ ((params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D))*F_fermi(r,iparam)
+ -ters_fc(r,ters_R,ters_D)*F_fermi_d(r,iparam));
+ else
+ return params[iparam].bigb * exp(-params[iparam].lam2 * r) *
+ (params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D));
+}
+
+/* ---------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT ters_bij(F_FLOAT zeta, int iparam)
+{
+ F_FLOAT tmp = params[iparam].beta * zeta;
+ if (tmp > params[iparam].c1) return F_F(1.0)/sqrt(tmp);
+ if (tmp > params[iparam].c2)
+ return (F_F(1.0) - pow(tmp,-params[iparam].powern) / (F_F(2.0)*params[iparam].powern))/sqrt(tmp);
+ if (tmp < params[iparam].c4) return F_F(1.0);
+ if (tmp < params[iparam].c3)
+ return F_F(1.0) - pow(tmp,params[iparam].powern)/(F_F(2.0)*params[iparam].powern);
+ return pow(F_F(1.0) + pow(tmp,params[iparam].powern), -F_F(1.0)/(F_F(2.0)*params[iparam].powern));
+}
+
+/* ---------------------------------------------------------------------- */
+
+__device__ inline F_FLOAT ters_bij_d(F_FLOAT zeta, int iparam)
+{
+ F_FLOAT tmp = params[iparam].beta * zeta;
+ if (tmp > params[iparam].c1) return params[iparam].beta * -F_F(0.5)*pow(tmp,-F_F(1.5));
+ if (tmp > params[iparam].c2)
+ return params[iparam].beta * (-F_F(0.5)*pow(tmp,-F_F(1.5)) *
+ (F_F(1.0) - F_F(0.5)*(F_F(1.0) + F_F(1.0)/(F_F(2.0)*params[iparam].powern)) *
+ pow(tmp,-params[iparam].powern)));
+ if (tmp < params[iparam].c4) return F_F(0.0);
+ if (tmp < params[iparam].c3)
+ return -F_F(0.5)*params[iparam].beta * pow(tmp,params[iparam].powern-F_F(1.0));
+
+ F_FLOAT tmp_n = pow(tmp,params[iparam].powern);
+ return -F_F(0.5) * pow(F_F(1.0)+tmp_n, -F_F(1.0)-(F_F(1.0)/(F_F(2.0)*params[iparam].powern)))*tmp_n / zeta;
+}
+
+__device__ void force_zeta(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij,
+ F_FLOAT &fforce, F_FLOAT &prefactor,
+ int eflag, F_FLOAT &eng)
+{
+ F_FLOAT r,fa,fa_d,bij;
+ F_FLOAT ters_R = params[iparam].bigr;
+ F_FLOAT ters_D = params[iparam].bigd;
+ r = sqrt(rsq);
+ fa = ters_fa(r,iparam,ters_R,ters_D);
+ fa_d = ters_fa_d(r,iparam,ters_R,ters_D);
+ bij = ters_bij(zeta_ij,iparam);
+ fforce = F_F(0.5)*bij*fa_d / r;
+ prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam);
+ if (eflag) eng += bij*fa;
+}
+
+__device__ void force_zeta_prefactor_force(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij,
+ F_FLOAT &fforce, F_FLOAT &prefactor)
+{
+ F_FLOAT r,fa,fa_d,bij;
+ F_FLOAT ters_R = params[iparam].bigr;
+ F_FLOAT ters_D = params[iparam].bigd;
+ r = sqrt(rsq);
+ fa = ters_fa(r,iparam,ters_R,ters_D);
+ fa_d = ters_fa_d(r,iparam,ters_R,ters_D);
+ bij = ters_bij(zeta_ij,iparam);
+ fforce = F_F(0.5)*bij*fa_d / r;
+ prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam);
+}
+
+__device__ void force_zeta_prefactor(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij,
+ F_FLOAT &prefactor)
+{
+ F_FLOAT r,fa;
+ r = sqrt(rsq);
+ fa = ters_fa(r,iparam,params[iparam].bigr,params[iparam].bigd);
+ prefactor = -F_F(0.5)*fa*ters_bij_d(zeta_ij,iparam);
+}
+
+
+__device__ void costheta_d(F_FLOAT3& rij_hat, F_FLOAT& rij,
+ F_FLOAT3& rik_hat, F_FLOAT& rik,
+ F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk)
+{
+ // first element is derivative wrt Ri, second wrt Rj, third wrt Rk
+
+ F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat);
+
+ vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj);
+ vec3_scale(F_F(1.0)/rij,drj,drj);
+ vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk);
+ vec3_scale(F_F(1.0)/rik,drk,drk);
+ vec3_add(drj,drk,dri);
+ vec3_scale(-F_F(1.0),dri,dri);
+}
+
+__device__ void ters_zetaterm_d(F_FLOAT prefactor,
+ F_FLOAT3& rij_hat, F_FLOAT rij,
+ F_FLOAT3& rik_hat, F_FLOAT rik,
+ F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk,
+ int iparam)
+{
+ F_FLOAT ex_delr,ex_delr_d,tmp;
+ F_FLOAT3 dcosdri,dcosdrj,dcosdrk;
+
+ if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik));
+ else tmp = params[iparam].lam3 * (rij-rik);
+
+ if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30);
+ else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0);
+ else ex_delr = exp(tmp);
+
+ if (params[iparam].powermint == 3)
+ ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr;
+ else ex_delr_d = params[iparam].lam3 * ex_delr;
+
+
+ const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat);
+ costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk);
+
+ const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) -
+ (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta)));
+ const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta);
+ const F_FLOAT denominator = (params[iparam].d*params[iparam].d) +
+ (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta);
+ const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri
+ // dri = -dfc*gijk*ex_delr*rik_hat;
+ // dri += fc*gijk_d*ex_delr*dcosdri;
+ // dri += fc*gijk*ex_delr_d*(rik_hat - rij_hat);
+ const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd);
+ const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd);
+
+
+ vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri);
+ vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri);
+ vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri);
+ vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri);
+ vec3_scale(prefactor,dri,dri);
+ // compute the derivative wrt Rj
+ // drj = fc*gijk_d*ex_delr*dcosdrj;
+ // drj += fc*gijk*ex_delr_d*rij_hat;
+
+ vec3_scale(fc*gijk_d*ex_delr,dcosdrj,drj);
+ vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj);
+ vec3_scale(prefactor,drj,drj);
+
+ // compute the derivative wrt Rk
+ // drk = dfc*gijk*ex_delr*rik_hat;
+ // drk += fc*gijk_d*ex_delr*dcosdrk;
+ // drk += -fc*gijk*ex_delr_d*rik_hat;
+
+ vec3_scale(dfc*gijk*ex_delr,rik_hat,drk);
+ vec3_scaleadd(fc*gijk_d*ex_delr,dcosdrk,drk,drk);
+ vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk);
+ vec3_scale(prefactor,drk,drk);
+}
+
+__device__ void ters_zetaterm_d_fi(F_FLOAT &prefactor,
+ F_FLOAT3& rij_hat, F_FLOAT &rij,
+ F_FLOAT3& rik_hat, F_FLOAT &rik,
+ F_FLOAT3& dri, int &iparam)
+{
+ F_FLOAT ex_delr,ex_delr_d,tmp;
+
+ if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik));
+ else tmp = params[iparam].lam3 * (rij-rik);
+
+ if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30);
+ else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0);
+ else ex_delr = exp(tmp);
+
+ if (params[iparam].powermint == 3)
+ ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr;
+ else ex_delr_d = params[iparam].lam3 * ex_delr;
+
+ const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat);
+ //costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk);
+
+
+ F_FLOAT3 dcosdri;
+ vec3_scaleadd(-cos_theta,rij_hat,rik_hat,dri);
+ vec3_scale(F_F(1.0)/rij,dri,dri);
+ vec3_scaleadd(-cos_theta,rik_hat,rij_hat,dcosdri);
+ vec3_scale(F_F(1.0)/rik,dcosdri,dcosdri);
+ vec3_add(dri,dcosdri,dcosdri);
+ vec3_scale(-F_F(1.0),dcosdri,dcosdri);
+
+ const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) -
+ (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta)));
+ const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta);
+ const F_FLOAT denominator = (params[iparam].d*params[iparam].d) +
+ (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta);
+ const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri
+//
+ const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd);
+ const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd);
+
+ vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri);
+ vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri);
+ vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri);
+ vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri);
+ vec3_scale(prefactor,dri,dri);
+
+}
+
+__device__ void ters_zetaterm_d_fj(F_FLOAT &prefactor,
+ F_FLOAT3& rij_hat, F_FLOAT &rij,
+ F_FLOAT3& rik_hat, F_FLOAT &rik,
+ F_FLOAT3& drj, int &iparam)
+{
+ F_FLOAT ex_delr,ex_delr_d,tmp;
+
+ if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik));
+ else tmp = params[iparam].lam3 * (rij-rik);
+
+ if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30);
+ else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0);
+ else ex_delr = exp(tmp);
+
+ if (params[iparam].powermint == 3)
+ ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr;
+ else ex_delr_d = params[iparam].lam3 * ex_delr;
+
+ const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat);
+ vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj);
+ vec3_scale(F_F(1.0)/rij,drj,drj);
+
+ const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) -
+ (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta)));
+ const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta);
+ const F_FLOAT denominator = (params[iparam].d*params[iparam].d) +
+ (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta);
+ const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri
+
+ const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd);
+
+ vec3_scale(fc*gijk_d*ex_delr,drj,drj);
+ vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj);
+ vec3_scale(prefactor,drj,drj);
+}
+
+__device__ void ters_zetaterm_d_fk(F_FLOAT &prefactor,
+ F_FLOAT3& rij_hat, F_FLOAT &rij,
+ F_FLOAT3& rik_hat, F_FLOAT &rik,
+ F_FLOAT3& drk, int &iparam)
+{
+ F_FLOAT ex_delr,ex_delr_d,tmp;
+
+ if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik));
+ else tmp = params[iparam].lam3 * (rij-rik);
+
+ if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30);
+ else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0);
+ else ex_delr = exp(tmp);
+
+ if (params[iparam].powermint == 3)
+ ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr;
+ else ex_delr_d = params[iparam].lam3 * ex_delr;
+
+ const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat);
+ vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk);
+ vec3_scale(F_F(1.0)/rik,drk,drk);
+
+ const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) -
+ (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta)));
+ const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta);
+ const F_FLOAT denominator = (params[iparam].d*params[iparam].d) +
+ (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta);
+ const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri
+
+ const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd);
+ const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd);
+
+ vec3_scale(fc*gijk_d*ex_delr,drk,drk);
+ vec3_scaleadd(dfc*gijk*ex_delr,rik_hat,drk,drk);
+ vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk);
+ vec3_scale(prefactor,drk,drk);
+}
+
+__device__ void attractive(int iparam, F_FLOAT prefactor,
+ F_FLOAT4& delij,
+ F_FLOAT4& delik,
+ F_FLOAT3& fi, F_FLOAT3& fj, F_FLOAT3& fk)
+{
+ F_FLOAT3 rij_hat,rik_hat;
+ F_FLOAT rij,rijinv,rik,rikinv;
+
+ rij = sqrt(delij.w);
+ rijinv = F_F(1.0)/rij;
+ vec3_scale(rijinv,delij,rij_hat);
+
+ rik = sqrt(delik.w);
+ rikinv = F_F(1.0)/rik;
+ vec3_scale(rikinv,delik,rik_hat);
+
+ ters_zetaterm_d(prefactor,rij_hat,rij,rik_hat,rik,fi,fj,fk,iparam);
+}
+
+__device__ void attractive_fi(int& iparam, F_FLOAT& prefactor,
+ F_FLOAT4& delij,
+ F_FLOAT4& delik,
+ F_FLOAT3& f)
+{
+ F_FLOAT3 rij_hat,rik_hat;
+ F_FLOAT rij,rijinv,rik,rikinv;
+
+ rij = sqrt(delij.w);
+ rijinv = F_F(1.0)/rij;
+ vec3_scale(rijinv,delij,rij_hat);
+
+ rik = sqrt(delik.w);
+ rikinv = F_F(1.0)/rik;
+ vec3_scale(rikinv,delik,rik_hat);
+
+ ters_zetaterm_d_fi(prefactor,rij_hat,rij,rik_hat,rik,f,iparam);
+}
+
+__device__ void attractive_fj(int iparam, F_FLOAT prefactor,
+ F_FLOAT4& delij,
+ F_FLOAT4& delik,
+ F_FLOAT3& f)
+{
+ F_FLOAT3 rij_hat,rik_hat;
+ F_FLOAT rij,rijinv,rik,rikinv;
+
+ rij = sqrt(delij.w);
+ rijinv = F_F(1.0)/rij;
+ vec3_scale(rijinv,delij,rij_hat);
+
+ rik = sqrt(delik.w);
+ rikinv = F_F(1.0)/rik;
+ vec3_scale(rikinv,delik,rik_hat);
+
+ ters_zetaterm_d_fj(prefactor,rij_hat,rij,rik_hat,rik,f,iparam);
+}
+
+__device__ void attractive_fk(int iparam, F_FLOAT prefactor,
+ F_FLOAT4& delij,
+ F_FLOAT4& delik,
+ F_FLOAT3& f)
+{
+ F_FLOAT3 rij_hat,rik_hat;
+ F_FLOAT rij,rijinv,rik,rikinv;
+
+ rij = sqrt(delij.w);
+ rijinv = F_F(1.0)/rij;
+ vec3_scale(rijinv,delij,rij_hat);
+
+ rik = sqrt(delik.w);
+ rikinv = F_F(1.0)/rik;
+ vec3_scale(rikinv,delik,rik_hat);
+
+ ters_zetaterm_d_fk(prefactor,rij_hat,rij,rik_hat,rik,f,iparam);
+}
+
+__global__ void Pair_Tersoff_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red)
+{
+ int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+ if( ii >= _nall ) return;
+
+ X_FLOAT4 myxtype;
+ F_FLOAT4 delij;
+ F_FLOAT xtmp,ytmp,ztmp;
+ int itype,jnum,i,j;
+ int* jlist;
+ int neigh_red = 0;
+ i = ii;//_ilist[ii];
+ myxtype = fetchXType(i);
+
+ xtmp=myxtype.x;
+ ytmp=myxtype.y;
+ ztmp=myxtype.z;
+ itype=map[(static_cast (myxtype.w))];
+
+ jnum = _numneigh[i];
+ jlist = &_neighbors[i];
+
+ __syncthreads();
+ for (int jj = 0; jj < jnum; jj++)
+ {
+ if(jj (myxtype.w))];
+ int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype];
+ delij.w = vec3_dot(delij,delij);
+ if (delij.w < params[iparam_ij].cutsq)
+ {
+ _glob_neighbors_red[i+neigh_red*_nall]=j;
+ _glob_neightype_red[i+neigh_red*_nall]=jtype;
+ _glob_r_ij[i+neigh_red*_nall]=delij;
+ neigh_red++;
+ }
+ }
+ }
+ _glob_numneigh_red[i]=neigh_red;
+}
+
+
+ __global__ void Pair_Tersoff_Kernel_TpA_ZetaIJ()//F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red)
+ {
+
+ int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+ if( ii >= _nall ) return;
+
+
+ F_FLOAT4 delij;
+ F_FLOAT4 delik;
+
+ int itype,jnum,i,j;
+ int* jlist;
+ i = ii;
+ itype=map[(static_cast (_type[i]))];
+
+ jnum = _glob_numneigh_red[i];
+ jlist = &_glob_neighbors_red[i];
+
+ __syncthreads();
+ for (int jj = 0; jj < jnum; jj++)
+ {
+ if(jj
+ __global__ void Pair_Tersoff_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red)
+{
+ ENERGY_FLOAT evdwl = ENERGY_F(0.0);
+
+ ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x];
+ ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x];
+
+ F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem;
+ if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x];
+ else
+ if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x];
+ else
+ if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x];
+ shared_F_F+=threadIdx.x;
+
+ if(eflag_atom||eflag)
+ {
+ sharedE[0] = ENERGY_F(0.0);
+ sharedV += blockDim.x;
+ }
+
+ if(vflagm||vflag_atom)
+ {
+ sharedV[0*blockDim.x] = ENERGY_F(0.0);
+ sharedV[1*blockDim.x] = ENERGY_F(0.0);
+ sharedV[2*blockDim.x] = ENERGY_F(0.0);
+ sharedV[3*blockDim.x] = ENERGY_F(0.0);
+ sharedV[4*blockDim.x] = ENERGY_F(0.0);
+ sharedV[5*blockDim.x] = ENERGY_F(0.0);
+ }
+
+ int jnum_red=0;
+#define fxtmp shared_F_F[0]
+#define fytmp shared_F_F[blockDim.x]
+#define fztmp shared_F_F[2*blockDim.x]
+//#define jnum_red (static_cast (shared_F_F[3*blockDim.x]))
+
+ int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x;
+
+ X_FLOAT4 myxtype_i,myxtype_j,myxtype_k;
+ F_FLOAT4 delij,delik,deljk;
+ F_FLOAT fpair;
+ F_FLOAT prefactor_ij,prefactor_ji;
+
+ int itype,i,j;
+ int* jlist_red;
+
+ if(ii < _inum)
+ {
+ i = _ilist[ii];
+
+ if(vflagm)
+ myxtype_i=fetchXType(i);
+ //itype=map[(static_cast (myxtype_i.w))];
+ itype=map[_type[i]];
+
+
+ fxtmp = F_F(0.0);
+ fytmp = F_F(0.0);
+ fztmp = F_F(0.0);
+
+
+ //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i];
+ jnum_red = _glob_numneigh_red[i];
+ jlist_red = &_glob_neighbors_red[i];
+ }
+ __syncthreads();
+
+#pragma unroll 1
+ for (int jj = 0; jj < jnum_red; jj++)
+ {
+ if(i < _nlocal)
+ {
+ fpair=F_F(0.0);
+ j = jlist_red[jj*_nall];
+ j &= NEIGHMASK;
+
+ if(vflagm)
+ myxtype_j = fetchXType(j);
+
+ int jtype = _glob_neightype_red[i+jj*_nall];
+ delij = _glob_r_ij[i+jj*_nall];
+
+ volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype];
+ volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype];
+
+ if (delij.w();
+#undef fxtmp
+#undef fytmp
+#undef fztmp
+//#undef jnum_red
+}
From 10a6791ea2bf43dac404132f33e655ea2f1f6b74 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:33:50 +0000
Subject: [PATCH 27/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7142
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
lib/cuda/cuda_common.h | 344 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 344 insertions(+)
create mode 100644 lib/cuda/cuda_common.h
diff --git a/lib/cuda/cuda_common.h b/lib/cuda/cuda_common.h
new file mode 100644
index 0000000000..d4687ebd06
--- /dev/null
+++ b/lib/cuda/cuda_common.h
@@ -0,0 +1,344 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#ifndef _CUDA_COMMON_H_
+#define _CUDA_COMMON_H_
+
+//#include "cutil.h"
+#include "cuda_precision.h"
+#include "cuda_wrapper_cu.h"
+
+#define CUDA_MAX_TYPES_PLUS_ONE 12 //for pair styles which use constant space for parameters, this needs to be one larger than the number of atom types
+//this can not be arbitrarly large, since constant space is limited.
+//in principle one could alter potentials to use global memory for parameters, some du that already since the first examples I encountered had a high number (20+) of atom types
+//Christian
+#define CUDA_MAX_TYPES2 (CUDA_MAX_TYPES_PLUS_ONE * CUDA_MAX_TYPES_PLUS_ONE)
+#define CUDA_MAX_NSPECIAL 25
+
+// define some easy-to-use debug and emulation macros
+#ifdef _DEBUG
+#define MYDBG(a) a
+#else
+#define MYDBG(a)
+#endif
+
+#if __DEVICE_EMULATION__
+#define MYEMU(a) a
+#else
+#define MYEMU(a)
+#endif
+
+#define MYEMUDBG(a) MYEMU(MYDBG(a))
+
+// Add Prefix (needed as workaround, same constant's names in different files causes conflict)
+#define MY_ADD_PREFIX(prefix, var) prefix##_##var
+#define MY_ADD_PREFIX2(prefix, var) MY_ADD_PREFIX(prefix, var)
+#define MY_AP(var) MY_ADD_PREFIX2(MY_PREFIX, var)
+
+#define MY_VAR_TO_STR(var) #var
+#define MY_VAR_TO_STR2(var) MY_VAR_TO_STR(var)
+#define MY_CONST(var) (MY_VAR_TO_STR2(MY_PREFIX) "_" MY_VAR_TO_STR2(var))
+
+#define CUDA_USE_TEXTURE
+#define CUDA_USE_FLOAT4
+
+//constants used by many classes
+
+//domain
+#define _boxhi MY_AP(boxhi)
+#define _boxlo MY_AP(boxlo)
+#define _subhi MY_AP(subhi)
+#define _sublo MY_AP(sublo)
+#define _box_size MY_AP(box_size)
+#define _prd MY_AP(prd)
+#define _periodicity MY_AP(periodicity)
+#define _triclinic MY_AP(triclinic)
+#define _boxhi_lamda MY_AP(boxhi_lamda)
+#define _boxlo_lamda MY_AP(boxlo_lamda)
+#define _prd_lamda MY_AP(prd_lamda)
+#define _h MY_AP(h)
+#define _h_inv MY_AP(h_inv)
+#define _h_rate MY_AP(h_rate)
+__device__ __constant__ X_FLOAT _boxhi[3];
+__device__ __constant__ X_FLOAT _boxlo[3];
+__device__ __constant__ X_FLOAT _subhi[3];
+__device__ __constant__ X_FLOAT _sublo[3];
+__device__ __constant__ X_FLOAT _box_size[3];
+__device__ __constant__ X_FLOAT _prd[3];
+__device__ __constant__ int _periodicity[3];
+__device__ __constant__ int _triclinic;
+__device__ __constant__ X_FLOAT _boxhi_lamda[3];
+__device__ __constant__ X_FLOAT _boxlo_lamda[3];
+__device__ __constant__ X_FLOAT _prd_lamda[3];
+__device__ __constant__ X_FLOAT _h[6];
+__device__ __constant__ X_FLOAT _h_inv[6];
+__device__ __constant__ V_FLOAT _h_rate[6];
+
+
+//atom properties
+#define _x MY_AP(x)
+#define _v MY_AP(v)
+#define _f MY_AP(f)
+#define _tag MY_AP(tag)
+#define _type MY_AP(type)
+#define _mask MY_AP(mask)
+#define _image MY_AP(image)
+#define _q MY_AP(q)
+#define _mass MY_AP(mass)
+#define _rmass MY_AP(rmass)
+#define _rmass_flag MY_AP(rmass_flag)
+#define _eatom MY_AP(eatom)
+#define _vatom MY_AP(vatom)
+#define _x_type MY_AP(x_type)
+#define _radius MY_AP(radius)
+#define _density MY_AP(density)
+#define _omega MY_AP(omega)
+#define _torque MY_AP(torque)
+#define _special MY_AP(special)
+#define _maxspecial MY_AP(maxspecial)
+#define _nspecial MY_AP(nspecial)
+#define _special_flag MY_AP(special_flag)
+#define _molecule MY_AP(molecule)
+#define _v_radius MY_AP(v_radius)
+#define _omega_rmass MY_AP(omega_rmass)
+#define _freeze_group_bit MY_AP(freeze_group_bit)
+#define _map_array MY_AP(map_array)
+__device__ __constant__ X_FLOAT* _x; //holds pointer to positions
+__device__ __constant__ V_FLOAT* _v;
+__device__ __constant__ F_FLOAT* _f;
+__device__ __constant__ int* _tag;
+__device__ __constant__ int* _type;
+__device__ __constant__ int* _mask;
+__device__ __constant__ int* _image;
+__device__ __constant__ V_FLOAT* _mass;
+__device__ __constant__ F_FLOAT* _q;
+__device__ __constant__ V_FLOAT* _rmass;
+__device__ __constant__ int _rmass_flag;
+__device__ __constant__ ENERGY_FLOAT* _eatom;
+__device__ __constant__ ENERGY_FLOAT* _vatom;
+__device__ __constant__ X_FLOAT4* _x_type; //holds pointer to positions
+__device__ __constant__ X_FLOAT* _radius;
+__device__ __constant__ F_FLOAT* _density;
+__device__ __constant__ V_FLOAT* _omega;
+__device__ __constant__ F_FLOAT* _torque;
+__device__ __constant__ int* _special;
+__device__ __constant__ int _maxspecial;
+__device__ __constant__ int* _nspecial;
+__device__ __constant__ int _special_flag[4];
+__device__ __constant__ int* _molecule;
+__device__ __constant__ V_FLOAT4* _v_radius; //holds pointer to positions
+__device__ __constant__ V_FLOAT4* _omega_rmass; //holds pointer to positions
+__device__ __constant__ int _freeze_group_bit;
+__device__ __constant__ int* _map_array;
+
+#ifdef CUDA_USE_TEXTURE
+
+ #define _x_tex MY_AP(x_tex)
+ #if X_PRECISION == 1
+ texture _x_tex;
+ #else
+ texture _x_tex;
+ #endif
+
+ #define _type_tex MY_AP(type_tex)
+ texture _type_tex;
+
+ #define _x_type_tex MY_AP(x_type_tex)
+ #if X_PRECISION == 1
+ texture _x_type_tex;
+ #else
+ texture _x_type_tex;
+ #endif
+
+ #define _v_radius_tex MY_AP(v_radius_tex)
+ #if V_PRECISION == 1
+ texture _v_radius_tex;
+ #else
+ texture _v_radius_tex;
+ #endif
+
+ #define _omega_rmass_tex MY_AP(omega_rmass_tex)
+ #if V_PRECISION == 1
+ texture _omega_rmass_tex;
+ #else
+ texture _omega_rmass_tex;
+ #endif
+
+ #define _q_tex MY_AP(q_tex)
+ #if F_PRECISION == 1
+ texture _q_tex;
+ #else
+ texture _q_tex;
+ #endif
+
+#endif
+
+//neighbor
+#ifdef IncludeCommonNeigh
+#define _inum MY_AP(inum)
+#define _inum_border MY_AP(inum_border)
+#define _ilist MY_AP(ilist)
+#define _ilist_border MY_AP(ilist_border)
+#define _numneigh MY_AP(numneigh)
+#define _numneigh_border MY_AP(numneigh_border)
+#define _numneigh_inner MY_AP(numneigh_inner)
+#define _firstneigh MY_AP(firstneigh)
+#define _neighbors MY_AP(neighbors)
+#define _neighbors_border MY_AP(neighbors_border)
+#define _neighbors_inner MY_AP(neighbors_inner)
+#define _reneigh_flag MY_AP(reneigh_flag)
+#define _triggerneighsq MY_AP(triggerneighsq)
+#define _xhold MY_AP(xhold)
+#define _maxhold MY_AP(maxhold)
+#define _dist_check MY_AP(dist_check)
+#define _neighbor_maxlocal MY_AP(neighbor_maxlocal)
+#define _maxneighbors MY_AP(maxneighbors)
+#define _overlap_comm MY_AP(overlap_comm)
+__device__ __constant__ int _inum;
+__device__ __constant__ int* _inum_border;
+__device__ __constant__ int* _ilist;
+__device__ __constant__ int* _ilist_border;
+__device__ __constant__ int* _numneigh;
+__device__ __constant__ int* _numneigh_border;
+__device__ __constant__ int* _numneigh_inner;
+__device__ __constant__ int** _firstneigh;
+__device__ __constant__ int* _neighbors;
+__device__ __constant__ int* _neighbors_border;
+__device__ __constant__ int* _neighbors_inner;
+__device__ __constant__ int* _reneigh_flag;
+__device__ __constant__ X_FLOAT _triggerneighsq;
+__device__ __constant__ X_FLOAT* _xhold; //holds pointer to positions
+__device__ __constant__ int _maxhold;
+__device__ __constant__ int _dist_check;
+__device__ __constant__ int _neighbor_maxlocal;
+__device__ __constant__ int _maxneighbors;
+__device__ __constant__ int _overlap_comm;
+#endif
+
+//system properties
+#define _nall MY_AP(nall)
+#define _nghost MY_AP(nghost)
+#define _nlocal MY_AP(nlocal)
+#define _nmax MY_AP(nmax)
+#define _cuda_ntypes MY_AP(cuda_ntypes)
+#define _dtf MY_AP(dtf)
+#define _dtv MY_AP(dtv)
+#define _factor MY_AP(factor)
+#define _virial MY_AP(virial)
+#define _eng_vdwl MY_AP(eng_vdwl)
+#define _eng_coul MY_AP(eng_coul)
+#define _molecular MY_AP(molecular)
+__device__ __constant__ unsigned _nall;
+__device__ __constant__ unsigned _nghost;
+__device__ __constant__ unsigned _nlocal;
+__device__ __constant__ unsigned _nmax;
+__device__ __constant__ unsigned _cuda_ntypes;
+__device__ __constant__ V_FLOAT _dtf;
+__device__ __constant__ X_FLOAT _dtv;
+__device__ __constant__ V_FLOAT _factor;
+__device__ __constant__ ENERGY_FLOAT* _virial;
+__device__ __constant__ ENERGY_FLOAT* _eng_vdwl;
+__device__ __constant__ ENERGY_FLOAT* _eng_coul;
+__device__ __constant__ int _molecular;
+
+//other general constants
+#define _buffer MY_AP(buffer)
+#define _flag MY_AP(flag)
+#define _debugdata MY_AP(debugdata)
+__device__ __constant__ void* _buffer;
+__device__ __constant__ int* _flag;
+__device__ __constant__ int* _debugdata;
+
+// pointers to data fields on GPU are hold in constant space
+// -> reduces register usage and number of parameters for kernelcalls
+// will be variables of file scope in cuda files
+
+
+
+
+// maybe used to output cudaError_t
+#define MY_OUTPUT_RESULT(result) \
+ switch(result) \
+ { \
+ case cudaSuccess: printf(" => cudaSuccess\n"); break; \
+ case cudaErrorInvalidValue: printf(" => cudaErrorInvalidValue\n"); break; \
+ case cudaErrorInvalidSymbol: printf(" => cudaErrorInvalidSymbol\n"); break; \
+ case cudaErrorInvalidDevicePointer: printf(" => cudaErrorInvalidDevicePointer\n"); break; \
+ case cudaErrorInvalidMemcpyDirection: printf(" => cudaErrorInvalidMemcpyDirection\n"); break; \
+ default: printf(" => unknown\n"); break; \
+ }
+
+#ifdef _DEBUG
+# define CUT_CHECK_ERROR(errorMessage) { \
+ cudaError_t err = cudaGetLastError(); \
+ if( cudaSuccess != err) { \
+ fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
+ errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
+ exit(EXIT_FAILURE); \
+ } \
+ err = cudaThreadSynchronize(); \
+ if( cudaSuccess != err) { \
+ fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
+ errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
+ exit(EXIT_FAILURE); \
+ } \
+ }
+#else
+# define CUT_CHECK_ERROR(errorMessage) { \
+ cudaError_t err = cudaGetLastError(); \
+ if( cudaSuccess != err) { \
+ fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
+ errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
+ exit(EXIT_FAILURE); \
+ } \
+ }
+#endif
+
+# define CUDA_SAFE_CALL_NO_SYNC( call) { \
+ cudaError err = call; \
+ if( cudaSuccess != err) { \
+ fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \
+ __FILE__, __LINE__, cudaGetErrorString( err) ); \
+ exit(EXIT_FAILURE); \
+ } }
+
+# define CUDA_SAFE_CALL( call) CUDA_SAFE_CALL_NO_SYNC(call);
+
+#define X_MASK 1
+#define V_MASK 2
+#define F_MASK 4
+#define TAG_MASK 8
+#define TYPE_MASK 16
+#define MASK_MASK 32
+#define IMAGE_MASK 64
+#define Q_MASK 128
+#define MOLECULE_MASK 256
+#define RMASS_MASK 512
+#define RADIUS_MASK 1024
+#define DENSITY_MASK 2048
+#define OMEGA_MASK 4096
+#define TORQUE_MASK 8192
+
+
+
+#endif // #ifdef _CUDA_COMMON_H_
From a053fd4788013f62f7e55245832218dad0a9ebc9 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:35:39 +0000
Subject: [PATCH 28/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7143
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-CUDA/Install.sh | 20 +-
src/USER-CUDA/comm_cuda.cpp | 4 +
src/USER-CUDA/cuda.cpp | 3 +
src/USER-CUDA/cuda_common.h | 344 -----------------------------
src/USER-CUDA/cuda_precision.h | 269 -----------------------
src/USER-CUDA/cuda_shared.h | 378 --------------------------------
src/USER-CUDA/neighbor_cuda.cpp | 7 +-
src/USER-CUDA/verlet_cuda.cpp | 7 +-
8 files changed, 29 insertions(+), 1003 deletions(-)
delete mode 100644 src/USER-CUDA/cuda_common.h
delete mode 100644 src/USER-CUDA/cuda_precision.h
delete mode 100644 src/USER-CUDA/cuda_shared.h
diff --git a/src/USER-CUDA/Install.sh b/src/USER-CUDA/Install.sh
index 3dc143471f..56f0dc80b9 100755
--- a/src/USER-CUDA/Install.sh
+++ b/src/USER-CUDA/Install.sh
@@ -82,6 +82,12 @@ if (test $1 = 1) then
cp pair_eam_alloy_cuda.h ..
cp pair_eam_cuda.h ..
cp pair_eam_fs_cuda.h ..
+ cp pair_sw_cuda.h ..
+ cp pair_sw_cuda.cpp ..
+ cp pair_tersoff_cuda.h ..
+ cp pair_tersoff_cuda.cpp ..
+ cp pair_tersoff_zbl_cuda.h ..
+ cp pair_tersoff_zbl_cuda.cpp ..
fi
if (test -e ../pair_gran_hooke.cpp) then
@@ -193,12 +199,9 @@ if (test $1 = 1) then
cp verlet_cuda.h ..
cp cuda.h ..
- cp cuda_common.h ..
cp cuda_data.h ..
cp cuda_modify_flags.h ..
cp cuda_neigh_list.h ..
- cp cuda_precision.h ..
- cp cuda_shared.h ..
elif (test $1 = 0) then
@@ -341,12 +344,15 @@ elif (test $1 = 0) then
rm -f ../pppm_cuda.h
rm -f ../verlet_cuda.h
+ rm -f ../pair_sw_cuda.h
+ rm -f ../pair_sw_cuda.cpp
+ rm -f ../pair_tersoff_cuda.h
+ rm -f ../pair_tersoff_cuda.cpp
+ rm -f ../pair_tersoff_zbl_cuda.h
+ rm -f ../pair_tersoff_zbl_cuda.cpp
+
rm -f ../cuda.h
- rm -f ../cuda_common.h
rm -f ../cuda_data.h
rm -f ../cuda_modify_flags.h
rm -f ../cuda_neigh_list.h
- rm -f ../cuda_precision.h
- rm -f ../cuda_shared.h
-
fi
diff --git a/src/USER-CUDA/comm_cuda.cpp b/src/USER-CUDA/comm_cuda.cpp
index 8e75f93ba5..ea4a4ee6a6 100644
--- a/src/USER-CUDA/comm_cuda.cpp
+++ b/src/USER-CUDA/comm_cuda.cpp
@@ -41,6 +41,9 @@ using namespace LAMMPS_NS;
#define BUFFACTOR 1.5
#define BUFMIN 1000
#define BUFEXTRA 1000
+
+
+
#define BIG 1.0e20
enum{SINGLE,MULTI};
@@ -137,6 +140,7 @@ void CommCuda::init()
void CommCuda::setup()
{
+ if(cuda->shared_data.pair.neighall) cutghostuser = MAX(2.0*neighbor->cutneighmax,cutghostuser);
Comm::setup();
//upload changed geometry to device
diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp
index 39261bd7c0..819357bc16 100644
--- a/src/USER-CUDA/cuda.cpp
+++ b/src/USER-CUDA/cuda.cpp
@@ -46,6 +46,8 @@
using namespace LAMMPS_NS;
+
+
Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp)
{
cuda_exists=true;
@@ -309,6 +311,7 @@ void Cuda::setSharedDataZero()
shared_data.pair.special_lj = 0;
shared_data.pair.special_coul = 0;
+ shared_data.pair.neighall = false;
shared_data.pppm.cudable_force = 0;
diff --git a/src/USER-CUDA/cuda_common.h b/src/USER-CUDA/cuda_common.h
deleted file mode 100644
index d4687ebd06..0000000000
--- a/src/USER-CUDA/cuda_common.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
-
- Original Version:
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- See the README file in the top-level LAMMPS directory.
-
- -----------------------------------------------------------------------
-
- USER-CUDA Package and associated modifications:
- https://sourceforge.net/projects/lammpscuda/
-
- Christian Trott, christian.trott@tu-ilmenau.de
- Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
- Theoretical Physics II, University of Technology Ilmenau, Germany
-
- See the README file in the USER-CUDA directory.
-
- This software is distributed under the GNU General Public License.
-------------------------------------------------------------------------- */
-
-#ifndef _CUDA_COMMON_H_
-#define _CUDA_COMMON_H_
-
-//#include "cutil.h"
-#include "cuda_precision.h"
-#include "cuda_wrapper_cu.h"
-
-#define CUDA_MAX_TYPES_PLUS_ONE 12 //for pair styles which use constant space for parameters, this needs to be one larger than the number of atom types
-//this can not be arbitrarly large, since constant space is limited.
-//in principle one could alter potentials to use global memory for parameters, some du that already since the first examples I encountered had a high number (20+) of atom types
-//Christian
-#define CUDA_MAX_TYPES2 (CUDA_MAX_TYPES_PLUS_ONE * CUDA_MAX_TYPES_PLUS_ONE)
-#define CUDA_MAX_NSPECIAL 25
-
-// define some easy-to-use debug and emulation macros
-#ifdef _DEBUG
-#define MYDBG(a) a
-#else
-#define MYDBG(a)
-#endif
-
-#if __DEVICE_EMULATION__
-#define MYEMU(a) a
-#else
-#define MYEMU(a)
-#endif
-
-#define MYEMUDBG(a) MYEMU(MYDBG(a))
-
-// Add Prefix (needed as workaround, same constant's names in different files causes conflict)
-#define MY_ADD_PREFIX(prefix, var) prefix##_##var
-#define MY_ADD_PREFIX2(prefix, var) MY_ADD_PREFIX(prefix, var)
-#define MY_AP(var) MY_ADD_PREFIX2(MY_PREFIX, var)
-
-#define MY_VAR_TO_STR(var) #var
-#define MY_VAR_TO_STR2(var) MY_VAR_TO_STR(var)
-#define MY_CONST(var) (MY_VAR_TO_STR2(MY_PREFIX) "_" MY_VAR_TO_STR2(var))
-
-#define CUDA_USE_TEXTURE
-#define CUDA_USE_FLOAT4
-
-//constants used by many classes
-
-//domain
-#define _boxhi MY_AP(boxhi)
-#define _boxlo MY_AP(boxlo)
-#define _subhi MY_AP(subhi)
-#define _sublo MY_AP(sublo)
-#define _box_size MY_AP(box_size)
-#define _prd MY_AP(prd)
-#define _periodicity MY_AP(periodicity)
-#define _triclinic MY_AP(triclinic)
-#define _boxhi_lamda MY_AP(boxhi_lamda)
-#define _boxlo_lamda MY_AP(boxlo_lamda)
-#define _prd_lamda MY_AP(prd_lamda)
-#define _h MY_AP(h)
-#define _h_inv MY_AP(h_inv)
-#define _h_rate MY_AP(h_rate)
-__device__ __constant__ X_FLOAT _boxhi[3];
-__device__ __constant__ X_FLOAT _boxlo[3];
-__device__ __constant__ X_FLOAT _subhi[3];
-__device__ __constant__ X_FLOAT _sublo[3];
-__device__ __constant__ X_FLOAT _box_size[3];
-__device__ __constant__ X_FLOAT _prd[3];
-__device__ __constant__ int _periodicity[3];
-__device__ __constant__ int _triclinic;
-__device__ __constant__ X_FLOAT _boxhi_lamda[3];
-__device__ __constant__ X_FLOAT _boxlo_lamda[3];
-__device__ __constant__ X_FLOAT _prd_lamda[3];
-__device__ __constant__ X_FLOAT _h[6];
-__device__ __constant__ X_FLOAT _h_inv[6];
-__device__ __constant__ V_FLOAT _h_rate[6];
-
-
-//atom properties
-#define _x MY_AP(x)
-#define _v MY_AP(v)
-#define _f MY_AP(f)
-#define _tag MY_AP(tag)
-#define _type MY_AP(type)
-#define _mask MY_AP(mask)
-#define _image MY_AP(image)
-#define _q MY_AP(q)
-#define _mass MY_AP(mass)
-#define _rmass MY_AP(rmass)
-#define _rmass_flag MY_AP(rmass_flag)
-#define _eatom MY_AP(eatom)
-#define _vatom MY_AP(vatom)
-#define _x_type MY_AP(x_type)
-#define _radius MY_AP(radius)
-#define _density MY_AP(density)
-#define _omega MY_AP(omega)
-#define _torque MY_AP(torque)
-#define _special MY_AP(special)
-#define _maxspecial MY_AP(maxspecial)
-#define _nspecial MY_AP(nspecial)
-#define _special_flag MY_AP(special_flag)
-#define _molecule MY_AP(molecule)
-#define _v_radius MY_AP(v_radius)
-#define _omega_rmass MY_AP(omega_rmass)
-#define _freeze_group_bit MY_AP(freeze_group_bit)
-#define _map_array MY_AP(map_array)
-__device__ __constant__ X_FLOAT* _x; //holds pointer to positions
-__device__ __constant__ V_FLOAT* _v;
-__device__ __constant__ F_FLOAT* _f;
-__device__ __constant__ int* _tag;
-__device__ __constant__ int* _type;
-__device__ __constant__ int* _mask;
-__device__ __constant__ int* _image;
-__device__ __constant__ V_FLOAT* _mass;
-__device__ __constant__ F_FLOAT* _q;
-__device__ __constant__ V_FLOAT* _rmass;
-__device__ __constant__ int _rmass_flag;
-__device__ __constant__ ENERGY_FLOAT* _eatom;
-__device__ __constant__ ENERGY_FLOAT* _vatom;
-__device__ __constant__ X_FLOAT4* _x_type; //holds pointer to positions
-__device__ __constant__ X_FLOAT* _radius;
-__device__ __constant__ F_FLOAT* _density;
-__device__ __constant__ V_FLOAT* _omega;
-__device__ __constant__ F_FLOAT* _torque;
-__device__ __constant__ int* _special;
-__device__ __constant__ int _maxspecial;
-__device__ __constant__ int* _nspecial;
-__device__ __constant__ int _special_flag[4];
-__device__ __constant__ int* _molecule;
-__device__ __constant__ V_FLOAT4* _v_radius; //holds pointer to positions
-__device__ __constant__ V_FLOAT4* _omega_rmass; //holds pointer to positions
-__device__ __constant__ int _freeze_group_bit;
-__device__ __constant__ int* _map_array;
-
-#ifdef CUDA_USE_TEXTURE
-
- #define _x_tex MY_AP(x_tex)
- #if X_PRECISION == 1
- texture _x_tex;
- #else
- texture _x_tex;
- #endif
-
- #define _type_tex MY_AP(type_tex)
- texture _type_tex;
-
- #define _x_type_tex MY_AP(x_type_tex)
- #if X_PRECISION == 1
- texture _x_type_tex;
- #else
- texture _x_type_tex;
- #endif
-
- #define _v_radius_tex MY_AP(v_radius_tex)
- #if V_PRECISION == 1
- texture _v_radius_tex;
- #else
- texture _v_radius_tex;
- #endif
-
- #define _omega_rmass_tex MY_AP(omega_rmass_tex)
- #if V_PRECISION == 1
- texture _omega_rmass_tex;
- #else
- texture _omega_rmass_tex;
- #endif
-
- #define _q_tex MY_AP(q_tex)
- #if F_PRECISION == 1
- texture _q_tex;
- #else
- texture _q_tex;
- #endif
-
-#endif
-
-//neighbor
-#ifdef IncludeCommonNeigh
-#define _inum MY_AP(inum)
-#define _inum_border MY_AP(inum_border)
-#define _ilist MY_AP(ilist)
-#define _ilist_border MY_AP(ilist_border)
-#define _numneigh MY_AP(numneigh)
-#define _numneigh_border MY_AP(numneigh_border)
-#define _numneigh_inner MY_AP(numneigh_inner)
-#define _firstneigh MY_AP(firstneigh)
-#define _neighbors MY_AP(neighbors)
-#define _neighbors_border MY_AP(neighbors_border)
-#define _neighbors_inner MY_AP(neighbors_inner)
-#define _reneigh_flag MY_AP(reneigh_flag)
-#define _triggerneighsq MY_AP(triggerneighsq)
-#define _xhold MY_AP(xhold)
-#define _maxhold MY_AP(maxhold)
-#define _dist_check MY_AP(dist_check)
-#define _neighbor_maxlocal MY_AP(neighbor_maxlocal)
-#define _maxneighbors MY_AP(maxneighbors)
-#define _overlap_comm MY_AP(overlap_comm)
-__device__ __constant__ int _inum;
-__device__ __constant__ int* _inum_border;
-__device__ __constant__ int* _ilist;
-__device__ __constant__ int* _ilist_border;
-__device__ __constant__ int* _numneigh;
-__device__ __constant__ int* _numneigh_border;
-__device__ __constant__ int* _numneigh_inner;
-__device__ __constant__ int** _firstneigh;
-__device__ __constant__ int* _neighbors;
-__device__ __constant__ int* _neighbors_border;
-__device__ __constant__ int* _neighbors_inner;
-__device__ __constant__ int* _reneigh_flag;
-__device__ __constant__ X_FLOAT _triggerneighsq;
-__device__ __constant__ X_FLOAT* _xhold; //holds pointer to positions
-__device__ __constant__ int _maxhold;
-__device__ __constant__ int _dist_check;
-__device__ __constant__ int _neighbor_maxlocal;
-__device__ __constant__ int _maxneighbors;
-__device__ __constant__ int _overlap_comm;
-#endif
-
-//system properties
-#define _nall MY_AP(nall)
-#define _nghost MY_AP(nghost)
-#define _nlocal MY_AP(nlocal)
-#define _nmax MY_AP(nmax)
-#define _cuda_ntypes MY_AP(cuda_ntypes)
-#define _dtf MY_AP(dtf)
-#define _dtv MY_AP(dtv)
-#define _factor MY_AP(factor)
-#define _virial MY_AP(virial)
-#define _eng_vdwl MY_AP(eng_vdwl)
-#define _eng_coul MY_AP(eng_coul)
-#define _molecular MY_AP(molecular)
-__device__ __constant__ unsigned _nall;
-__device__ __constant__ unsigned _nghost;
-__device__ __constant__ unsigned _nlocal;
-__device__ __constant__ unsigned _nmax;
-__device__ __constant__ unsigned _cuda_ntypes;
-__device__ __constant__ V_FLOAT _dtf;
-__device__ __constant__ X_FLOAT _dtv;
-__device__ __constant__ V_FLOAT _factor;
-__device__ __constant__ ENERGY_FLOAT* _virial;
-__device__ __constant__ ENERGY_FLOAT* _eng_vdwl;
-__device__ __constant__ ENERGY_FLOAT* _eng_coul;
-__device__ __constant__ int _molecular;
-
-//other general constants
-#define _buffer MY_AP(buffer)
-#define _flag MY_AP(flag)
-#define _debugdata MY_AP(debugdata)
-__device__ __constant__ void* _buffer;
-__device__ __constant__ int* _flag;
-__device__ __constant__ int* _debugdata;
-
-// pointers to data fields on GPU are hold in constant space
-// -> reduces register usage and number of parameters for kernelcalls
-// will be variables of file scope in cuda files
-
-
-
-
-// maybe used to output cudaError_t
-#define MY_OUTPUT_RESULT(result) \
- switch(result) \
- { \
- case cudaSuccess: printf(" => cudaSuccess\n"); break; \
- case cudaErrorInvalidValue: printf(" => cudaErrorInvalidValue\n"); break; \
- case cudaErrorInvalidSymbol: printf(" => cudaErrorInvalidSymbol\n"); break; \
- case cudaErrorInvalidDevicePointer: printf(" => cudaErrorInvalidDevicePointer\n"); break; \
- case cudaErrorInvalidMemcpyDirection: printf(" => cudaErrorInvalidMemcpyDirection\n"); break; \
- default: printf(" => unknown\n"); break; \
- }
-
-#ifdef _DEBUG
-# define CUT_CHECK_ERROR(errorMessage) { \
- cudaError_t err = cudaGetLastError(); \
- if( cudaSuccess != err) { \
- fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
- errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
- exit(EXIT_FAILURE); \
- } \
- err = cudaThreadSynchronize(); \
- if( cudaSuccess != err) { \
- fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
- errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
- exit(EXIT_FAILURE); \
- } \
- }
-#else
-# define CUT_CHECK_ERROR(errorMessage) { \
- cudaError_t err = cudaGetLastError(); \
- if( cudaSuccess != err) { \
- fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
- errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
- exit(EXIT_FAILURE); \
- } \
- }
-#endif
-
-# define CUDA_SAFE_CALL_NO_SYNC( call) { \
- cudaError err = call; \
- if( cudaSuccess != err) { \
- fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \
- __FILE__, __LINE__, cudaGetErrorString( err) ); \
- exit(EXIT_FAILURE); \
- } }
-
-# define CUDA_SAFE_CALL( call) CUDA_SAFE_CALL_NO_SYNC(call);
-
-#define X_MASK 1
-#define V_MASK 2
-#define F_MASK 4
-#define TAG_MASK 8
-#define TYPE_MASK 16
-#define MASK_MASK 32
-#define IMAGE_MASK 64
-#define Q_MASK 128
-#define MOLECULE_MASK 256
-#define RMASS_MASK 512
-#define RADIUS_MASK 1024
-#define DENSITY_MASK 2048
-#define OMEGA_MASK 4096
-#define TORQUE_MASK 8192
-
-
-
-#endif // #ifdef _CUDA_COMMON_H_
diff --git a/src/USER-CUDA/cuda_precision.h b/src/USER-CUDA/cuda_precision.h
deleted file mode 100644
index 5b7d6a6843..0000000000
--- a/src/USER-CUDA/cuda_precision.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
-
- Original Version:
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- See the README file in the top-level LAMMPS directory.
-
- -----------------------------------------------------------------------
-
- USER-CUDA Package and associated modifications:
- https://sourceforge.net/projects/lammpscuda/
-
- Christian Trott, christian.trott@tu-ilmenau.de
- Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
- Theoretical Physics II, University of Technology Ilmenau, Germany
-
- See the README file in the USER-CUDA directory.
-
- This software is distributed under the GNU General Public License.
-------------------------------------------------------------------------- */
-
-#ifndef CUDA_PRECISION_H_
-#define CUDA_PRECISION_H_
-/* This File gives Type definitions for mixed precision calculation in the cuda part of LAMMPS-CUDA.
- * Predefined behaviour is given by global CUDA_PRECISION (can be overwritten during compilation).
- * ***_FLOAT: type definition of given property
- * ***_F: constant extension in code (1.0 is interpreted as double while 1.0f is interpreted as float, now use: 1.0CUDA_F)
- */
-
-#ifdef CUDA_USE_BINNING
-#define CUDA_IF_BINNING(a) a
-#else
-#define CUDA_IF_BINNING(a)
-#endif
-
-//GLOBAL
-
-#ifdef CUDA_PRECISION
- #if CUDA_PRECISION == 1
- #define CUDA_FLOAT float
- #define CUDA_F(x) x##f
- #endif
- #if CUDA_PRECISION == 2
- #define CUDA_FLOAT double
- #define CUDA_F(x) x
- #endif
-#endif
-
-#ifndef CUDA_PRECISION
- #define CUDA_FLOAT double
- #define CUDA_F(x) x
- #define CUDA_PRECISION 2
-#endif
-//--------------------------------
-//-----------FFT-----------------
-//--------------------------------
-
-#ifdef FFT_PRECISION_CU
- #if FFT_PRECISION_CU == 1
- #define FFT_FLOAT float
- #define FFT_F(x) x##f
- #endif
- #if FFT_PRECISION_CU == 2
- #define FFT_FLOAT double
- #define FFT_F(x) x
- #endif
-#endif
-
-#ifndef FFT_PRECISION_CU
- #define FFT_FLOAT CUDA_FLOAT
- #define FFT_F(x) CUDA_F(x)
- #define FFT_PRECISION_CU CUDA_PRECISION
-#endif
-
-//--------------------------------
-//-----------PPPM-----------------
-//--------------------------------
-
-#ifdef PPPM_PRECISION
- #if PPPM_PRECISION == 1
- #define PPPM_FLOAT float
- #define PPPM_F(x) x##f
- #endif
- #if PPPM_PRECISION == 2
- #define PPPM_FLOAT double
- #define PPPM_F(x) x
- #endif
-#endif
-
-#ifndef PPPM_PRECISION
- #define PPPM_FLOAT CUDA_FLOAT
- #define PPPM_F(x) CUDA_F(x)
- #define PPPM_PRECISION CUDA_PRECISION
-#endif
-
-//--------------------------------
-//-----------FORCE-----------------
-//--------------------------------
-
-
-#ifdef F_PRECISION
- #if F_PRECISION == 1
- #define F_FLOAT float
- #define F_F(x) x##f
- #endif
- #if F_PRECISION == 2
- #define F_FLOAT double
- #define F_F(x) x
- #endif
-#endif
-
-#ifndef F_PRECISION
- #define F_FLOAT CUDA_FLOAT
- #define F_F(x) CUDA_F(x)
- #define F_PRECISION CUDA_PRECISION
-#endif
-
-#if F_PRECISION == 1
-#define _SQRT_ sqrtf
-#define _RSQRT_ rsqrtf
-#define _EXP_ expf
-#else
-#define _SQRT_ sqrt
-#define _RSQRT_ rsqrt
-#define _EXP_ exp
-#endif
-
-#if F_PRECISION == 2
-struct F_FLOAT2
-{
- F_FLOAT x;
- F_FLOAT y;
-};
-struct F_FLOAT3
-{
- F_FLOAT x;
- F_FLOAT y;
- F_FLOAT z;
-};
-struct F_FLOAT4
-{
- F_FLOAT x;
- F_FLOAT y;
- F_FLOAT z;
- F_FLOAT w;
-};
-#else
-#define F_FLOAT2 float2
-#define F_FLOAT3 float3
-#define F_FLOAT4 float4
-#endif
-//--------------------------------
-//-----------ENERGY-----------------
-//--------------------------------
-
-#ifndef ENERGY_PRECISION
- #define ENERGY_FLOAT CUDA_FLOAT
- #define ENERGY_F(x) CUDA_F(x)
-#endif
-
-#ifdef ENERGY_PRECISION
- #if ENERGY_PRECISION == 1
- #define ENERGY_FLOAT float
- #define ENERGY_F(x) x##f
- #endif
- #if ENERGY_PRECISION == 2
- #define ENERGY_FLOAT double
- #define ENERGY_F(x) x
- #endif
-#endif
-
-#ifndef ENERGY_PRECISION
- #define ENERGY_FLOAT CUDA_FLOAT
- #define ENERGY_F(x) CUDA_F(x)
- #define ENERGY_PRECISION CUDA_PRECISION
-#endif
-
-//--------------------------------
-//-----------POSITIONS------------
-//--------------------------------
-
-#ifdef X_PRECISION
- #if X_PRECISION == 1
- #define X_FLOAT float
- #define X_F(x) x##f
- #endif
- #if X_PRECISION == 2
- #define X_FLOAT double
- #define X_F(x) x
- #endif
-#endif
-
-#ifndef X_PRECISION
- #define X_FLOAT CUDA_FLOAT
- #define X_F(x) CUDA_F(x)
- #define X_PRECISION CUDA_PRECISION
-#endif
-
-#if X_PRECISION == 2
-struct X_FLOAT2
-{
- X_FLOAT x;
- X_FLOAT y;
-};
-struct X_FLOAT3
-{
- X_FLOAT x;
- X_FLOAT y;
- X_FLOAT z;
-};
-struct X_FLOAT4
-{
- X_FLOAT x;
- X_FLOAT y;
- X_FLOAT z;
- X_FLOAT w;
-};
-#else
-#define X_FLOAT2 float2
-#define X_FLOAT3 float3
-#define X_FLOAT4 float4
-#endif
-
-//--------------------------------
-//-----------velocities-----------
-//--------------------------------
-
-#ifdef V_PRECISION
- #if V_PRECISION == 1
- #define V_FLOAT float
- #define V_F(x) x##f
- #endif
- #if V_PRECISION == 2
- #define V_FLOAT double
- #define V_F(x) x
- #endif
-#endif
-
-#ifndef V_PRECISION
- #define V_FLOAT CUDA_FLOAT
- #define V_F(x) CUDA_F(x)
- #define V_PRECISION CUDA_PRECISION
-#endif
-
-#if V_PRECISION == 2
-struct V_FLOAT4
-{
- V_FLOAT x;
- V_FLOAT y;
- V_FLOAT z;
- V_FLOAT w;
-};
-#else
-#define V_FLOAT4 float4
-#endif
-
-#ifdef NO_PREC_TIMING
-struct timespec_2
-{
- unsigned int tv_sec;
- unsigned int tv_nsec;
-};
-
-#define timespec timespec_2
-#define clock_gettime(a,b)
-#endif
-#endif /*CUDA_PRECISION_H_*/
diff --git a/src/USER-CUDA/cuda_shared.h b/src/USER-CUDA/cuda_shared.h
deleted file mode 100644
index f7983fff05..0000000000
--- a/src/USER-CUDA/cuda_shared.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
-
- Original Version:
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- See the README file in the top-level LAMMPS directory.
-
- -----------------------------------------------------------------------
-
- USER-CUDA Package and associated modifications:
- https://sourceforge.net/projects/lammpscuda/
-
- Christian Trott, christian.trott@tu-ilmenau.de
- Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
- Theoretical Physics II, University of Technology Ilmenau, Germany
-
- See the README file in the USER-CUDA directory.
-
- This software is distributed under the GNU General Public License.
-------------------------------------------------------------------------- */
-
-#ifndef _CUDA_SHARED_H_
-#define _CUDA_SHARED_H_
-#include "cuda_precision.h"
-
-#define CUDA_MAX_DEBUG_SIZE 1000 //size of debugdata array (allows for so many doubles or twice as many int)
-
-struct dev_array
-{
- void* dev_data; // pointer to memory address on cuda device
- unsigned dim[3]; // array dimensions
-};
-
-struct cuda_shared_atom // relevent data from atom class
-{
- dev_array dx; // cumulated distance for binning settings
- dev_array x; // position
- dev_array v; // velocity
- dev_array f; // force
- dev_array tag;
- dev_array type; // global ID number, there are ghosttype = ntypes (ntypescuda=ntypes+1)
- dev_array mask;
- dev_array image;
- dev_array q; // charges
- dev_array mass; // per-type masses
- dev_array rmass; // per-atom masses
- dev_array radius; // per-atom radius
- dev_array density;
- dev_array omega;
- dev_array torque;
- dev_array molecule;
-
- dev_array special;
- int maxspecial;
- dev_array nspecial;
- int* special_flag;
- int molecular;
-
- dev_array eatom; // per-atom energy
- dev_array vatom; // per-atom virial
- int need_eatom;
- int need_vatom;
-
- dev_array x_type; // position + type in X_FLOAT4 struct
- dev_array v_radius; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style
- dev_array omega_rmass; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style
-
- double* mass_host; // remember per-type host pointer to masses
- //int natoms; // total # of atoms in system, could be 0
- int nghost; // and ghost atoms on this proc
- int nlocal; // # of owned
- int nall; // total # of atoms in this proc
- int nmax; // max # of owned+ghost in arrays on this proc
- int ntypes;
- int q_flag; // do we have charges?
- int rmass_flag; // do we have per-atom masses?
- int firstgroup;
- int nfirst;
-
- int update_nlocal;
- int update_nmax;
-
- dev_array xhold; // position at last neighboring
- X_FLOAT triggerneighsq; // maximum square movement before reneighboring
- int reneigh_flag; // is reneighboring necessary
- int maxhold; // size of xhold
- int dist_check; //perform distance check for reneighboring
- dev_array binned_id; //id of each binned atom (not tag!!)
- dev_array binned_idnew; //new id of each binned atom for sorting basically setting atom[binned_id[k]] at atom[binned_newid[k]]
- float bin_extraspace;
- int bin_dim[3];
- int bin_nmax;
- dev_array map_array;
-};
-
-struct cuda_shared_pair // relevent data from pair class
-{
- char cudable_force; // check for (cudable_force!=0)
- X_FLOAT cut_global;
- X_FLOAT cut_inner_global;
- X_FLOAT cut_coul_global;
- double** cut; // type-type cutoff
- double** cutsq; // type-type cutoff
- double** cut_inner; // type-type cutoff for coul
- double** cut_coul; // type-type cutoff for coul
- double** coeff1; // tpye-type pair parameters
- double** coeff2;
- double** coeff3;
- double** coeff4;
- double** coeff5;
- double** coeff6;
- double** coeff7;
- double** coeff8;
- double** coeff9;
- double** coeff10;
- double** offset;
- double* special_lj;
- double* special_coul;
- dev_array virial; // ENERGY_FLOAT
- dev_array eng_vdwl; // ENERGY_FLOAT
- dev_array eng_coul; // ENERGY_FLOAT
- X_FLOAT cut_coulsq_global;
- F_FLOAT g_ewald,kappa;
- int freeze_group_bit;
-
- dev_array coeff1_gm;
- dev_array coeff2_gm;
- dev_array coeff3_gm;
- dev_array coeff4_gm;
- dev_array coeff5_gm;
- dev_array coeff6_gm;
- dev_array coeff7_gm;
- dev_array coeff8_gm;
- dev_array coeff9_gm;
- dev_array coeff10_gm;
-
- int lastgridsize;
- int n_energy_virial;
- int collect_forces_later;
- int use_block_per_atom;
- int override_block_per_atom;
-
-};
-
-struct cuda_shared_domain // relevent data from domain class
-{
- X_FLOAT sublo[3]; // orthogonal box -> sub-box bounds on this proc
- X_FLOAT subhi[3];
- X_FLOAT boxlo[3];
- X_FLOAT boxhi[3];
- X_FLOAT prd[3];
- int periodicity[3]; // xyz periodicity as array
-
- int triclinic;
- X_FLOAT xy;
- X_FLOAT xz;
- X_FLOAT yz;
- X_FLOAT boxlo_lamda[3];
- X_FLOAT boxhi_lamda[3];
- X_FLOAT prd_lamda[3];
- X_FLOAT h[6];
- X_FLOAT h_inv[6];
- V_FLOAT h_rate[6];
- int update;
-};
-
-struct cuda_shared_pppm
-{
- char cudable_force;
-#ifdef FFT_CUFFT
- FFT_FLOAT* work1;
- FFT_FLOAT* work2;
- FFT_FLOAT* work3;
- PPPM_FLOAT* greensfn;
- PPPM_FLOAT* fkx;
- PPPM_FLOAT* fky;
- PPPM_FLOAT* fkz;
- PPPM_FLOAT* vg;
-#endif
- int* part2grid;
- PPPM_FLOAT* density_brick;
- int* density_brick_int;
- PPPM_FLOAT density_intScale;
- PPPM_FLOAT* vdx_brick;
- PPPM_FLOAT* vdy_brick;
- PPPM_FLOAT* vdz_brick;
- PPPM_FLOAT* density_fft;
- ENERGY_FLOAT* energy;
- ENERGY_FLOAT* virial;
- int nxlo_in;
- int nxhi_in;
- int nxlo_out;
- int nxhi_out;
- int nylo_in;
- int nyhi_in;
- int nylo_out;
- int nyhi_out;
- int nzlo_in;
- int nzhi_in;
- int nzlo_out;
- int nzhi_out;
- int nx_pppm;
- int ny_pppm;
- int nz_pppm;
- PPPM_FLOAT qqrd2e;
- int order;
- // float3 sublo;
- PPPM_FLOAT* rho_coeff;
- int nmax;
- int nlocal;
- PPPM_FLOAT* debugdata;
- PPPM_FLOAT delxinv;
- PPPM_FLOAT delyinv;
- PPPM_FLOAT delzinv;
- int nlower;
- int nupper;
- PPPM_FLOAT shiftone;
-
-};
-
-struct cuda_shared_comm
-{
- int maxswap;
- int maxlistlength;
- dev_array pbc;
- dev_array slablo;
- dev_array slabhi;
- dev_array multilo;
- dev_array multihi;
- dev_array sendlist;
- int grow_flag;
- int comm_phase;
-
- int nsend;
- int* nsend_swap;
- int* send_size;
- int* recv_size;
- double** buf_send;
- void** buf_send_dev;
- double** buf_recv;
- void** buf_recv_dev;
- void* buffer;
- int buffer_size;
- double overlap_split_ratio;
-};
-
-struct cuda_shared_neighlist // member of CudaNeighList, has no instance in cuda_shared_data
-{
- int maxlocal;
- int inum; // # of I atoms neighbors are stored for local indices of I atoms
- int inum_border2;
- dev_array inum_border; // # of atoms which interact with border atoms
- dev_array ilist;
- dev_array ilist_border;
- dev_array numneigh;
- dev_array numneigh_inner;
- dev_array numneigh_border;
- dev_array firstneigh;
- dev_array neighbors;
- dev_array neighbors_border;
- dev_array neighbors_inner;
- int maxpage;
- dev_array page_pointers;
- dev_array* pages;
- int maxneighbors;
- int neigh_lists_per_page;
- double** cutneighsq;
- CUDA_FLOAT* cu_cutneighsq;
- int* binned_id;
- int* bin_dim;
- int bin_nmax;
- float bin_extraspace;
- double maxcut;
- dev_array ex_type;
- int nex_type;
- dev_array ex1_bit;
- dev_array ex2_bit;
- int nex_group;
- dev_array ex_mol_bit;
- int nex_mol;
-
-};
-
-struct cuda_compile_settings // this is used to compare compile settings (i.e. precision) of the cu files, and the cpp files
-{
- int prec_glob;
- int prec_x;
- int prec_v;
- int prec_f;
- int prec_pppm;
- int prec_fft;
- int cufft;
- int arch;
-};
-
-struct cuda_timings_struct
-{
- //Debug:
- double test1;
- double test2;
- //transfers
- double transfer_upload_tmp_constr;
- double transfer_download_tmp_deconstr;
-
- //communication
- double comm_forward_total;
- double comm_forward_mpi_upper;
- double comm_forward_mpi_lower;
- double comm_forward_kernel_pack;
- double comm_forward_kernel_unpack;
- double comm_forward_kernel_self;
- double comm_forward_upload;
- double comm_forward_download;
-
- double comm_exchange_total;
- double comm_exchange_mpi;
- double comm_exchange_kernel_pack;
- double comm_exchange_kernel_unpack;
- double comm_exchange_kernel_fill;
- double comm_exchange_cpu_pack;
- double comm_exchange_upload;
- double comm_exchange_download;
-
- double comm_border_total;
- double comm_border_mpi;
- double comm_border_kernel_pack;
- double comm_border_kernel_unpack;
- double comm_border_kernel_self;
- double comm_border_kernel_buildlist;
- double comm_border_upload;
- double comm_border_download;
-
- //pair forces
- double pair_xtype_conversion;
- double pair_kernel;
- double pair_virial;
- double pair_force_collection;
-
- //neighbor
- double neigh_bin;
- double neigh_build;
- double neigh_special;
-
- //PPPM
- double pppm_particle_map;
- double pppm_make_rho;
- double pppm_brick2fft;
- double pppm_poisson;
- double pppm_fillbrick;
- double pppm_fieldforce;
- double pppm_compute;
-
-};
-
-struct cuda_shared_data // holds space for all relevent data from the different classes
-{
- void* buffer; //holds temporary GPU data [data used in subroutines, which has not to be consistend outside of that routine]
- int buffersize; //maxsize of buffer
- int buffer_new; //should be 1 if the pointer to buffer has changed
- void* flag;
- void* debugdata; //array for easily collecting debugdata from device class cuda contains the corresponding cu_debugdata and host array
- cuda_shared_atom atom;
- cuda_shared_pair pair;
- cuda_shared_domain domain;
- cuda_shared_pppm pppm;
- cuda_shared_comm comm;
- cuda_compile_settings compile_settings;
- cuda_timings_struct cuda_timings;
- int exchange_dim;
- int me; //mpi rank
- unsigned int datamask;
- int overlap_comm;
-};
-
-
-#endif // #ifndef _CUDA_SHARED_H_
diff --git a/src/USER-CUDA/neighbor_cuda.cpp b/src/USER-CUDA/neighbor_cuda.cpp
index 99bf2dce3c..dc5af9f2f8 100644
--- a/src/USER-CUDA/neighbor_cuda.cpp
+++ b/src/USER-CUDA/neighbor_cuda.cpp
@@ -26,6 +26,9 @@
using namespace LAMMPS_NS;
+
+
+
enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp
/* ---------------------------------------------------------------------- */
@@ -56,9 +59,9 @@ void NeighborCuda::choose_build(int index, NeighRequest *rq)
{
Neighbor::choose_build(index,rq);
- if (rq->full && style == NSQ && rq->ghost == 0 && rq->cudable)
+ if (rq->full && style == NSQ && rq->cudable)
pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_nsq_cuda;
- else if (rq->full && style == BIN && rq->ghost == 0 && rq->cudable)
+ else if (rq->full && style == BIN && rq->cudable)
pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_bin_cuda;
}
diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp
index 0c3f675fae..fbaa1800a5 100644
--- a/src/USER-CUDA/verlet_cuda.cpp
+++ b/src/USER-CUDA/verlet_cuda.cpp
@@ -21,6 +21,7 @@
This software is distributed under the GNU General Public License.
------------------------------------------------------------------------- */
+
#include
#include
#include
@@ -56,6 +57,7 @@ using namespace LAMMPS_NS;
#define MAKETIMEING
+
VerletCuda::VerletCuda(LAMMPS *lmp, int narg, char **arg) : Verlet(lmp, narg, arg) {
cuda = lmp->cuda;
if(cuda == NULL)
@@ -132,20 +134,19 @@ void VerletCuda::setup()
cuda->uploadAll();
neighbor->build();
neighbor->ncalls = 0;
- cuda->uploadAllNeighborLists();
+
if(atom->mass)
cuda->cu_mass->upload();
if(cuda->cu_map_array)
cuda->cu_map_array->upload();
-
+
// compute all forces
ev_set(update->ntimestep);
if(elist_atom) cuda->shared_data.atom.need_eatom = 1;
if(vlist_atom) cuda->shared_data.atom.need_vatom = 1;
if(elist_atom||vlist_atom) cuda->checkResize();
-
int test_BpA_vs_TpA = true;
timespec starttime;
From 6cebfc12b5c904dc7f03659a3a1fdb52a145cd41 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:36:25 +0000
Subject: [PATCH 29/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7144
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/USER-CUDA/pair_sw_cuda.cpp | 209 ++++++++++++++++++++++
src/USER-CUDA/pair_sw_cuda.h | 66 +++++++
src/USER-CUDA/pair_tersoff_cuda.cpp | 206 ++++++++++++++++++++++
src/USER-CUDA/pair_tersoff_cuda.h | 66 +++++++
src/USER-CUDA/pair_tersoff_zbl_cuda.cpp | 220 ++++++++++++++++++++++++
src/USER-CUDA/pair_tersoff_zbl_cuda.h | 53 ++++++
6 files changed, 820 insertions(+)
create mode 100644 src/USER-CUDA/pair_sw_cuda.cpp
create mode 100644 src/USER-CUDA/pair_sw_cuda.h
create mode 100644 src/USER-CUDA/pair_tersoff_cuda.cpp
create mode 100644 src/USER-CUDA/pair_tersoff_cuda.h
create mode 100644 src/USER-CUDA/pair_tersoff_zbl_cuda.cpp
create mode 100644 src/USER-CUDA/pair_tersoff_zbl_cuda.h
diff --git a/src/USER-CUDA/pair_sw_cuda.cpp b/src/USER-CUDA/pair_sw_cuda.cpp
new file mode 100644
index 0000000000..601ad7f2cf
--- /dev/null
+++ b/src/USER-CUDA/pair_sw_cuda.cpp
@@ -0,0 +1,209 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Paul Crozier (SNL)
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+#include
+#include "pair_sw_cuda.h"
+#include "cuda_data.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "cuda_neigh_list.h"
+#include "update.h"
+#include "integrate.h"
+#include "respa.h"
+#include "memory.h"
+#include "error.h"
+#include "cuda.h"
+
+using namespace LAMMPS_NS;
+
+
+
+
+/* ---------------------------------------------------------------------- */
+
+PairSWCuda::PairSWCuda(LAMMPS *lmp) : PairSW(lmp)
+{
+ cuda = lmp->cuda;
+ if(cuda == NULL)
+ error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS..");
+
+ allocated2 = false;
+ params_f = NULL;
+ cuda->setSystemParams();
+ cuda->shared_data.pair.cudable_force = 1;
+ cuda->shared_data.pair.override_block_per_atom = 0;
+ cuda->shared_data.pair.neighall = true;
+ init = false;
+}
+
+/* ----------------------------------------------------------------------
+ remember pointer to arrays in cuda shared data
+------------------------------------------------------------------------- */
+
+void PairSWCuda::allocate()
+{
+ if(! allocated) PairSW::allocate();
+ if(! allocated2)
+ {
+ allocated2 = true;
+ cuda->shared_data.pair.cutsq = cutsq;
+ cuda->shared_data.pair.special_lj = force->special_lj;
+ cuda->shared_data.pair.special_coul = force->special_coul;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairSWCuda::compute(int eflag, int vflag)
+{
+ if(!init) {Cuda_PairSWCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements); init=true;}
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ if(eflag) cuda->cu_eng_vdwl->upload();
+ if(vflag) cuda->cu_virial->upload();
+
+ Cuda_PairSWCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map
+ if(not cuda->shared_data.pair.collect_forces_later)
+ {
+ if(eflag) cuda->cu_eng_vdwl->download();
+ if(vflag) cuda->cu_virial->download();
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairSWCuda::settings(int narg, char **arg)
+{
+ PairSW::settings(narg, arg);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairSWCuda::coeff(int narg, char **arg)
+{
+ PairSW::coeff(narg, arg);
+ allocate();
+ params_f = (ParamSW_Float *) memory->srealloc(params_f,maxparam*sizeof(ParamSW_Float),
+ "pair:params_f");
+ for(int i=0;ishared_data.pair.cut_global = cutmax;
+}
+
+void PairSWCuda::init_style()
+{
+ MYDBG(printf("# CUDA PairSWCuda::init_style start\n"); )
+
+ int irequest;
+
+ irequest = neighbor->request(this);
+ neighbor->requests[irequest]->full = 1;
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->cudable = 1;
+ neighbor->requests[irequest]->ghost = 1;
+
+
+ MYDBG(printf("# CUDA PairSWCuda::init_style end\n"); )
+}
+
+void PairSWCuda::init_list(int id, NeighList *ptr)
+{
+ MYDBG(printf("# CUDA PairSWCuda::init_list\n");)
+ PairSW::init_list(id, ptr);
+ // right now we can only handle verlet (id 0), not respa
+ if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr);
+ // see Neighbor::init() for details on lammps lists' logic
+ MYDBG(printf("# CUDA PairSWCuda::init_list end\n");)
+ cu_params_f = (ParamSW_Float*) CudaWrapper_AllocCudaData(sizeof(ParamSW_Float)*maxparam);
+ CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(ParamSW_Float)*maxparam);
+ cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements);
+ cu_elem2param->upload();
+ cu_map = new cCudaData ( map,atom->ntypes+1 );
+ cu_map->upload();
+}
+
+void PairSWCuda::ev_setup(int eflag, int vflag)
+{
+ int maxeatomold=maxeatom;
+ PairSW::ev_setup(eflag,vflag);
+
+ if (eflag_atom && atom->nmax > maxeatomold)
+ {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );}
+
+ if (vflag_atom && atom->nmax > maxeatomold)
+ {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );}
+}
+
+
diff --git a/src/USER-CUDA/pair_sw_cuda.h b/src/USER-CUDA/pair_sw_cuda.h
new file mode 100644
index 0000000000..be9ba9bb3d
--- /dev/null
+++ b/src/USER-CUDA/pair_sw_cuda.h
@@ -0,0 +1,66 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(sw/cuda,PairSWCuda)
+
+#else
+
+#ifndef PAIR_SW_CUDA_H
+#define PAIR_SW_CUDA_H
+
+#include "pair_sw_cuda_cu.h"
+#include "pair_sw.h"
+#include "cuda_data.h"
+
+namespace LAMMPS_NS {
+
+class PairSWCuda : public PairSW
+{
+ public:
+ PairSWCuda(class LAMMPS *);
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ void init_list(int, class NeighList *);
+ void init_style();
+ void ev_setup(int eflag, int vflag);
+ protected:
+
+ class Cuda *cuda;
+ void allocate();
+ bool allocated2;
+ class CudaNeighList* cuda_neigh_list;
+ ParamSW_Float* params_f;
+ ParamSW_Float* cu_params_f;
+ cCudaData* cu_elem2param;
+ cCudaData* cu_map;
+ bool init;
+ bool iszbl;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-CUDA/pair_tersoff_cuda.cpp b/src/USER-CUDA/pair_tersoff_cuda.cpp
new file mode 100644
index 0000000000..4f1dba4e31
--- /dev/null
+++ b/src/USER-CUDA/pair_tersoff_cuda.cpp
@@ -0,0 +1,206 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Paul Crozier (SNL)
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+#include
+#include "pair_tersoff_cuda.h"
+#include "cuda_data.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "cuda_neigh_list.h"
+#include "update.h"
+#include "integrate.h"
+#include "respa.h"
+#include "memory.h"
+#include "error.h"
+#include "cuda.h"
+
+using namespace LAMMPS_NS;
+
+
+
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffCuda::PairTersoffCuda(LAMMPS *lmp) : PairTersoff(lmp)
+{
+ cuda = lmp->cuda;
+ if(cuda == NULL)
+ error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS..");
+
+ allocated2 = false;
+ params_f = NULL;
+ cuda->setSystemParams();
+ cuda->shared_data.pair.cudable_force = 1;
+ cuda->shared_data.pair.override_block_per_atom = 0;
+ cuda->shared_data.pair.neighall = true;
+ init = false;
+ iszbl = false;
+}
+
+/* ----------------------------------------------------------------------
+ remember pointer to arrays in cuda shared data
+------------------------------------------------------------------------- */
+
+void PairTersoffCuda::allocate()
+{
+ if(! allocated) PairTersoff::allocate();
+ if(! allocated2)
+ {
+ allocated2 = true;
+ cuda->shared_data.pair.cutsq = cutsq;
+ cuda->shared_data.pair.special_lj = force->special_lj;
+ cuda->shared_data.pair.special_coul = force->special_coul;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffCuda::compute(int eflag, int vflag)
+{
+ if(!init) {Cuda_PairTersoffCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements,iszbl); init=true;}
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ if(eflag) cuda->cu_eng_vdwl->upload();
+ if(vflag) cuda->cu_virial->upload();
+
+ Cuda_PairTersoffCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map
+ if(not cuda->shared_data.pair.collect_forces_later)
+ {
+ if(eflag) cuda->cu_eng_vdwl->download();
+ if(vflag) cuda->cu_virial->download();
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffCuda::settings(int narg, char **arg)
+{
+ PairTersoff::settings(narg, arg);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffCuda::coeff(int narg, char **arg)
+{
+ PairTersoff::coeff(narg, arg);
+ allocate();
+ params_f = (Param_Float *) memory->srealloc(params_f,maxparam*sizeof(Param_Float),
+ "pair:params_f");
+ for(int i=0;ishared_data.pair.cut_global = cutmax;
+}
+
+void PairTersoffCuda::init_style()
+{
+ MYDBG(printf("# CUDA PairTersoffCuda::init_style start\n"); )
+
+ int irequest;
+
+ irequest = neighbor->request(this);
+ neighbor->requests[irequest]->full = 1;
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->cudable = 1;
+ neighbor->requests[irequest]->ghost = 1;
+
+
+ MYDBG(printf("# CUDA PairTersoffCuda::init_style end\n"); )
+}
+
+void PairTersoffCuda::init_list(int id, NeighList *ptr)
+{
+ MYDBG(printf("# CUDA PairTersoffCuda::init_list\n");)
+ PairTersoff::init_list(id, ptr);
+ // right now we can only handle verlet (id 0), not respa
+ if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr);
+ // see Neighbor::init() for details on lammps lists' logic
+ MYDBG(printf("# CUDA PairTersoffCuda::init_list end\n");)
+ cu_params_f = (Param_Float*) CudaWrapper_AllocCudaData(sizeof(Param_Float)*maxparam);
+ CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(Param_Float)*maxparam);
+ cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements);
+ cu_elem2param->upload();
+ cu_map = new cCudaData ( map,atom->ntypes+1 );
+ cu_map->upload();
+}
+
+void PairTersoffCuda::ev_setup(int eflag, int vflag)
+{
+ int maxeatomold=maxeatom;
+ PairTersoff::ev_setup(eflag,vflag);
+
+ if (eflag_atom && atom->nmax > maxeatomold)
+ {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );}
+
+ if (vflag_atom && atom->nmax > maxeatomold)
+ {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );}
+}
+
+
diff --git a/src/USER-CUDA/pair_tersoff_cuda.h b/src/USER-CUDA/pair_tersoff_cuda.h
new file mode 100644
index 0000000000..34a06f91a9
--- /dev/null
+++ b/src/USER-CUDA/pair_tersoff_cuda.h
@@ -0,0 +1,66 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+
+ Original Version:
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+
+ -----------------------------------------------------------------------
+
+ USER-CUDA Package and associated modifications:
+ https://sourceforge.net/projects/lammpscuda/
+
+ Christian Trott, christian.trott@tu-ilmenau.de
+ Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
+ Theoretical Physics II, University of Technology Ilmenau, Germany
+
+ See the README file in the USER-CUDA directory.
+
+ This software is distributed under the GNU General Public License.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tersoff/cuda,PairTersoffCuda)
+
+#else
+
+#ifndef PAIR_TERSOFF_CUDA_H
+#define PAIR_TERSOFF_CUDA_H
+
+#include "pair_tersoff_cuda_cu.h"
+#include "pair_tersoff.h"
+#include "cuda_data.h"
+
+namespace LAMMPS_NS {
+
+class PairTersoffCuda : public PairTersoff
+{
+ public:
+ PairTersoffCuda(class LAMMPS *);
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ void init_list(int, class NeighList *);
+ void init_style();
+ void ev_setup(int eflag, int vflag);
+ protected:
+
+ class Cuda *cuda;
+ void allocate();
+ bool allocated2;
+ class CudaNeighList* cuda_neigh_list;
+ Param_Float* params_f;
+ Param_Float* cu_params_f;
+ cCudaData* cu_elem2param;
+ cCudaData* cu_map;
+ bool init;
+ bool iszbl;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp
new file mode 100644
index 0000000000..45236da515
--- /dev/null
+++ b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp
@@ -0,0 +1,220 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Aidan Thompson (SNL) - original Tersoff implementation
+ David Farrell (NWU) - ZBL addition
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_tersoff_zbl_cuda.h"
+#include "atom.h"
+#include "update.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "force.h"
+#include "comm.h"
+#include "memory.h"
+#include "error.h"
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define MAXLINE 1024
+#define DELTA 4
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffZBLCuda::PairTersoffZBLCuda(LAMMPS *lmp) : PairTersoffCuda(lmp)
+{
+ // hard-wired constants in metal or real units
+ // a0 = Bohr radius
+ // epsilon0 = permittivity of vacuum = q / energy-distance units
+ // e = unit charge
+ // 1 Kcal/mole = 0.043365121 eV
+
+ if (strcmp(update->unit_style,"metal") == 0) {
+ global_a_0 = 0.529;
+ global_epsilon_0 = 0.00552635;
+ global_e = 1.0;
+ } else if (strcmp(update->unit_style,"real") == 0) {
+ global_a_0 = 0.529;
+ global_epsilon_0 = 0.00552635 * 0.043365121;
+ global_e = 1.0;
+ } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units");
+ iszbl = true;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffZBLCuda::read_file(char *file)
+{
+ int params_per_line = 21;
+ char **words = new char*[params_per_line+1];
+
+ delete [] params;
+ params = NULL;
+ nparams = 0;
+
+ // open file on proc 0
+
+ FILE *fp;
+ if (comm->me == 0) {
+ fp = fopen(file,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open Tersoff potential file %s",file);
+ error->one(FLERR,str);
+ }
+ }
+
+ // read each line out of file, skipping blank lines or leading '#'
+ // store line of params if all 3 element tags are in element list
+
+ int n,nwords,ielement,jelement,kelement;
+ char line[MAXLINE],*ptr;
+ int eof = 0;
+
+ while (1) {
+ if (comm->me == 0) {
+ ptr = fgets(line,MAXLINE,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ // strip comment, skip line if blank
+
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ nwords = atom->count_words(line);
+ if (nwords == 0) continue;
+
+ // concatenate additional lines until have params_per_line words
+
+ while (nwords < params_per_line) {
+ n = strlen(line);
+ if (comm->me == 0) {
+ ptr = fgets(&line[n],MAXLINE-n,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ nwords = atom->count_words(line);
+ }
+
+ if (nwords != params_per_line)
+ error->all(FLERR,"Incorrect format in Tersoff potential file");
+
+ // words = ptrs to all words in line
+
+ nwords = 0;
+ words[nwords++] = strtok(line," \t\n\r\f");
+ while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue;
+
+ // ielement,jelement,kelement = 1st args
+ // if all 3 args are in element list, then parse this line
+ // else skip to next line
+
+ for (ielement = 0; ielement < nelements; ielement++)
+ if (strcmp(words[0],elements[ielement]) == 0) break;
+ if (ielement == nelements) continue;
+ for (jelement = 0; jelement < nelements; jelement++)
+ if (strcmp(words[1],elements[jelement]) == 0) break;
+ if (jelement == nelements) continue;
+ for (kelement = 0; kelement < nelements; kelement++)
+ if (strcmp(words[2],elements[kelement]) == 0) break;
+ if (kelement == nelements) continue;
+
+ // load up parameter settings and error check their values
+
+ if (nparams == maxparam) {
+ maxparam += DELTA;
+ params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),
+ "pair:params");
+ }
+
+ params[nparams].ielement = ielement;
+ params[nparams].jelement = jelement;
+ params[nparams].kelement = kelement;
+ params[nparams].powerm = atof(words[3]);
+ params[nparams].gamma = atof(words[4]);
+ params[nparams].lam3 = atof(words[5]);
+ params[nparams].c = atof(words[6]);
+ params[nparams].d = atof(words[7]);
+ params[nparams].h = atof(words[8]);
+ params[nparams].powern = atof(words[9]);
+ params[nparams].beta = atof(words[10]);
+ params[nparams].lam2 = atof(words[11]);
+ params[nparams].bigb = atof(words[12]);
+ params[nparams].bigr = atof(words[13]);
+ params[nparams].bigd = atof(words[14]);
+ params[nparams].lam1 = atof(words[15]);
+ params[nparams].biga = atof(words[16]);
+ params[nparams].Z_i = atof(words[17]);
+ params[nparams].Z_j = atof(words[18]);
+ params[nparams].ZBLcut = atof(words[19]);
+ params[nparams].ZBLexpscale = atof(words[20]);
+
+ // currently only allow m exponent of 1 or 3
+
+ params[nparams].powermint = int(params[nparams].powerm);
+
+ if (
+ params[nparams].lam3 < 0.0 || params[nparams].c < 0.0 ||
+ params[nparams].d < 0.0 || params[nparams].powern < 0.0 ||
+ params[nparams].beta < 0.0 || params[nparams].lam2 < 0.0 ||
+ params[nparams].bigb < 0.0 || params[nparams].bigr < 0.0 ||
+ params[nparams].bigd < 0.0 ||
+ params[nparams].bigd > params[nparams].bigr ||
+ params[nparams].lam3 < 0.0 || params[nparams].biga < 0.0 ||
+ params[nparams].powerm - params[nparams].powermint != 0.0 ||
+ (params[nparams].powermint != 3 && params[nparams].powermint != 1) ||
+ params[nparams].gamma < 0.0 ||
+ params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 ||
+ params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0)
+ error->all(FLERR,"Illegal Tersoff parameter");
+
+ nparams++;
+ }
+
+ delete [] words;
+}
+
+void PairTersoffZBLCuda::coeff(int narg, char **arg)
+{
+ PairTersoffCuda::coeff(narg, arg);
+ for(int i=0;i
Date: Thu, 20 Oct 2011 14:56:21 +0000
Subject: [PATCH 30/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7145
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/Install.sh | 8 ++
src/ASPHERE/compute_erotate_asphere.cpp | 92 ++++++++++----
src/ASPHERE/compute_erotate_asphere.h | 4 +-
src/ASPHERE/fix_nve_line.cpp | 162 ++++++++++++++++++++++++
src/ASPHERE/fix_nve_line.h | 44 +++++++
src/ASPHERE/fix_nve_tri.cpp | 156 +++++++++++++++++++++++
src/ASPHERE/fix_nve_tri.h | 44 +++++++
7 files changed, 487 insertions(+), 23 deletions(-)
create mode 100644 src/ASPHERE/fix_nve_line.cpp
create mode 100644 src/ASPHERE/fix_nve_line.h
create mode 100644 src/ASPHERE/fix_nve_tri.cpp
create mode 100644 src/ASPHERE/fix_nve_tri.h
diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh
index a494ae63d7..c896a5c285 100644
--- a/src/ASPHERE/Install.sh
+++ b/src/ASPHERE/Install.sh
@@ -8,6 +8,8 @@ if (test $1 = 1) then
cp fix_nph_asphere.cpp ..
cp fix_npt_asphere.cpp ..
cp fix_nve_asphere.cpp ..
+ cp fix_nve_line.cpp ..
+ cp fix_nve_tri.cpp ..
cp fix_nvt_asphere.cpp ..
cp pair_gayberne.cpp ..
cp pair_resquared.cpp ..
@@ -18,6 +20,8 @@ if (test $1 = 1) then
cp fix_nph_asphere.h ..
cp fix_npt_asphere.h ..
cp fix_nve_asphere.h ..
+ cp fix_nve_line.h ..
+ cp fix_nve_tri.h ..
cp fix_nvt_asphere.h ..
cp pair_gayberne.h ..
cp pair_resquared.h ..
@@ -30,6 +34,8 @@ elif (test $1 = 0) then
rm -f ../fix_nph_asphere.cpp
rm -f ../fix_npt_asphere.cpp
rm -f ../fix_nve_asphere.cpp
+ rm -f ../fix_nve_line.cpp
+ rm -f ../fix_nve_tri.cpp
rm -f ../fix_nvt_asphere.cpp
rm -f ../pair_gayberne.cpp
rm -f ../pair_resquared.cpp
@@ -40,6 +46,8 @@ elif (test $1 = 0) then
rm -f ../fix_nph_asphere.h
rm -f ../fix_npt_asphere.h
rm -f ../fix_nve_asphere.h
+ rm -f ../fix_nve_line.h
+ rm -f ../fix_nve_tri.h
rm -f ../fix_nvt_asphere.h
rm -f ../pair_gayberne.h
rm -f ../pair_resquared.h
diff --git a/src/ASPHERE/compute_erotate_asphere.cpp b/src/ASPHERE/compute_erotate_asphere.cpp
index 80c4083a9f..a18b62c1f1 100644
--- a/src/ASPHERE/compute_erotate_asphere.cpp
+++ b/src/ASPHERE/compute_erotate_asphere.cpp
@@ -16,6 +16,8 @@
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "update.h"
#include "force.h"
#include "memory.h"
@@ -36,9 +38,12 @@ ComputeERotateAsphere(LAMMPS *lmp, int narg, char **arg) :
// error check
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec)
- error->all(FLERR,"Compute erotate/asphere requires atom style ellipsoid");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_ellipsoid && !avec_line && !avec_tri)
+ error->all(FLERR,"Compute erotate/asphere requires "
+ "atom style ellipsoid or line or tri");
}
/* ---------------------------------------------------------------------- */
@@ -49,13 +54,21 @@ void ComputeERotateAsphere::init()
// no point particles allowed, spherical is OK
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
int *mask = atom->mask;
int nlocal = atom->nlocal;
+ int flag;
for (int i = 0; i < nlocal; i++)
- if (mask[i] & groupbit)
- if (ellipsoid[i] < 0)
+ if (mask[i] & groupbit) {
+ flag = 0;
+ if (ellipsoid && ellipsoid[i] >= 0) flag = 1;
+ if (line && line[i] >= 0) flag = 1;
+ if (tri && tri[i] >= 0) flag = 1;
+ if (!flag)
error->one(FLERR,"Compute erotate/asphere requires extended particles");
+ }
pfactor = 0.5 * force->mvv2e;
}
@@ -66,8 +79,16 @@ double ComputeERotateAsphere::compute_scalar()
{
invoked_scalar = update->ntimestep;
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *ebonus;
+ if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
+ double **omega = atom->omega;
double **angmom = atom->angmom;
double *rmass = atom->rmass;
int *mask = atom->mask;
@@ -76,6 +97,7 @@ double ComputeERotateAsphere::compute_scalar()
// sum rotational energy for each particle
// no point particles since divide by inertia
+ double length;
double *shape,*quat;
double wbody[3],inertia[3];
double rot[3][3];
@@ -83,28 +105,54 @@ double ComputeERotateAsphere::compute_scalar()
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
+ if (ellipsoid && ellipsoid[i] >= 0) {
+ shape = ebonus[ellipsoid[i]].shape;
+ quat = ebonus[ellipsoid[i]].quat;
- shape = bonus[ellipsoid[i]].shape;
- quat = bonus[ellipsoid[i]].quat;
+ // principal moments of inertia
+
+ inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0;
+ inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0;
+ inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0;
+
+ // wbody = angular velocity in body frame
+
+ MathExtra::quat_to_mat(quat,rot);
+ MathExtra::transpose_matvec(rot,angmom[i],wbody);
+ wbody[0] /= inertia[0];
+ wbody[1] /= inertia[1];
+ wbody[2] /= inertia[2];
+
+ erotate += inertia[0]*wbody[0]*wbody[0] +
+ inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2];
- // principal moments of inertia
+ } else if (line && line[i] >= 0) {
+ length = lbonus[line[i]].length;
- inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0;
- inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0;
- inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0;
+ erotate += (omega[i][0]*omega[i][0] + omega[i][1]*omega[i][1] +
+ omega[i][2]*omega[i][2]) * length*length*rmass[i] / 12.0;
- // wbody = angular velocity in body frame
+ } else if (tri && tri[i] >= 0) {
- MathExtra::quat_to_mat(quat,rot);
- MathExtra::transpose_matvec(rot,angmom[i],wbody);
- wbody[0] /= inertia[0];
- wbody[1] /= inertia[1];
- wbody[2] /= inertia[2];
-
- erotate += inertia[0]*wbody[0]*wbody[0] +
- inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2];
+ // principal moments of inertia
+
+ inertia[0] = tbonus[tri[i]].inertia[0];
+ inertia[1] = tbonus[tri[i]].inertia[1];
+ inertia[2] = tbonus[tri[i]].inertia[2];
+
+ // wbody = angular velocity in body frame
+
+ MathExtra::quat_to_mat(tbonus[tri[i]].quat,rot);
+ MathExtra::transpose_matvec(rot,angmom[i],wbody);
+ wbody[0] /= inertia[0];
+ wbody[1] /= inertia[1];
+ wbody[2] /= inertia[2];
+
+ erotate += inertia[0]*wbody[0]*wbody[0] +
+ inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2];
+ }
}
-
+
MPI_Allreduce(&erotate,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
scalar *= pfactor;
return scalar;
diff --git a/src/ASPHERE/compute_erotate_asphere.h b/src/ASPHERE/compute_erotate_asphere.h
index 0e3ae271d7..9274425795 100644
--- a/src/ASPHERE/compute_erotate_asphere.h
+++ b/src/ASPHERE/compute_erotate_asphere.h
@@ -32,7 +32,9 @@ class ComputeERotateAsphere : public Compute {
private:
double pfactor;
- class AtomVecEllipsoid *avec;
+ class AtomVecEllipsoid *avec_ellipsoid;
+ class AtomVecLine *avec_line;
+ class AtomVecTri *avec_tri;
};
}
diff --git a/src/ASPHERE/fix_nve_line.cpp b/src/ASPHERE/fix_nve_line.cpp
new file mode 100644
index 0000000000..682119c6a1
--- /dev/null
+++ b/src/ASPHERE/fix_nve_line.cpp
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "string.h"
+#include "fix_nve_line.h"
+#include "atom.h"
+#include "atom_vec_line.h"
+#include "domain.h"
+#include "math_const.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define INERTIA (1.0/12.0) // moment of inertia prefactor for line segment
+
+/* ---------------------------------------------------------------------- */
+
+FixNVELine::FixNVELine(LAMMPS *lmp, int narg, char **arg) :
+ FixNVE(lmp, narg, arg)
+{
+ if (narg != 3) error->all(FLERR,"Illegal fix nve/line command");
+
+ time_integrate = 1;
+
+ MINUSPI = -MY_PI;
+ TWOPI = 2.0*MY_PI;
+
+ // error checks
+
+ avec = (AtomVecLine *) atom->style_match("line");
+ if (!avec) error->all(FLERR,"Fix nve/line requires atom style line");
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixNVELine::setmask()
+{
+ int mask = 0;
+ mask |= INITIAL_INTEGRATE;
+ mask |= FINAL_INTEGRATE;
+ mask |= INITIAL_INTEGRATE_RESPA;
+ mask |= FINAL_INTEGRATE_RESPA;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVELine::init()
+{
+ int i,itype;
+
+ if (domain->dimension != 2)
+ error->all(FLERR,"Fix nve/line can only be used for 2d simulations");
+
+ // check that all particles are line segments
+ // no point particles allowed
+
+ int *line = atom->line;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (line[i] < 0) error->one(FLERR,"Fix nve/line requires line particles");
+ }
+
+ FixNVE::init();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVELine::initial_integrate(int vflag)
+{
+ double dtfm,dtirotate,delx,dely,length,theta;
+
+ AtomVecLine::Bonus *bonus = avec->bonus;
+ int *line = atom->line;
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **omega = atom->omega;
+ double **torque = atom->torque;
+ double *rmass = atom->rmass;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // set timestep here since dt may have changed or come via rRESPA
+
+ double dtfrotate = dtf / INERTIA;
+
+ // update v,x,omega,theta for all particles
+ // d_omega/dt = torque / inertia
+ // bound theta by -PI to PI
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+ x[i][0] += dtv * v[i][0];
+ x[i][1] += dtv * v[i][1];
+
+ length = bonus[line[i]].length;
+ theta = bonus[line[i]].theta;
+ dtirotate = dtfrotate / (length*length*rmass[i]);
+ omega[i][2] += dtirotate * torque[i][2];
+ theta += dtv * omega[i][2];
+ while (theta <= MINUSPI) theta += TWOPI;
+ while (theta > MY_PI) theta -= TWOPI;
+ bonus[line[i]].theta = theta;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVELine::final_integrate()
+{
+ double dtfm,dtirotate,length;
+
+ AtomVecLine::Bonus *bonus = avec->bonus;
+ int *line = atom->line;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **omega = atom->omega;
+ double **torque = atom->torque;
+ double *rmass = atom->rmass;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // set timestep here since dt may have changed or come via rRESPA
+
+ double dtfrotate = dtf / INERTIA;
+
+ // update v,omega for all particles
+ // d_omega/dt = torque / inertia
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+
+ length = bonus[line[i]].length;
+ dtirotate = dtfrotate / (length*length*rmass[i]);
+ omega[i][2] += dtirotate * torque[i][2];
+ }
+}
diff --git a/src/ASPHERE/fix_nve_line.h b/src/ASPHERE/fix_nve_line.h
new file mode 100644
index 0000000000..7d6e962044
--- /dev/null
+++ b/src/ASPHERE/fix_nve_line.h
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(nve/line,FixNVELine)
+
+#else
+
+#ifndef LMP_FIX_NVE_LINE_H
+#define LMP_FIX_NVE_LINE_H
+
+#include "fix_nve.h"
+
+namespace LAMMPS_NS {
+
+class FixNVELine : public FixNVE {
+ public:
+ FixNVELine(class LAMMPS *, int, char **);
+ ~FixNVELine() {}
+ int setmask();
+ void init();
+ void initial_integrate(int);
+ void final_integrate();
+
+ private:
+ double MINUSPI,TWOPI;
+ class AtomVecLine *avec;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/ASPHERE/fix_nve_tri.cpp b/src/ASPHERE/fix_nve_tri.cpp
new file mode 100644
index 0000000000..ca83afcdbb
--- /dev/null
+++ b/src/ASPHERE/fix_nve_tri.cpp
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "string.h"
+#include "fix_nve_tri.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "atom_vec_tri.h"
+#include "domain.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+FixNVETri::FixNVETri(LAMMPS *lmp, int narg, char **arg) :
+ FixNVE(lmp, narg, arg)
+{
+ if (narg != 3) error->all(FLERR,"Illegal fix nve/tri command");
+
+ time_integrate = 1;
+
+ // error checks
+
+ avec = (AtomVecTri *) atom->style_match("tri");
+ if (!avec) error->all(FLERR,"Fix nve/tri requires atom style tri");
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixNVETri::setmask()
+{
+ int mask = 0;
+ mask |= INITIAL_INTEGRATE;
+ mask |= FINAL_INTEGRATE;
+ mask |= INITIAL_INTEGRATE_RESPA;
+ mask |= FINAL_INTEGRATE_RESPA;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVETri::init()
+{
+ int i,itype;
+
+ if (domain->dimension != 3)
+ error->all(FLERR,"Fix nve/line can only be used for 3d simulations");
+
+ // check that all particles are triangles
+ // no point particles allowed
+
+ int *tri = atom->tri;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (tri[i] < 0) error->one(FLERR,"Fix nve/tri requires tri particles");
+ }
+
+ FixNVE::init();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVETri::initial_integrate(int vflag)
+{
+ double dtfm;
+ double omega[3];
+
+ AtomVecTri::Bonus *bonus = avec->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **angmom = atom->angmom;
+ double **torque = atom->torque;
+ double *rmass = atom->rmass;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // set timestep here since dt may have changed or come via rRESPA
+
+ dtq = 0.5 * dtv;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+ v[i][2] += dtfm * f[i][2];
+ x[i][0] += dtv * v[i][0];
+ x[i][1] += dtv * v[i][1];
+ x[i][2] += dtv * v[i][2];
+
+ // update angular momentum by 1/2 step
+
+ angmom[i][0] += dtf * torque[i][0];
+ angmom[i][1] += dtf * torque[i][1];
+ angmom[i][2] += dtf * torque[i][2];
+
+ // compute omega at 1/2 step from angmom at 1/2 step and current q
+ // update quaternion a full step via Richardson iteration
+ // returns new normalized quaternion
+
+ MathExtra::mq_to_omega(angmom[i],bonus[tri[i]].quat,
+ bonus[tri[i]].inertia,omega);
+ MathExtra::richardson(bonus[tri[i]].quat,angmom[i],omega,
+ bonus[tri[i]].inertia,dtq);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVETri::final_integrate()
+{
+ double dtfm;
+
+ double **v = atom->v;
+ double **f = atom->f;
+ double **angmom = atom->angmom;
+ double **torque = atom->torque;
+ double *rmass = atom->rmass;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ // update v,omega for all particles
+ // d_omega/dt = torque / inertia
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ dtfm = dtf / rmass[i];
+ v[i][0] += dtfm * f[i][0];
+ v[i][1] += dtfm * f[i][1];
+ v[i][2] += dtfm * f[i][2];
+
+ angmom[i][0] += dtf * torque[i][0];
+ angmom[i][1] += dtf * torque[i][1];
+ angmom[i][2] += dtf * torque[i][2];
+ }
+}
diff --git a/src/ASPHERE/fix_nve_tri.h b/src/ASPHERE/fix_nve_tri.h
new file mode 100644
index 0000000000..e268b6b1e6
--- /dev/null
+++ b/src/ASPHERE/fix_nve_tri.h
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(nve/tri,FixNVETri)
+
+#else
+
+#ifndef LMP_FIX_NVE_TRI_H
+#define LMP_FIX_NVE_TRI_H
+
+#include "fix_nve.h"
+
+namespace LAMMPS_NS {
+
+class FixNVETri : public FixNVE {
+ public:
+ FixNVETri(class LAMMPS *, int, char **);
+ ~FixNVETri() {}
+ int setmask();
+ void init();
+ void initial_integrate(int);
+ void final_integrate();
+
+ private:
+ double dtq;
+ class AtomVecTri *avec;
+};
+
+}
+
+#endif
+#endif
From ca8dfd3d7c07ac0560cfe8230e705cc068fa1716 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:56:49 +0000
Subject: [PATCH 31/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7146
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/SRD/fix_srd.cpp | 1164 +++++++++++++++++++++++----------
src/SRD/fix_srd.h | 52 +-
src/atom.cpp | 12 +-
src/atom.h | 4 +-
src/compute_property_atom.cpp | 428 +++++++++++-
src/compute_property_atom.h | 19 +-
src/fix_rigid.cpp | 325 ++++++---
src/fix_rigid.h | 11 +-
src/read_data.cpp | 99 ++-
src/read_data.h | 6 +-
src/set.cpp | 136 +++-
11 files changed, 1688 insertions(+), 568 deletions(-)
diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp
index 411beb9c9d..b673b9b7b5 100644
--- a/src/SRD/fix_srd.cpp
+++ b/src/SRD/fix_srd.cpp
@@ -22,6 +22,8 @@
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "group.h"
#include "update.h"
#include "force.h"
@@ -42,7 +44,7 @@ using namespace LAMMPS_NS;
using namespace MathConst;
enum{SLIP,NOSLIP};
-enum{SPHERE,ELLIPSOID,WALL};
+enum{SPHERE,ELLIPSOID,LINE,TRIANGLE,WALL};
enum{INSIDE_ERROR,INSIDE_WARN,INSIDE_IGNORE};
enum{BIG_MOVE,SRD_MOVE,SRD_ROTATE};
enum{CUBIC_ERROR,CUBIC_WARN};
@@ -50,10 +52,13 @@ enum{SHIFT_NO,SHIFT_YES,SHIFT_POSSIBLE};
enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp
-#define INERTIA 0.4
-#define ATOMPERBIN 10
+#define EINERTIA 0.2 // moment of inertia prefactor for ellipsoid
+
+#define ATOMPERBIN 30
#define BIG 1.0e20
#define VBINSIZE 5
+#define TOLERANCE 0.00001
+#define MAXITER 20
//#define SRD_DEBUG 1
//#define SRD_DEBUG_ATOMID 58
@@ -95,7 +100,7 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
cubictol = 0.01;
shiftuser = SHIFT_NO;
shiftseed = 0;
- streamflag = 1;
+ tstat = 0;
int iarg = 8;
while (iarg < narg) {
@@ -156,10 +161,10 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
else error->all(FLERR,"Illegal fix srd command");
shiftseed = atoi(arg[iarg+2]);
iarg += 3;
- } else if (strcmp(arg[iarg],"stream") == 0) {
+ } else if (strcmp(arg[iarg],"tstat") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command");
- if (strcmp(arg[iarg+1],"yes") == 0) streamflag = 1;
- else if (strcmp(arg[iarg+1],"no") == 0) streamflag = 0;
+ if (strcmp(arg[iarg+1],"no") == 0) tstat = 0;
+ else if (strcmp(arg[iarg+1],"yes") == 0) tstat = 1;
else error->all(FLERR,"Illegal fix srd command");
iarg += 2;
} else error->all(FLERR,"Illegal fix srd command");
@@ -168,7 +173,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
// error check
if (nevery <= 0) error->all(FLERR,"Illegal fix srd command");
- if (bigexist && biggroup < 0) error->all(FLERR,"Could not find fix srd group ID");
+ if (bigexist && biggroup < 0)
+ error->all(FLERR,"Could not find fix srd group ID");
if (gridsrd <= 0.0) error->all(FLERR,"Illegal fix srd command");
if (temperature_srd <= 0.0) error->all(FLERR,"Illegal fix srd command");
if (seed <= 0) error->all(FLERR,"Illegal fix srd command");
@@ -176,7 +182,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
if (maxbounceallow < 0) error->all(FLERR,"Illegal fix srd command");
if (lamdaflag && lamda <= 0.0) error->all(FLERR,"Illegal fix srd command");
if (gridsearch <= 0.0) error->all(FLERR,"Illegal fix srd command");
- if (cubictol < 0.0 || cubictol > 1.0) error->all(FLERR,"Illegal fix srd command");
+ if (cubictol < 0.0 || cubictol > 1.0)
+ error->all(FLERR,"Illegal fix srd command");
if ((shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE) &&
shiftseed <= 0) error->all(FLERR,"Illegal fix srd command");
@@ -236,6 +243,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
// atom style pointers to particles that store bonus info
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
// fix parameters
@@ -289,7 +298,8 @@ void FixSRD::init()
{
// error checks
- if (force->newton_pair == 0) error->all(FLERR,"Fix srd requires newton pair on");
+ if (force->newton_pair == 0)
+ error->all(FLERR,"Fix srd requires newton pair on");
if (bigexist && comm->ghost_velocity == 0)
error->all(FLERR,"Fix srd requires ghost atoms store velocity");
if (bigexist && collidestyle == NOSLIP && !atom->torque_flag)
@@ -319,19 +329,21 @@ void FixSRD::init()
fwall = wallfix->fwall;
walltrigger = 0.5 * neighbor->skin;
if (wallfix->overlap && overlap == 0 && me == 0)
- error->warning(FLERR,"Fix SRD walls overlap but fix srd overlap not set");
+ error->warning(FLERR,
+ "Fix SRD walls overlap but fix srd overlap not set");
}
}
// set change_flags if box size or shape changes
- change_size = change_shape = 0;
+ change_size = change_shape = deformflag = 0;
if (domain->nonperiodic == 2) change_size = 1;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->box_change) {
if (modify->fix[i]->box_change_size) change_size = 1;
if (modify->fix[i]->box_change_shape) change_shape = 1;
if (strcmp(modify->fix[i]->style,"deform") == 0) {
+ deformflag = 1;
FixDeform *deform = (FixDeform *) modify->fix[i];
if (deform->box_change_shape && deform->remapflag != V_REMAP)
error->all(FLERR,"Using fix srd with inconsistent "
@@ -339,6 +351,10 @@ void FixSRD::init()
}
}
+ if (deformflag && tstat == 0 && me == 0)
+ error->warning(FLERR,
+ "Using fix srd with box deformation but no SRD thermostat");
+
// parameterize based on current box volume
dimension = domain->dimension;
@@ -391,7 +407,8 @@ void FixSRD::setup(int vflag)
setup_bounds();
if (dist_srd_reneigh < nevery*dt_big*vmax && me == 0)
- error->warning(FLERR,"Fix srd SRD moves may trigger frequent reneighboring");
+ error->warning(FLERR,
+ "Fix srd SRD moves may trigger frequent reneighboring");
// setup search bins and search stencil based on these distances
@@ -407,6 +424,7 @@ void FixSRD::setup(int vflag)
reneighflag = BIG_MOVE;
pre_neighbor();
}
+
/* ----------------------------------------------------------------------
assign SRD particles to bins
assign big particles to all bins they overlap
@@ -416,6 +434,7 @@ void FixSRD::pre_neighbor()
{
int i,j,m,ix,iy,iz,jx,jy,jz,ibin,jbin,lo,hi;
double rsq,cutbinsq;
+ double xlamda[3];
// grow SRD per-atom bin arrays if necessary
@@ -561,7 +580,8 @@ void FixSRD::pre_neighbor()
if (side == 0) {
hi = static_cast ((xwall[m]+delta-xblo2)*bininv2x);
if (hi < 0) continue;
- if (hi >= nbin2x) error->all(FLERR,"Fix SRD: bad search bin assignment");
+ if (hi >= nbin2x) error->all(FLERR,
+ "Fix SRD: bad search bin assignment");
lo = 0;
} else {
lo = static_cast ((xwall[m]-delta-xblo2)*bininv2x);
@@ -583,7 +603,8 @@ void FixSRD::pre_neighbor()
if (side == 0) {
hi = static_cast ((xwall[m]+delta-yblo2)*bininv2y);
if (hi < 0) continue;
- if (hi >= nbin2y) error->all(FLERR,"Fix SRD: bad search bin assignment");
+ if (hi >= nbin2y) error->all(FLERR,
+ "Fix SRD: bad search bin assignment");
lo = 0;
} else {
lo = static_cast ((xwall[m]-delta-yblo2)*bininv2y);
@@ -605,7 +626,8 @@ void FixSRD::pre_neighbor()
if (side == 0) {
hi = static_cast ((xwall[m]+delta-zblo2)*bininv2z);
if (hi < 0) continue;
- if (hi >= nbin2z) error->all(FLERR,"Fix SRD: bad search bin assignment");
+ if (hi >= nbin2z) error->all(FLERR,
+ "Fix SRD: bad search bin assignment");
lo = 0;
} else {
lo = static_cast ((xwall[m]-delta-zblo2)*bininv2z);
@@ -645,6 +667,7 @@ void FixSRD::pre_neighbor()
void FixSRD::post_force(int vflag)
{
int i,m,ix,iy,iz;
+ double xlamda[3];
// zero per-timestep stats
@@ -765,19 +788,20 @@ void FixSRD::post_force(int vflag)
/* ----------------------------------------------------------------------
reset SRD velocities
- may perform random shifting by 1/2 bin in each dimension
+ may perform random shifting by up to 1/2 bin in each dimension
called at pre-neighbor stage when all SRDs are now inside my sub-domain
- for triclinic, will set mean velocity to box deformation velocity
+ if tstat, then thermostat SRD particles as well, including streaming effects
------------------------------------------------------------------------- */
void FixSRD::reset_velocities()
{
int i,j,n,ix,iy,iz,ibin,axis,sign,irandom;
- double u[3],vave[3];
- double vx,vy,vz,vsq;
- double *vold,*vnew,*xlamda;
+ double u[3],vsum[3];
+ double vx,vy,vz,vsq,tbin,scale;
+ double *vave,*vnew,*xlamda;
+ double vstream[3];
- // if requested, perform a dynamic shift
+ // if requested, perform a dynamic shift of bin positions
if (shiftflag) {
double *boxlo;
@@ -831,39 +855,23 @@ void FixSRD::reset_velocities()
if (triclinic) domain->lamda2x(nlocal);
- if (triclinic && streamflag) {
- double *h_rate = domain->h_rate;
- double *h_ratelo = domain->h_ratelo;
- for (i = 0; i < nlocal; i++)
- if (mask[i] & groupbit) {
- xlamda = x[i];
- v[i][0] -= h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] +
- h_rate[4]*xlamda[2] + h_ratelo[0];
- v[i][1] -= h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
- v[i][2] -= h_rate[2]*xlamda[2] + h_ratelo[2];
- }
- }
-
// for each bin I have particles contributing to:
- // compute ave v and v^2 of particles in that bin
+ // compute summed v of particles in that bin
// if I own the bin, set its random value, else set to 0.0
for (i = 0; i < nbins; i++) {
n = 0;
- vave[0] = vave[1] = vave[2] = 0.0;
+ vsum[0] = vsum[1] = vsum[2] = 0.0;
for (j = binhead[i]; j >= 0; j = binnext[j]) {
- vx = v[j][0];
- vy = v[j][1];
- vz = v[j][2];
- vave[0] += vx;
- vave[1] += vy;
- vave[2] += vz;
+ vsum[0] += v[j][0];
+ vsum[1] += v[j][1];
+ vsum[2] += v[j][2];
n++;
}
- vbin[i].vave[0] = vave[0];
- vbin[i].vave[1] = vave[1];
- vbin[i].vave[2] = vave[2];
+ vbin[i].vsum[0] = vsum[0];
+ vbin[i].vsum[1] = vsum[1];
+ vbin[i].vsum[2] = vsum[2];
vbin[i].n = n;
if (vbin[i].owner) vbin[i].random = random->uniform();
else vbin[i].random = 0.0;
@@ -874,24 +882,43 @@ void FixSRD::reset_velocities()
if (shifts[shiftflag].commflag) vbin_comm(shiftflag);
// for each bin I have particles contributing to:
- // reassign particle velocity by rotation around a random axis
- // accumulate T_srd for each bin I own
- // for triclinic, replace mean velocity with stream velocity
+ // compute vave over particles in bin
+ // thermal velocity of each particle = v - vave
+ // rotate thermal vel of each particle around one of 6 random axes
+ // add vave back to each particle
+ // thermostat if requested:
+ // if no deformation, rescale thermal vel to temperature
+ // if deformation, rescale thermal vel and change vave to vstream
+ // these are settings for extra dof_temp, dof_tstat to subtract
+ // (not sure why these settings work best)
+ // no deformation, no tstat: dof_temp = 1
+ // yes deformation, no tstat: doesn't matter, system will not equilibrate
+ // no deformation, yes tstat: dof_temp = dof_tstat = 1
+ // yes deformation, yes tstat: dof_temp = dof_tstat = 0
+ // accumulate final T_srd for each bin I own
+
+ double tfactor = force->mvv2e * mass_srd / (dimension * force->boltz);
+ int dof_temp = 1;
+ int dof_tstat;
+ if (tstat) {
+ if (deformflag) dof_tstat = dof_temp = 0;
+ else dof_tstat = 1;
+ }
srd_bin_temp = 0.0;
srd_bin_count = 0;
if (dimension == 2) axis = 2;
+ double *h_rate = domain->h_rate;
+ double *h_ratelo = domain->h_ratelo;
for (i = 0; i < nbins; i++) {
n = vbin[i].n;
if (n == 0) continue;
- vold = vbin[i].vave;
- vold[0] /= n;
- vold[1] /= n;
- vold[2] /= n;
-
- vnew = vold;
+ vave = vbin[i].vsum;
+ vave[0] /= n;
+ vave[1] /= n;
+ vave[2] /= n;
irandom = static_cast (6.0*vbin[i].random);
sign = irandom % 2;
@@ -900,47 +927,63 @@ void FixSRD::reset_velocities()
vsq = 0.0;
for (j = binhead[i]; j >= 0; j = binnext[j]) {
if (axis == 0) {
- u[0] = v[j][0]-vold[0];
- u[1] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2];
- u[2] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1];
+ u[0] = v[j][0]-vave[0];
+ u[1] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2];
+ u[2] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1];
} else if (axis == 1) {
- u[1] = v[j][1]-vold[1];
- u[0] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2];
- u[2] = sign ? vold[0]-v[j][0] : v[j][0]-vold[0];
+ u[1] = v[j][1]-vave[1];
+ u[0] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2];
+ u[2] = sign ? vave[0]-v[j][0] : v[j][0]-vave[0];
} else {
- u[2] = v[j][2]-vold[2];
- u[1] = sign ? v[j][0]-vold[0] : vold[0]-v[j][0];
- u[0] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1];
+ u[2] = v[j][2]-vave[2];
+ u[1] = sign ? v[j][0]-vave[0] : vave[0]-v[j][0];
+ u[0] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1];
}
vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2];
- v[j][0] = u[0] + vnew[0];
- v[j][1] = u[1] + vnew[1];
- v[j][2] = u[2] + vnew[2];
+ v[j][0] = u[0] + vave[0];
+ v[j][1] = u[1] + vave[1];
+ v[j][2] = u[2] + vave[2];
+ }
+
+ if (tstat && n > 1) {
+ if (deformflag) {
+ xlamda = vbin[i].xctr;
+ vstream[0] = h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] +
+ h_rate[4]*xlamda[2] + h_ratelo[0];
+ vstream[1] = h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
+ vstream[2] = h_rate[2]*xlamda[2] + h_ratelo[2];
+ } else {
+ vstream[0] = vave[0];
+ vstream[1] = vave[1];
+ vstream[2] = vave[2];
+ }
+
+ // tbin = thermal temperature of particles in bin
+ // scale = scale factor for thermal velocity
+
+ tbin = vsq/(n-dof_tstat) * tfactor;
+ scale = sqrt(temperature_srd/tbin);
+
+ vsq = 0.0;
+ for (j = binhead[i]; j >= 0; j = binnext[j]) {
+ u[0] = (v[j][0] - vave[0]) * scale;
+ u[1] = (v[j][1] - vave[1]) * scale;
+ u[2] = (v[j][2] - vave[2]) * scale;
+ vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2];
+ v[j][0] = u[0] + vstream[0];
+ v[j][1] = u[1] + vstream[1];
+ v[j][2] = u[2] + vstream[2];
+ }
}
// sum partial contribution of my particles to T even if I don't own bin
- // but only count bin if I own it, so that bin is counted exactly once
+ // but only count bin if I own it, so each bin is counted exactly once
- if (n > 1) {
- srd_bin_temp += vsq / (n-1);
- if (vbin[i].owner) srd_bin_count++;
- }
+ if (n > 1) srd_bin_temp += vsq/(n-dof_temp);
+ if (vbin[i].owner) srd_bin_count++;
}
- srd_bin_temp *= force->mvv2e * mass_srd / (dimension * force->boltz);
-
- if (triclinic && streamflag) {
- double *h_rate = domain->h_rate;
- double *h_ratelo = domain->h_ratelo;
- for (i = 0; i < nlocal; i++)
- if (mask[i] & groupbit) {
- xlamda = x[i];
- v[i][0] += h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] +
- h_rate[4]*xlamda[2] + h_ratelo[0];
- v[i][1] += h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
- v[i][2] += h_rate[2]*xlamda[2] + h_ratelo[2];
- }
- }
+ srd_bin_temp *= tfactor;
// rescale any too-large velocities
@@ -1032,9 +1075,9 @@ void FixSRD::vbin_pack(BinAve *vbin, int n, int *list, double *buf)
for (int i = 0; i < n; i++) {
j = list[i];
buf[m++] = vbin[j].n;
- buf[m++] = vbin[j].vave[0];
- buf[m++] = vbin[j].vave[1];
- buf[m++] = vbin[j].vave[2];
+ buf[m++] = vbin[j].vsum[0];
+ buf[m++] = vbin[j].vsum[1];
+ buf[m++] = vbin[j].vsum[2];
buf[m++] = vbin[j].random;
}
}
@@ -1050,9 +1093,9 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list)
for (int i = 0; i < n; i++) {
j = list[i];
vbin[j].n += static_cast (buf[m++]);
- vbin[j].vave[0] += buf[m++];
- vbin[j].vave[1] += buf[m++];
- vbin[j].vave[2] += buf[m++];
+ vbin[j].vsum[0] += buf[m++];
+ vbin[j].vsum[1] += buf[m++];
+ vbin[j].vsum[2] += buf[m++];
vbin[j].random += buf[m++];
}
}
@@ -1065,7 +1108,7 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list)
void FixSRD::collisions_single()
{
- int i,j,k,m,type,mbig,ibin,ibounce,inside,collide_flag;
+ int i,j,k,m,type,nbig,ibin,ibounce,inside,collide_flag,lineside;
double dt,t_remain;
double norm[3],xscoll[3],xbcoll[3],vsnew[3];
Big *big;
@@ -1097,11 +1140,11 @@ void FixSRD::collisions_single()
dt = dt_big;
while (collide_flag) {
- mbig = nbinbig[ibin];
- if (ibounce == 0) ncheck += mbig;
+ nbig = nbinbig[ibin];
+ if (ibounce == 0) ncheck += nbig;
collide_flag = 0;
- for (m = 0; m < mbig; m++) {
+ for (m = 0; m < nbig; m++) {
k = binbig[ibin][m];
big = &biglist[k];
j = big->index;
@@ -1161,17 +1204,11 @@ void FixSRD::collisions_single()
}
if (collidestyle == SLIP) {
- if (type == SPHERE)
- slip_sphere(v[i],v[j],norm,vsnew);
- else if (type == ELLIPSOID)
- slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew);
- else
- slip_wall(v[i],j,norm,vsnew);
+ if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
+ else slip_wall(v[i],j,norm,vsnew);
} else {
- if (type != WALL)
- noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
- else
- noslip_wall(v[i],j,xscoll,norm,vsnew);
+ if (type != WALL) noslip(v[i],v[j],x[j],big,-1, xscoll,norm,vsnew);
+ else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew);
}
if (dimension == 2) vsnew[2] = 0.0;
@@ -1222,7 +1259,7 @@ void FixSRD::collisions_single()
void FixSRD::collisions_multi()
{
- int i,j,k,m,type,mbig,ibin,ibounce,inside,jfirst,typefirst;
+ int i,j,k,m,type,nbig,ibin,ibounce,inside,jfirst,typefirst,jlast;
double dt,t_remain,t_first;
double norm[3],xscoll[3],xbcoll[3],vsnew[3];
double normfirst[3],xscollfirst[3],xbcollfirst[3];
@@ -1251,22 +1288,31 @@ void FixSRD::collisions_multi()
if (nbinbig[ibin] == 0) continue;
ibounce = 0;
+ jlast = -1;
dt = dt_big;
while (1) {
- mbig = nbinbig[ibin];
- if (ibounce == 0) ncheck += mbig;
+ nbig = nbinbig[ibin];
+ if (ibounce == 0) ncheck += nbig;
t_first = 0.0;
- for (m = 0; m < mbig; m++) {
+ for (m = 0; m < nbig; m++) {
k = binbig[ibin][m];
big = &biglist[k];
j = big->index;
+ if (j == jlast) continue;
type = big->type;
- if (type == SPHERE) inside = inside_sphere(x[i],x[j],big);
- else if (type == ELLIPSOID) inside = inside_ellipsoid(x[i],x[j],big);
- else inside = inside_wall(x[i],j);
+ if (type == SPHERE)
+ inside = inside_sphere(x[i],x[j],big);
+ else if (type == ELLIPSOID)
+ inside = inside_ellipsoid(x[i],x[j],big);
+ else if (type == LINE)
+ inside = inside_line(x[i],x[j],v[i],v[j],big,dt);
+ else if (type == TRIANGLE)
+ inside = inside_tri(x[i],x[j],v[i],v[j],big,dt);
+ else
+ inside = inside_wall(x[i],j);
if (inside) {
if (type == SPHERE)
@@ -1275,6 +1321,12 @@ void FixSRD::collisions_multi()
else if (type == ELLIPSOID)
t_remain = collision_ellipsoid_exact(x[i],x[j],v[i],v[j],big,
xscoll,xbcoll,norm);
+ else if (type == LINE)
+ t_remain = collision_line_exact(x[i],x[j],v[i],v[j],big,dt,
+ xscoll,xbcoll,norm);
+ else if (type == TRIANGLE)
+ t_remain = collision_tri_exact(x[i],x[j],v[i],v[j],big,dt,
+ xscoll,xbcoll,norm);
else
t_remain = collision_wall_exact(x[i],j,v[i],xscoll,xbcoll,norm);
@@ -1318,7 +1370,7 @@ void FixSRD::collisions_multi()
}
if (t_first == 0.0) break;
- j = jfirst;
+ j = jlast = jfirst;
type = typefirst;
xscoll[0] = xscollfirst[0];
xscoll[1] = xscollfirst[1];
@@ -1331,17 +1383,11 @@ void FixSRD::collisions_multi()
norm[2] = normfirst[2];
if (collidestyle == SLIP) {
- if (type == SPHERE)
- slip_sphere(v[i],v[j],norm,vsnew);
- else if (type == ELLIPSOID)
- slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew);
- else
- slip_wall(v[i],j,norm,vsnew);
+ if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
+ else slip_wall(v[i],j,norm,vsnew);
} else {
- if (type != WALL)
- noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
- else
- noslip_wall(v[i],j,xscoll,norm,vsnew);
+ if (type != WALL) noslip(v[i],v[j],x[j],big,-1,xscoll,norm,vsnew);
+ else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew);
}
if (dimension == 2) vsnew[2] = 0.0;
@@ -1420,6 +1466,276 @@ int FixSRD::inside_ellipsoid(double *xs, double *xb, Big *big)
return 0;
}
+/* ----------------------------------------------------------------------
+ check if SRD particle S is inside line big particle B
+ collision only possible if:
+ S starts on positive side of infinite line,
+ which means it will collide with outside of rigid body made of lines
+ since line segments have outward normals,
+ when vector from first to last point is crossed with +z axis
+ S ends on negative side of infinite line
+ unlike most other inside() routines, then calculate exact collision:
+ solve for collision pt along infinite line
+ collision if pt is within endpoints of B
+------------------------------------------------------------------------- */
+
+int FixSRD::inside_line(double *xs, double *xb, double *vs, double *vb,
+ Big *big, double dt_step)
+{
+ double pmc0[2],pmc1[2],n0[2],n1[2];
+ double n1_n0[2],pmc1_pmc0[2];
+
+ // 1 and 2 = start and end of timestep
+ // pmc = P - C, where P = position of S, C = position of B
+ // n = normal to line = [-sin(theta),cos(theta)], theta = orientation of B
+ // (P-C) dot N = side of line that S is on
+ // side0 = -1,0,1 for which side of line B that S is on at start of step
+ // side1 = -1,0,1 for which side of line B that S is on at end of step
+
+ xs1[0] = xs[0];
+ xs1[1] = xs[1];
+ xb1[0] = xb[0];
+ xb1[1] = xb[1];
+
+ xs0[0] = xs1[0] - dt_step*vs[0];
+ xs0[1] = xs1[1] - dt_step*vs[1];
+ xb0[0] = xb1[0] - dt_step*vb[0];
+ xb0[1] = xb1[1] - dt_step*vb[1];
+
+ theta1 = big->theta;
+ theta0 = theta1 - dt_step*big->omega[2];
+
+ pmc0[0] = xs0[0] - xb0[0];
+ pmc0[1] = xs0[1] - xb0[1];
+ n0[0] = sin(theta0);
+ n0[1] = -cos(theta0);
+
+ pmc1[0] = xs1[0] - xb1[0];
+ pmc1[1] = xs1[1] - xb1[1];
+ n1[0] = sin(theta1);
+ n1[1] = -cos(theta1);
+
+ double side0 = pmc0[0]*n0[0] + pmc0[1]*n0[1];
+ double side1 = pmc1[0]*n1[0] + pmc1[1]*n1[1];
+
+ if (side0 <= 0.0 || side1 >= 0.0) return 0;
+
+ // solve for time t (0 to 1) at which moving particle
+ // crosses infinite moving/rotating line
+
+ // Newton-Raphson solve of full non-linear parametric equation
+
+ tfraction = newton_raphson(0.0,1.0);
+
+ // quadratic equation solve of approximate parametric equation
+
+ /*
+ n1_n0[0] = n1[0]-n0[0]; n1_n0[1] = n1[1]-n0[1];
+ pmc1_pmc0[0] = pmc1[0]-pmc0[0]; pmc1_pmc0[1] = pmc1[1]-pmc0[1];
+
+ double a = pmc1_pmc0[0]*n1_n0[0] + pmc1_pmc0[1]*n1_n0[1];
+ double b = pmc1_pmc0[0]*n0[0] + pmc1_pmc0[1]*n0[1] +
+ n1_n0[0]*pmc0[0] + n1_n0[1]*pmc0[1];
+ double c = pmc0[0]*n0[0] + pmc0[1]*n0[1];
+
+ if (a == 0.0) {
+ double dot0 = pmc0[0]*n0[0] + pmc0[1]*n0[1];
+ double dot1 = pmc1[0]*n0[0] + pmc1[1]*n0[1];
+ double root = -dot0 / (dot1 - dot0);
+ //printf("Linear root: %g %g\n",root,tfraction);
+ tfraction = root;
+
+ } else {
+
+ double term = sqrt(b*b - 4.0*a*c);
+ double root1 = (-b + term) / (2.0*a);
+ double root2 = (-b - term) / (2.0*a);
+
+ //printf("ABC vecs: %g %g: %g %g\n",
+ // pmc1_pmc0[0],pmc1_pmc0[1],n1_n0[0],n1_n0[1]);
+ //printf("ABC vecs: %g %g: %g %g: %g %g %g\n",
+ // n0[0],n0[1],n1[0],n1[1],theta0,theta1,big->omega[2]);
+ //printf("ABC root: %g %g %g: %g %g %g\n",a,b,c,root1,root2,tfraction);
+
+ if (0.0 <= root1 && root1 <= 1.0) tfraction = root1;
+ else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2;
+ else error->one(FLERR,"Bad quadratic solve for particle/line collision");
+ }
+ */
+
+ // check if collision pt is within line segment at collision time
+
+ xsc[0] = xs0[0] + tfraction*(xs1[0]-xs0[0]);
+ xsc[1] = xs0[1] + tfraction*(xs1[1]-xs0[1]);
+ xbc[0] = xb0[0] + tfraction*(xb1[0]-xb0[0]);
+ xbc[1] = xb0[1] + tfraction*(xb1[1]-xb0[1]);
+ double delx = xsc[0] - xbc[0];
+ double dely = xsc[1] - xbc[1];
+ double rsq = delx*delx + dely*dely;
+ if (rsq > 0.25*big->length*big->length) return 0;
+
+ //nbc[0] = n0[0] + tfraction*(n1[0]-n0[0]);
+ //nbc[1] = n0[1] + tfraction*(n1[1]-n0[1]);
+
+ nbc[0] = sin(theta0 + tfraction*(theta1-theta0));
+ nbc[1] = -cos(theta0 + tfraction*(theta1-theta0));
+
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ check if SRD particle S is inside triangle big particle B
+ collision only possible if:
+ S starts on positive side of triangle plane,
+ which means it will collide with outside of rigid body made of tris
+ since triangles have outward normals,
+ S ends on negative side of triangle plane
+ unlike most other inside() routines, then calculate exact collision:
+ solve for collision pt on triangle plane
+ collision if pt is inside triangle B
+------------------------------------------------------------------------- */
+
+int FixSRD::inside_tri(double *xs, double *xb, double *vs, double *vb,
+ Big *big, double dt_step)
+{
+ double pmc0[3],pmc1[3],n0[3];
+ double n1_n0[3],pmc1_pmc0[3];
+ double excoll[3],eycoll[3],ezcoll[3];
+ double dc1[3],dc2[3],dc3[3];
+ double c1[3],c2[3],c3[3];
+ double c2mc1[3],c3mc2[3],c1mc3[3];
+ double pvec[3],xproduct[3];
+
+ // 1 and 2 = start and end of timestep
+ // pmc = P - C, where P = position of S, C = position of B
+ // n = normal to triangle
+ // (P-C) dot N = side of tri that S is on
+ // side0 = -1,0,1 for which side of tri B that S is on at start of step
+ // side1 = -1,0,1 for which side of tri B that S is on at end of step
+
+ double *omega = big->omega;
+ double *n1 = big->norm;
+
+ n0[0] = n1[0] - dt_step*(omega[1]*n1[2] - omega[2]*n1[1]);
+ n0[1] = n1[1] - dt_step*(omega[2]*n1[0] - omega[0]*n1[2]);
+ n0[2] = n1[2] - dt_step*(omega[0]*n1[1] - omega[1]*n1[0]);
+
+ pmc0[0] = xs[0] - dt_step*vs[0] - xb[0] + dt_step*vb[0];
+ pmc0[1] = xs[1] - dt_step*vs[1] - xb[1] + dt_step*vb[1];
+ pmc0[2] = xs[2] - dt_step*vs[2] - xb[2] + dt_step*vb[2];
+ pmc1[0] = xs[0] - xb[0];
+ pmc1[1] = xs[1] - xb[1];
+ pmc1[2] = xs[2] - xb[2];
+
+ double side0 = MathExtra::dot3(pmc0,n0);
+ double side1 = MathExtra::dot3(pmc1,n1);
+
+ if (side0 <= 0.0 || side1 >= 0.0) return 0;
+
+ // solve for time t (0 to 1) at which moving particle
+ // crosses moving/rotating tri
+ // quadratic equation solve of approximate parametric equation
+
+ n1_n0[0] = n1[0]-n0[0];
+ n1_n0[1] = n1[1]-n0[1];
+ n1_n0[2] = n1[2]-n0[2];
+ pmc1_pmc0[0] = pmc1[0]-pmc0[0];
+ pmc1_pmc0[1] = pmc1[1]-pmc0[1];
+ pmc1_pmc0[2] = pmc1[2]-pmc0[2];
+
+ double a = MathExtra::dot3(pmc1_pmc0,n1_n0);
+ double b = MathExtra::dot3(pmc1_pmc0,n0) + MathExtra::dot3(n1_n0,pmc0);
+ double c = MathExtra::dot3(pmc0,n0);
+
+ if (a == 0.0) {
+ double dot0 = MathExtra::dot3(pmc0,n0);
+ double dot1 = MathExtra::dot3(pmc1,n0);
+ double root = -dot0 / (dot1 - dot0);
+ tfraction = root;
+ } else {
+ double term = sqrt(b*b - 4.0*a*c);
+ double root1 = (-b + term) / (2.0*a);
+ double root2 = (-b - term) / (2.0*a);
+ if (0.0 <= root1 && root1 <= 1.0) tfraction = root1;
+ else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2;
+ else error->one(FLERR,"Bad quadratic solve for particle/tri collision");
+ }
+
+ // calculate position/orientation of S and B at collision time
+ // dt = time previous to now at which collision occurs
+ // point = S position in plane of triangle at collision time
+ // Excoll,Eycoll,Ezcoll = orientation of tri at collision time
+ // c1,c2,c3 = corner points of triangle at collision time
+ // nbc = normal to plane of triangle at collision time
+
+ AtomVecTri::Bonus *tbonus;
+ tbonus = avec_tri->bonus;
+
+ double *ex = big->ex;
+ double *ey = big->ey;
+ double *ez = big->ez;
+ int index = atom->tri[big->index];
+ double *c1body = tbonus[index].c1;
+ double *c2body = tbonus[index].c2;
+ double *c3body = tbonus[index].c3;
+
+ double dt = (1.0-tfraction)*dt_step;
+
+ xsc[0] = xs[0] - dt*vs[0];
+ xsc[1] = xs[1] - dt*vs[1];
+ xsc[2] = xs[2] - dt*vs[2];
+ xbc[0] = xb[0] - dt*vb[0];
+ xbc[1] = xb[1] - dt*vb[1];
+ xbc[2] = xb[2] - dt*vb[2];
+
+ excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]);
+ excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]);
+ excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]);
+
+ eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]);
+ eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]);
+ eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]);
+
+ ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]);
+ ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]);
+ ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]);
+
+ MathExtra::matvec(excoll,eycoll,ezcoll,c1body,dc1);
+ MathExtra::matvec(excoll,eycoll,ezcoll,c2body,dc2);
+ MathExtra::matvec(excoll,eycoll,ezcoll,c3body,dc3);
+
+ MathExtra::add3(xbc,dc1,c1);
+ MathExtra::add3(xbc,dc2,c2);
+ MathExtra::add3(xbc,dc3,c3);
+
+ MathExtra::sub3(c2,c1,c2mc1);
+ MathExtra::sub3(c3,c2,c3mc2);
+ MathExtra::sub3(c1,c3,c1mc3);
+
+ MathExtra::cross3(c2mc1,c3mc2,nbc);
+ MathExtra::norm3(nbc);
+
+ // check if collision pt is within triangle
+ // pvec = vector from tri vertex to intersection point
+ // xproduct = cross product of edge vec with pvec
+ // if dot product of xproduct with nbc < 0.0 for any of 3 edges,
+ // intersection point is outside tri
+
+ MathExtra::sub3(xsc,c1,pvec);
+ MathExtra::cross3(c2mc1,pvec,xproduct);
+ if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0;
+
+ MathExtra::sub3(xsc,c2,pvec);
+ MathExtra::cross3(c3mc2,pvec,xproduct);
+ if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0;
+
+ MathExtra::sub3(xsc,c3,pvec);
+ MathExtra::cross3(c1mc3,pvec,xproduct);
+ if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0;
+
+ return 1;
+}
+
/* ----------------------------------------------------------------------
check if SRD particle S is inside wall IWALL
------------------------------------------------------------------------- */
@@ -1451,7 +1767,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb,
double vs_dot_vs,vb_dot_vb,vs_dot_vb;
double vs_dot_xb,vb_dot_xs,vs_dot_xs,vb_dot_xb;
double xs_dot_xs,xb_dot_xb,xs_dot_xb;
- double a,b,c,scale,dt;
+ double a,b,c,scale;
vs_dot_vs = vs[0]*vs[0] + vs[1]*vs[1] + vs[2]*vs[2];
vb_dot_vb = vb[0]*vb[0] + vb[1]*vb[1] + vb[2]*vb[2];
@@ -1470,7 +1786,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb,
b = 2.0 * (vs_dot_xb + vb_dot_xs - vs_dot_xs - vb_dot_xb);
c = xs_dot_xs + xb_dot_xb - 2.0*xs_dot_xb - big->radsq;
- dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
+ double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
xscoll[0] = xs[0] - dt*vs[0];
xscoll[1] = xs[1] - dt*vs[1];
@@ -1541,7 +1857,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
double vs_vb[3],xs_xb[3],omega_ex[3],omega_ey[3],omega_ez[3];
double excoll[3],eycoll[3],ezcoll[3],delta[3],xbody[3],nbody[3];
double ax,bx,cx,ay,by,cy,az,bz,cz;
- double a,b,c,dt,scale;
+ double a,b,c,scale;
double *omega = big->omega;
double *ex = big->ex;
@@ -1551,17 +1867,9 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
vs_vb[0] = vs[0]-vb[0]; vs_vb[1] = vs[1]-vb[1]; vs_vb[2] = vs[2]-vb[2];
xs_xb[0] = xs[0]-xb[0]; xs_xb[1] = xs[1]-xb[1]; xs_xb[2] = xs[2]-xb[2];
- omega_ex[0] = omega[1]*ex[2] - omega[2]*ex[1];
- omega_ex[1] = omega[2]*ex[0] - omega[0]*ex[2];
- omega_ex[2] = omega[0]*ex[1] - omega[1]*ex[0];
-
- omega_ey[0] = omega[1]*ey[2] - omega[2]*ey[1];
- omega_ey[1] = omega[2]*ey[0] - omega[0]*ey[2];
- omega_ey[2] = omega[0]*ey[1] - omega[1]*ey[0];
-
- omega_ez[0] = omega[1]*ez[2] - omega[2]*ez[1];
- omega_ez[1] = omega[2]*ez[0] - omega[0]*ez[2];
- omega_ez[2] = omega[0]*ez[1] - omega[1]*ez[0];
+ MathExtra::cross3(omega,ex,omega_ex);
+ MathExtra::cross3(omega,ey,omega_ey);
+ MathExtra::cross3(omega,ez,omega_ez);
ax = vs_vb[0]*omega_ex[0] + vs_vb[1]*omega_ex[1] + vs_vb[2]*omega_ex[2];
bx = -(vs_vb[0]*ex[0] + vs_vb[1]*ex[1] + vs_vb[2]*ex[2]);
@@ -1586,7 +1894,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
c = cx*cx*big->aradsqinv + cy*cy*big->bradsqinv +
cz*cz*big->cradsqinv - 1.0;
- dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
+ double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
xscoll[0] = xs[0] - dt*vs[0];
xscoll[1] = xs[1] - dt*vs[1];
@@ -1602,37 +1910,27 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
// norm = normal in space frame
// only worry about normalizing final norm vector
- excoll[0] = ex[0] - dt * (omega[1]*ex[2] - omega[2]*ex[1]);
- excoll[1] = ex[1] - dt * (omega[2]*ex[0] - omega[0]*ex[2]);
- excoll[2] = ex[2] - dt * (omega[0]*ex[1] - omega[1]*ex[0]);
+ excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]);
+ excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]);
+ excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]);
- eycoll[0] = ey[0] - dt * (omega[1]*ey[2] - omega[2]*ey[1]);
- eycoll[1] = ey[1] - dt * (omega[2]*ey[0] - omega[0]*ey[2]);
- eycoll[2] = ey[2] - dt * (omega[0]*ey[1] - omega[1]*ey[0]);
+ eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]);
+ eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]);
+ eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]);
- ezcoll[0] = ez[0] - dt * (omega[1]*ez[2] - omega[2]*ez[1]);
- ezcoll[1] = ez[1] - dt * (omega[2]*ez[0] - omega[0]*ez[2]);
- ezcoll[2] = ez[2] - dt * (omega[0]*ez[1] - omega[1]*ez[0]);
+ ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]);
+ ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]);
+ ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]);
- delta[0] = xscoll[0] - xbcoll[0];
- delta[1] = xscoll[1] - xbcoll[1];
- delta[2] = xscoll[2] - xbcoll[2];
-
- xbody[0] = delta[0]*excoll[0] + delta[1]*excoll[1] + delta[2]*excoll[2];
- xbody[1] = delta[0]*eycoll[0] + delta[1]*eycoll[1] + delta[2]*eycoll[2];
- xbody[2] = delta[0]*ezcoll[0] + delta[1]*ezcoll[1] + delta[2]*ezcoll[2];
+ MathExtra::sub3(xscoll,xbcoll,delta);
+ MathExtra::transpose_matvec(excoll,eycoll,ezcoll,delta,xbody);
nbody[0] = xbody[0]*big->aradsqinv;
nbody[1] = xbody[1]*big->bradsqinv;
nbody[2] = xbody[2]*big->cradsqinv;
- norm[0] = excoll[0]*nbody[0] + eycoll[0]*nbody[1] + ezcoll[0]*nbody[2];
- norm[1] = excoll[1]*nbody[0] + eycoll[1]*nbody[1] + ezcoll[1]*nbody[2];
- norm[2] = excoll[2]*nbody[0] + eycoll[2]*nbody[1] + ezcoll[2]*nbody[2];
- scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
- norm[0] *= scale;
- norm[1] *= scale;
- norm[2] *= scale;
+ MathExtra::matvec(excoll,eycoll,ezcoll,nbody,norm);
+ MathExtra::norm3(norm);
return dt;
}
@@ -1640,6 +1938,10 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
/* ----------------------------------------------------------------------
collision of SRD particle S with surface of ellipsoidal big particle B
inexact because just push SRD to surface of big particle at end of step
+ time of collision = end of step
+ xscoll = collision pt = position of SRD at time of collision
+ xbcoll = xb = position of big particle at time of collision
+ norm = surface normal of collision pt at time of collision
------------------------------------------------------------------------- */
void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb,
@@ -1648,22 +1950,18 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb,
double *norm)
{
double xs_xb[3],delta[3],xbody[3],nbody[3];
- double x,y,z,scale;
double *ex = big->ex;
double *ey = big->ey;
double *ez = big->ez;
- xs_xb[0] = xs[0] - xb[0];
- xs_xb[1] = xs[1] - xb[1];
- xs_xb[2] = xs[2] - xb[2];
+ MathExtra::sub3(xs,xb,xs_xb);
+ double x = MathExtra::dot3(xs_xb,ex);
+ double y = MathExtra::dot3(xs_xb,ey);
+ double z = MathExtra::dot3(xs_xb,ez);
- x = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2];
- y = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2];
- z = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2];
-
- scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv +
- z*z*big->cradsqinv);
+ double scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv +
+ z*z*big->cradsqinv);
x *= scale;
y *= scale;
z *= scale;
@@ -1681,25 +1979,73 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb,
// norm = normal in space frame
// only worry about normalizing final norm vector
- delta[0] = xscoll[0] - xbcoll[0];
- delta[1] = xscoll[1] - xbcoll[1];
- delta[2] = xscoll[2] - xbcoll[2];
-
- xbody[0] = delta[0]*ex[0] + delta[1]*ex[1] + delta[2]*ex[2];
- xbody[1] = delta[0]*ey[0] + delta[1]*ey[1] + delta[2]*ey[2];
- xbody[2] = delta[0]*ez[0] + delta[1]*ez[1] + delta[2]*ez[2];
+ MathExtra::sub3(xscoll,xbcoll,delta);
+ MathExtra::transpose_matvec(ex,ey,ez,delta,xbody);
nbody[0] = xbody[0]*big->aradsqinv;
nbody[1] = xbody[1]*big->bradsqinv;
nbody[2] = xbody[2]*big->cradsqinv;
- norm[0] = ex[0]*nbody[0] + ey[0]*nbody[1] + ez[0]*nbody[2];
- norm[1] = ex[1]*nbody[0] + ey[1]*nbody[1] + ez[1]*nbody[2];
- norm[2] = ex[2]*nbody[0] + ey[2]*nbody[1] + ez[2]*nbody[2];
- scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
- norm[0] *= scale;
- norm[1] *= scale;
- norm[2] *= scale;
+ MathExtra::matvec(ex,ey,ez,nbody,norm);
+ MathExtra::norm3(norm);
+}
+
+/* ----------------------------------------------------------------------
+ collision of SRD particle S with surface of line big particle B
+ exact because compute time of collision
+ dt = time previous to now at which collision occurs
+ xscoll = collision pt = position of SRD at time of collision
+ xbcoll = position of big particle at time of collision
+ norm = surface normal of collision pt at time of collision
+------------------------------------------------------------------------- */
+
+double FixSRD::collision_line_exact(double *xs, double *xb,
+ double *vs, double *vb, Big *big,
+ double dt_step,
+ double *xscoll, double *xbcoll,
+ double *norm)
+{
+ xscoll[0] = xsc[0];
+ xscoll[1] = xsc[1];
+ xscoll[2] = 0.0;
+ xbcoll[0] = xbc[0];
+ xbcoll[1] = xbc[1];
+ xbcoll[2] = 0.0;
+
+ norm[0] = nbc[0];
+ norm[1] = nbc[1];
+ norm[2] = 0.0;
+
+ return (1.0-tfraction)*dt_step;
+}
+
+/* ----------------------------------------------------------------------
+ collision of SRD particle S with surface of triangle big particle B
+ exact because compute time of collision
+ dt = time previous to now at which collision occurs
+ xscoll = collision pt = position of SRD at time of collision
+ xbcoll = position of big particle at time of collision
+ norm = surface normal of collision pt at time of collision
+------------------------------------------------------------------------- */
+
+double FixSRD::collision_tri_exact(double *xs, double *xb,
+ double *vs, double *vb, Big *big,
+ double dt_step,
+ double *xscoll, double *xbcoll,
+ double *norm)
+{
+ xscoll[0] = xsc[0];
+ xscoll[1] = xsc[1];
+ xscoll[2] = xsc[2];
+ xbcoll[0] = xbc[0];
+ xbcoll[1] = xbc[1];
+ xbcoll[2] = xbc[2];
+
+ norm[0] = nbc[0];
+ norm[1] = nbc[1];
+ norm[2] = nbc[2];
+
+ return (1.0-tfraction)*dt_step;
}
/* ----------------------------------------------------------------------
@@ -1707,6 +2053,7 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb,
exact because compute time of collision
dt = time previous to now at which collision occurs
xscoll = collision pt = position of SRD at time of collision
+ xbcoll = position of wall at time of collision
norm = surface normal of collision pt at time of collision
------------------------------------------------------------------------- */
@@ -1737,6 +2084,7 @@ double FixSRD::collision_wall_exact(double *xs, int iwall, double *vs,
inexact because just push SRD to surface of wall at end of step
time of collision = end of step
xscoll = collision pt = position of SRD at time of collision
+ xbcoll = position of wall at time of collision
norm = surface normal of collision pt at time of collision
------------------------------------------------------------------------- */
@@ -1760,54 +2108,18 @@ void FixSRD::collision_wall_inexact(double *xs, int iwall, double *xscoll,
}
/* ----------------------------------------------------------------------
- SLIP collision with sphere
- vs = velocity of SRD, vb = velocity of BIG
- norm = unit normal from surface of BIG at collision pt
- v of BIG particle in direction of surf normal is added to v of SRD
- return vsnew of SRD
-------------------------------------------------------------------------- */
-
-void FixSRD::slip_sphere(double *vs, double *vb, double *norm, double *vsnew)
-{
- double r1,r2,vnmag,vs_dot_n,vsurf_dot_n;
- double tangent[3];
-
- while (1) {
- r1 = sigma * random->gaussian();
- r2 = sigma * random->gaussian();
- vnmag = sqrt(r1*r1 + r2*r2);
- if (vnmag*vnmag <= vmaxsq) break;
- }
-
- vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
-
- tangent[0] = vs[0] - vs_dot_n*norm[0];
- tangent[1] = vs[1] - vs_dot_n*norm[1];
- tangent[2] = vs[2] - vs_dot_n*norm[2];
-
- // vsurf = velocity of collision pt = translation/rotation of BIG particle
- // for sphere, only vb (translation) can contribute in normal direction
-
- vsurf_dot_n = vb[0]*norm[0] + vb[1]*norm[1] + vb[2]*norm[2];
-
- vsnew[0] = (vnmag+vsurf_dot_n)*norm[0] + tangent[0];
- vsnew[1] = (vnmag+vsurf_dot_n)*norm[1] + tangent[1];
- vsnew[2] = (vnmag+vsurf_dot_n)*norm[2] + tangent[2];
-}
-
-/* ----------------------------------------------------------------------
- SLIP collision with ellipsoid
+ SLIP collision with BIG particle with omega
vs = velocity of SRD, vb = velocity of BIG
xb = position of BIG, omega = rotation of BIG
xsurf = collision pt on surf of BIG
norm = unit normal from surface of BIG at collision pt
v of BIG particle in direction of surf normal is added to v of SRD
- includes component due to rotation of ellipsoid
+ includes component due to rotation of BIG
return vsnew of SRD
------------------------------------------------------------------------- */
-void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big,
- double *xsurf, double *norm, double *vsnew)
+void FixSRD::slip(double *vs, double *vb, double *xb, Big *big,
+ double *xsurf, double *norm, double *vsnew)
{
double r1,r2,vnmag,vs_dot_n,vsurf_dot_n;
double tangent[3],vsurf[3];
@@ -1827,6 +2139,8 @@ void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big,
tangent[2] = vs[2] - vs_dot_n*norm[2];
// vsurf = velocity of collision pt = translation/rotation of BIG particle
+ // NOTE: for sphere could just use vsurf = vb, since w x (xsurf-xb)
+ // is orthogonal to norm and thus doesn't contribute to vsurf_dot_n
vsurf[0] = vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]);
vsurf[1] = vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]);
@@ -1887,7 +2201,7 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew)
}
/* ----------------------------------------------------------------------
- NO-SLIP collision with sphere or ellipsoid
+ NO-SLIP collision with BIG particle including WALL
vs = velocity of SRD, vb = velocity of BIG
xb = position of BIG, omega = rotation of BIG
xsurf = collision pt on surf of BIG
@@ -1897,12 +2211,11 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew)
return vsnew of SRD
------------------------------------------------------------------------- */
-void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big,
+void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, int iwall,
double *xsurf, double *norm, double *vsnew)
{
double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2;
double tangent1[3],tangent2[3];
- double *omega = big->omega;
vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
@@ -1932,60 +2245,20 @@ void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big,
vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1];
vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2];
- // add in velocity of collision pt = translation/rotation of BIG particle
+ // add in velocity of collision pt
+ // for WALL: velocity of wall in one dim
+ // else: translation/rotation of BIG particle
- vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]);
- vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]);
- vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]);
-}
+ if (big->type == WALL) {
+ int dim = wallwhich[iwall] / 2;
+ vsnew[dim] += vwall[iwall];
-/* ----------------------------------------------------------------------
- NO-SLIP collision with wall IWALL
- vs = velocity of SRD
- xsurf = collision pt on surf of WALL
- norm = unit normal from WALL at collision pt
- v of collision pt is added to v of SRD
- return vsnew of SRD
-------------------------------------------------------------------------- */
-
-void FixSRD::noslip_wall(double *vs, int iwall,
- double *xsurf, double *norm, double *vsnew)
-{
- double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2;
- double tangent1[3],tangent2[3];
-
- vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
-
- tangent1[0] = vs[0] - vs_dot_n*norm[0];
- tangent1[1] = vs[1] - vs_dot_n*norm[1];
- tangent1[2] = vs[2] - vs_dot_n*norm[2];
- scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] +
- tangent1[2]*tangent1[2]);
- tangent1[0] *= scale;
- tangent1[1] *= scale;
- tangent1[2] *= scale;
-
- tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1];
- tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2];
- tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0];
-
- while (1) {
- r1 = sigma * random->gaussian();
- r2 = sigma * random->gaussian();
- vnmag = sqrt(r1*r1 + r2*r2);
- vtmag1 = sigma * random->gaussian();
- vtmag2 = sigma * random->gaussian();
- if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break;
+ } else {
+ double *omega = big->omega;
+ vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]);
+ vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]);
+ vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]);
}
-
- vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0];
- vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1];
- vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2];
-
- // add in velocity of collision pt = velocity of wall
-
- int dim = wallwhich[iwall] / 2;
- vsnew[dim] += vwall[iwall];
}
/* ----------------------------------------------------------------------
@@ -2027,6 +2300,7 @@ void FixSRD::force_torque(double *vsold, double *vsnew,
------------------------------------------------------------------------- */
void FixSRD::force_wall(double *vsold, double *vsnew, int iwall)
+
{
double dpdt[3];
@@ -2100,12 +2374,20 @@ void FixSRD::parameterize()
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double *radius = atom->radius;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
int *mask = atom->mask;
int nlocal = atom->nlocal;
- any_ellipsoids = 0;
+ int any_ellipsoids = 0;
+ int any_lines = 0;
+ int any_tris = 0;
maxbigdiam = 0.0;
minbigdiam = BIG;
@@ -2123,6 +2405,20 @@ void FixSRD::parameterize()
minbigdiam = MIN(minbigdiam,2.0*shape[0]);
minbigdiam = MIN(minbigdiam,2.0*shape[1]);
minbigdiam = MIN(minbigdiam,2.0*shape[2]);
+ } else if (line && line[i] >= 0) {
+ any_lines = 1;
+ double length = lbonus[line[i]].length;
+ maxbigdiam = MAX(maxbigdiam,length);
+ minbigdiam = MIN(minbigdiam,length);
+ } else if (tri && tri[i] >= 0) {
+ any_tris = 1;
+ double length1 = MathExtra::len3(tbonus[tri[i]].c1);
+ double length2 = MathExtra::len3(tbonus[tri[i]].c2);
+ double length3 = MathExtra::len3(tbonus[tri[i]].c3);
+ double length = MAX(length1,length2);
+ length = MAX(length,length3);
+ maxbigdiam = MAX(maxbigdiam,length);
+ minbigdiam = MIN(minbigdiam,length);
} else
error->one(FLERR,"Big particle in fix srd cannot be point particle");
}
@@ -2137,10 +2433,20 @@ void FixSRD::parameterize()
int itmp = any_ellipsoids;
MPI_Allreduce(&itmp,&any_ellipsoids,1,MPI_INT,MPI_MAX,world);
+ itmp = any_lines;
+ MPI_Allreduce(&itmp,&any_lines,1,MPI_INT,MPI_MAX,world);
+ itmp = any_tris;
+ MPI_Allreduce(&itmp,&any_tris,1,MPI_INT,MPI_MAX,world);
- // big particles are only torqued if are ellipsoids or NOSLIP collisions
+ if (any_lines && overlap == 0)
+ error->all(FLERR,"Cannot use lines with fix srd unless overlap is set");
+ if (any_tris && overlap == 0)
+ error->all(FLERR,"Cannot use tris with fix srd unless overlap is set");
- if (any_ellipsoids == 0 && collidestyle == SLIP) torqueflag = 0;
+ // big particles are only torqued if ellipsoids/lines/tris or NOSLIP
+
+ if (any_ellipsoids == 0 && any_lines == 0 && any_tris == 0 &&
+ collidestyle == SLIP) torqueflag = 0;
else torqueflag = 1;
// mass of SRD particles, require monodispersity
@@ -2186,28 +2492,46 @@ void FixSRD::parameterize()
vmaxsq = vmax*vmax;
// volbig = total volume of all big particles
+ // LINE/TRI particles have no volume
+ // incorrect if part of rigid particles, so add fudge factor with WIDTH
// apply radfactor to reduce final volume
double volbig = 0.0;
+ double WIDTH = 1.0;
if (dimension == 3) {
for (int i = 0; i < nlocal; i++)
if (mask[i] & biggroupbit) {
- if (radius && radius[i] > 0.0)
- volbig += 4.0/3.0*MY_PI*radius[i]*radius[i]*radius[i];
- else if (ellipsoid && ellipsoid[i] >= 0) {
+ if (radius && radius[i] > 0.0) {
+ double r = radfactor * radius[i];
+ volbig += 4.0/3.0*MY_PI * r*r*r;;
+ } else if (ellipsoid && ellipsoid[i] >= 0) {
double *shape = ebonus[ellipsoid[i]].shape;
- volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2];
+ volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2] *
+ radfactor*radfactor*radfactor;
+ } else if (tri && tri[i] >= 0) {
+ double *c1 = tbonus[tri[i]].c1;
+ double *c2 = tbonus[tri[i]].c2;
+ double *c3 = tbonus[tri[i]].c3;
+ double c2mc1[3],c3mc1[3],cross[3];
+ MathExtra::sub3(c2,c1,c2mc1);
+ MathExtra::sub3(c3,c1,c3mc1);
+ MathExtra::cross3(c2mc1,c3mc1,cross);
+ volbig += 0.5 * MathExtra::len3(cross);
}
}
} else {
for (int i = 0; i < nlocal; i++)
if (mask[i] & biggroupbit) {
- if (radius && radius[i] > 0.0)
- volbig += MY_PI*radius[i]*radius[i];
- else if (ellipsoid && ellipsoid[i] >= 0) {
+ if (radius && radius[i] > 0.0) {
+ double r = radfactor * radius[i];
+ volbig += MY_PI * r*r;
+ } else if (ellipsoid && ellipsoid[i] >= 0) {
double *shape = ebonus[ellipsoid[i]].shape;
- volbig += MY_PI*shape[0]*shape[1];
+ volbig += MY_PI * shape[0]*shape[1] * radfactor*radfactor;
+ } else if (line && line[i] >= 0) {
+ double length = lbonus[line[i]].length;
+ volbig += length * WIDTH;
}
}
}
@@ -2215,9 +2539,6 @@ void FixSRD::parameterize()
tmp = volbig;
MPI_Allreduce(&tmp,&volbig,1,MPI_DOUBLE,MPI_SUM,world);
- if (dimension == 3) volbig *= radfactor*radfactor*radfactor;
- else volbig *= radfactor*radfactor;
-
// particle counts
bigint mbig = 0;
@@ -2228,7 +2549,10 @@ void FixSRD::parameterize()
mass_big = 0.0;
for (int i = 0; i < nlocal; i++)
- if (mask[i] & biggroupbit) mass_big += rmass[i];
+ if (mask[i] & biggroupbit) {
+ if (rmass) mass_big += rmass[i];
+ else mass_big += mass[type[i]];
+ }
tmp = mass_big;
MPI_Allreduce(&tmp,&mass_big,1,MPI_DOUBLE,MPI_SUM,world);
@@ -2369,7 +2693,8 @@ void FixSRD::parameterize()
if (cubicflag == CUBIC_ERROR)
error->all(FLERR,"SRD bin size for fix srd differs from user request");
if (me == 0)
- error->warning(FLERR,"SRD bin size for fix srd differs from user request");
+ error->warning(FLERR,
+ "SRD bin size for fix srd differs from user request");
}
// error if lamda < 0.6 of SRD grid size and no shifting allowed
@@ -2400,30 +2725,46 @@ void FixSRD::parameterize()
/* ----------------------------------------------------------------------
set static parameters of each big particle, owned and ghost
called each reneighboring
- use radfactor in distance parameters
+ use radfactor in distance parameters as appropriate
------------------------------------------------------------------------- */
void FixSRD::big_static()
{
int i;
- double rad,arad,brad,crad;
- double *shape;
+ double rad,arad,brad,crad,length,length1,length2,length3;
+ double *shape,*c1,*c2,*c3;
+ double c2mc1[3],c3mc1[3];
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double *radius = atom->radius;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
+ int *type = atom->type;
double skinhalf = 0.5 * neighbor->skin;
for (int k = 0; k < nbig; k++) {
i = biglist[k].index;
+
+ // sphere
+ // set radius and radsq and cutoff based on radius
+
if (radius && radius[i] > 0.0) {
biglist[k].type = SPHERE;
rad = radfactor*radius[i];
biglist[k].radius = rad;
biglist[k].radsq = rad*rad;
biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
+
+ // ellipsoid
+ // set abc radsqinv and cutoff based on max radius
+
} else if (ellipsoid && ellipsoid[i] >= 0) {
shape = ebonus[ellipsoid[i]].shape;
biglist[k].type = ELLIPSOID;
@@ -2436,33 +2777,67 @@ void FixSRD::big_static()
rad = MAX(arad,brad);
rad = MAX(rad,crad);
biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
+
+ // line
+ // set length and cutoff based on 1/2 length
+
+ } else if (line && line[i] >= 0) {
+ length = lbonus[line[i]].length;
+ biglist[k].type = LINE;
+ biglist[k].length = length;
+ rad = 0.5*length;
+ biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
+
+ // tri
+ // set normbody based on c1,c2,c3
+ // set cutoff based on point furthest from centroid
+
+ } else if (tri && tri[i] >= 0) {
+ biglist[k].type = TRIANGLE;
+ c1 = tbonus[tri[i]].c1;
+ c2 = tbonus[tri[i]].c2;
+ c3 = tbonus[tri[i]].c3;
+ MathExtra::sub3(c2,c1,c2mc1);
+ MathExtra::sub3(c3,c1,c3mc1);
+ MathExtra::cross3(c2mc1,c3mc1,biglist[k].normbody);
+ length1 = MathExtra::len3(c1);
+ length2 = MathExtra::len3(c2);
+ length3 = MathExtra::len3(c3);
+ rad = MAX(length1,length2);
+ rad = MAX(rad,length3);
+ biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
}
}
}
/* ----------------------------------------------------------------------
- set dynamics parameters of each big particle, owned and ghost
- for ELLIPSOID, need current omega and ex,ey,ez
- for SPHERE, need current omega from atom->omega or atom->angmom
+ set dynamic parameters of each big particle, owned and ghost
called each timestep
------------------------------------------------------------------------- */
void FixSRD::big_dynamic()
{
int i;
- double *shape,*quat;
+ double *shape,*quat,*inertia;
+ double inertiaone[3];
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double **omega = atom->omega;
double **angmom = atom->angmom;
double *rmass = atom->rmass;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
for (int k = 0; k < nbig; k++) {
i = biglist[k].index;
- // sphere with omega
+ // sphere
// set omega from atom->omega directly
if (biglist[k].type == SPHERE) {
@@ -2470,15 +2845,45 @@ void FixSRD::big_dynamic()
biglist[k].omega[1] = omega[i][1];
biglist[k].omega[2] = omega[i][2];
- // ellipsoid with angmom
- // calculate ex,ey,ez and omega from quaternion and angmom
+ // ellipsoid
+ // set ex,ey,ez from quaternion
+ // set omega from angmom & ex,ey,ez
} else if (biglist[k].type == ELLIPSOID) {
- shape = ebonus[ellipsoid[i]].shape;
quat = ebonus[ellipsoid[i]].quat;
- exyz_from_q(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez);
- omega_from_mq(angmom[i],biglist[k].ex,biglist[k].ey,biglist[k].ez,
- rmass[i],shape,biglist[k].omega);
+ MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez);
+ shape = ebonus[ellipsoid[i]].shape;
+ inertiaone[0] = EINERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]);
+ inertiaone[1] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]);
+ inertiaone[2] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]);
+ MathExtra::angmom_to_omega(angmom[i],
+ biglist[k].ex,biglist[k].ey,biglist[k].ez,
+ inertiaone,biglist[k].omega);
+
+ // line
+ // set omega from atom->omega directly
+
+ } else if (biglist[k].type == LINE) {
+ biglist[k].theta = lbonus[line[i]].theta;
+ biglist[k].omega[0] = omega[i][0];
+ biglist[k].omega[1] = omega[i][1];
+ biglist[k].omega[2] = omega[i][2];
+
+ // tri
+ // set ex,ey,ez from quaternion
+ // set omega from angmom & ex,ey,ez
+ // set unit space-frame norm from body-frame norm
+
+ } else if (biglist[k].type == TRIANGLE) {
+ quat = tbonus[tri[i]].quat;
+ MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez);
+ inertia = tbonus[tri[i]].inertia;
+ MathExtra::angmom_to_omega(angmom[i],
+ biglist[k].ex,biglist[k].ey,biglist[k].ez,
+ inertia,biglist[k].omega);
+ MathExtra::matvec(biglist[k].ex,biglist[k].ey,biglist[k].ez,
+ biglist[k].normbody,biglist[k].norm);
+ MathExtra::norm3(biglist[k].norm);
}
}
}
@@ -2967,10 +3372,10 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic)
for (m = 0; m < nsend; m++) vbin[sendlist[m]].owner = 0;
}
- // if triclinic and streamflag:
- // set xctr (in lamda units) for all nbins so can compute bin vstream
+ // if tstat and deformflag:
+ // set xctr for all nbins in lamda units so can later compute vstream of bin
- if (triclinic && streamflag) {
+ if (tstat && deformflag) {
m = 0;
for (k = 0; k < nbinz; k++)
for (j = 0; j < nbiny; j++)
@@ -3182,55 +3587,6 @@ double FixSRD::bin_bin_distance(int i, int j, int k)
return (delx*delx + dely*dely + delz*delz);
}
-/* ----------------------------------------------------------------------
- compute space-frame ex,ey,ez from current quaternion q
- ex,ey,ez = space-frame coords of 1st,2nd,3rd principal axis
- operation is ex = q' d q = Q d, where d is (1,0,0) = 1st axis in body frame
-------------------------------------------------------------------------- */
-
-void FixSRD::exyz_from_q(double *q, double *ex, double *ey, double *ez)
-{
- ex[0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
- ex[1] = 2.0 * (q[1]*q[2] + q[0]*q[3]);
- ex[2] = 2.0 * (q[1]*q[3] - q[0]*q[2]);
-
- ey[0] = 2.0 * (q[1]*q[2] - q[0]*q[3]);
- ey[1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
- ey[2] = 2.0 * (q[2]*q[3] + q[0]*q[1]);
-
- ez[0] = 2.0 * (q[1]*q[3] + q[0]*q[2]);
- ez[1] = 2.0 * (q[2]*q[3] - q[0]*q[1]);
- ez[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
-}
-
-/* ----------------------------------------------------------------------
- compute omega from angular momentum
- w = omega = angular velocity in space frame
- wbody = angular velocity in body frame
- set wbody component to 0.0 if inertia component is 0.0
- otherwise body can spin easily around that axis
- project space-frame angular momentum onto body axes
- and divide by principal moments
-------------------------------------------------------------------------- */
-
-void FixSRD::omega_from_mq(double *m, double *ex, double *ey, double *ez,
- double mass, double *shape, double *w)
-{
- double inertia[3],wbody[3];
-
- inertia[0] = 0.2*mass * (shape[1]*shape[1]+shape[2]*shape[2]);
- inertia[1] = 0.2*mass * (shape[0]*shape[0]+shape[2]*shape[2]);
- inertia[2] = 0.2*mass * (shape[0]*shape[0]+shape[1]*shape[1]);
-
- wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0];
- wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1];
- wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / inertia[2];
-
- w[0] = wbody[0]*ex[0] + wbody[1]*ey[0] + wbody[2]*ez[0];
- w[1] = wbody[0]*ex[1] + wbody[1]*ey[1] + wbody[2]*ez[1];
- w[2] = wbody[0]*ex[2] + wbody[1]*ey[2] + wbody[2]*ez[2];
-}
-
/* ---------------------------------------------------------------------- */
int FixSRD::pack_reverse_comm(int n, int first, double *buf)
@@ -3365,6 +3721,90 @@ void FixSRD::velocity_stats(int groupnum)
/* ---------------------------------------------------------------------- */
+double FixSRD::newton_raphson(double t1, double t2)
+{
+ double f1,f2,df,tlo,thi;
+ lineside(t1,f1,df);
+ if (f1 < 0.0) {
+ tlo = t1;
+ thi = t2;
+ } else {
+ thi = t1;
+ tlo = t2;
+ }
+
+ double f;
+ double t = 0.5*(t1+t2);
+ double dtold = fabs(t2-t1);
+ double dt = dtold;
+ lineside(t,f,df);
+
+ double temp;
+ for (int i = 0; i < MAXITER; i++) {
+ if ((((t-thi)*df - f)*((t-tlo)*df - f) > 0.0) ||
+ (fabs(2.0*f) > fabs(dtold*df))) {
+ dtold = dt;
+ dt = 0.5 * (thi-tlo);
+ t = tlo + dt;
+ if (tlo == t) return t;
+ } else {
+ dtold = dt;
+ dt = f / df;
+ temp = t;
+ t -= dt;
+ if (temp == t) return t;
+ }
+ if (fabs(dt) < TOLERANCE) return t;
+ lineside(t,f,df);
+ if (f < 0.0) tlo = t;
+ else thi = t;
+ }
+
+ return t;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixSRD::lineside(double t, double &f, double &df)
+{
+ double p[2],c[2];
+
+ p[0] = xs0[0] + (xs1[0]-xs0[0])*t;
+ p[1] = xs0[1] + (xs1[1]-xs0[1])*t;
+ c[0] = xb0[0] + (xb1[0]-xb0[0])*t;
+ c[1] = xb0[1] + (xb1[1]-xb0[1])*t;
+ double dtheta = theta1 - theta0;
+ double theta = theta0 + dtheta*t;
+ double cosT = cos(theta);
+ double sinT = sin(theta);
+
+ f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT;
+ df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta -
+ ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixSRD::triside(double t, double &f, double &df)
+{
+ double p[2],c[2];
+
+ p[0] = xs0[0] + (xs1[0]-xs0[0])*t;
+ p[1] = xs0[1] + (xs1[1]-xs0[1])*t;
+ c[0] = xb0[0] + (xb1[0]-xb0[0])*t;
+ c[1] = xb0[1] + (xb1[1]-xb0[1])*t;
+ double dtheta = theta1 - theta0;
+ double theta = theta0 + dtheta*t;
+ double cosT = cos(theta);
+ double sinT = sin(theta);
+
+ f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT;
+ df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta -
+ ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta;
+}
+
+/* ---------------------------------------------------------------------- */
+
double FixSRD::memory_usage()
{
double bytes = 0.0;
diff --git a/src/SRD/fix_srd.h b/src/SRD/fix_srd.h
index 8552078e6d..43d9f7c2e3 100644
--- a/src/SRD/fix_srd.h
+++ b/src/SRD/fix_srd.h
@@ -43,9 +43,9 @@ class FixSRD : public Fix {
int me,nprocs;
int bigexist,biggroup,biggroupbit;
int collidestyle,lamdaflag,overlap,insideflag,exactflag,maxbounceallow;
- int cubicflag,shiftuser,shiftseed,shiftflag,streamflag;
+ int cubicflag,shiftuser,shiftseed,shiftflag,tstat;
double gridsrd,gridsearch,lamda,radfactor,cubictol;
- int triclinic,change_size,change_shape;
+ int triclinic,change_size,change_shape,deformflag;
double dt_big,dt_srd;
double mass_big,mass_srd;
@@ -64,6 +64,8 @@ class FixSRD : public Fix {
double walltrigger;
class AtomVecEllipsoid *avec_ellipsoid;
+ class AtomVecLine *avec_line;
+ class AtomVecTri *avec_tri;
// for orthogonal box, these are in box units
// for triclinic box, these are in lamda units
@@ -92,18 +94,21 @@ class FixSRD : public Fix {
struct Big {
int index; // local index of particle/wall
- int type; // SPHERE or ELLIPSOID or WALL
+ int type; // SPHERE or ELLIPSOID or LINE or TRI or WALL
double radius,radsq; // radius of sphere
double aradsqinv; // 3 ellipsoid radii
double bradsqinv;
double cradsqinv;
+ double length; // length of line segment
+ double normbody[3]; // normal of tri in body-frame
double cutbinsq; // add big to bin if within this distance
- double omega[3]; // current omega for sphere or ellipsoid
- double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid
+ double omega[3]; // current omega for sphere/ellipsoid/tri/line
+ double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid/tri
+ double norm[3]; // current unit normal of tri in space-frame
+ double theta; // current orientation of line
};
Big *biglist; // list of info for each owned & ghost big and wall
- int any_ellipsoids; // 1 if any big particles are ellipsoids
int torqueflag; // 1 if any big particle is torqued
// current size of particle-based arrays
@@ -123,7 +128,7 @@ class FixSRD : public Fix {
int owner; // 1 if I am owner of this bin, 0 if not
int n; // # of SRD particles in bin
double xctr[3]; // center point of bin, only used for triclinic
- double vave[3]; // sum of v components for SRD particles in bin
+ double vsum[3]; // sum of v components for SRD particles in bin
double random; // random value if I am owner
};
@@ -167,6 +172,17 @@ class FixSRD : public Fix {
int maxstencil; // max # of bins stencil array can hold
int **stencil; // list of 3d bin offsets a big particle can overlap
+ // persistent data for line/tri collision calculations
+
+ double tfraction,theta0,theta1;
+ double xs0[3],xs1[3],xsc[3];
+ double xb0[3],xb1[3],xbc[3];
+ double nbc[3];
+
+ // shared data for triangle collision calculations
+
+ // private functions
+
void reset_velocities();
void vbin_comm(int);
void vbin_pack(BinAve *, int, int *, double *);
@@ -177,6 +193,8 @@ class FixSRD : public Fix {
int inside_sphere(double *, double *, Big *);
int inside_ellipsoid(double *, double *, Big *);
+ int inside_line(double *, double *, double *, double *, Big *, double);
+ int inside_tri(double *, double *, double *, double *, Big *, double);
int inside_wall(double *, int);
double collision_sphere_exact(double *, double *, double *, double *,
@@ -187,18 +205,19 @@ class FixSRD : public Fix {
Big *, double *, double *, double *);
void collision_ellipsoid_inexact(double *, double *,
Big *, double *, double *, double *);
+ double collision_line_exact(double *, double *, double *, double *,
+ Big *, double, double *, double *, double *);
+ double collision_tri_exact(double *, double *, double *, double *,
+ Big *, double, double *, double *, double *);
double collision_wall_exact(double *, int, double *,
double *, double *, double *);
void collision_wall_inexact(double *, int, double *, double *, double *);
- void slip_sphere(double *, double *, double *, double *);
- void slip_ellipsoid(double *, double *, double *, Big *,
- double *, double *, double *);
+ void slip(double *, double *, double *, Big *,
+ double *, double *, double *);
void slip_wall(double *, int, double *, double *);
-
- void noslip(double *, double *, double *, Big *,
+ void noslip(double *, double *, double *, Big *, int,
double *, double *, double *);
- void noslip_wall(double *, int, double *, double *, double *);
void force_torque(double *, double *, double *,
double *, double *, double *);
@@ -217,11 +236,12 @@ class FixSRD : public Fix {
double point_bin_distance(double *, int, int, int);
double bin_bin_distance(int, int, int);
- void exyz_from_q(double *, double *, double *, double *);
- void omega_from_mq(double *, double *, double *, double *,
- double, double *, double *);
void velocity_stats(int);
+ double newton_raphson(double, double);
+ void lineside(double, double &, double &);
+ void triside(double, double &, double &);
+
double distance(int, int);
void print_collision(int, int, int, double, double,
double *, double *, double *, int);
diff --git a/src/atom.cpp b/src/atom.cpp
index f42b1250f1..023d7a173f 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -75,7 +75,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
radius = rmass = NULL;
vfrac = s0 = NULL;
x0 = NULL;
- ellipsoid = NULL;
+ ellipsoid = line = tri = NULL;
spin = NULL;
eradius = ervel = erforce = NULL;
cs = csforce = vforce = ervelforce = NULL;
@@ -106,7 +106,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
// initialize atom style and array existence flags
// customize by adding new flag
- sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0;
+ sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0;
+ peri_flag = electron_flag = 0;
wavepacket_flag = sph_flag = 0;
molecule_flag = q_flag = mu_flag = 0;
@@ -185,6 +186,8 @@ Atom::~Atom()
memory->destroy(s0);
memory->destroy(x0);
memory->destroy(ellipsoid);
+ memory->destroy(line);
+ memory->destroy(tri);
memory->destroy(spin);
memory->destroy(eradius);
memory->destroy(ervel);
@@ -259,8 +262,9 @@ void Atom::create_avec(const char *style, int narg, char **arg, char *suffix)
// may have been set by old avec
// customize by adding new flag
- sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0;
-
+ sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0;
+ peri_flag = electron_flag = 0;
+
molecule_flag = q_flag = mu_flag = 0;
rmass_flag = radius_flag = omega_flag = torque_flag = angmom_flag = 0;
vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0;
diff --git a/src/atom.h b/src/atom.h
index 98b687ec9a..429aacb1c2 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -51,7 +51,7 @@ class Atom : protected Pointers {
double **omega,**angmom,**torque;
double *radius,*rmass,*vfrac,*s0;
double **x0;
- int *ellipsoid;
+ int *ellipsoid,*line,*tri;
int *spin;
double *eradius,*ervel,*erforce,*ervelforce;
double *cs,*csforce,*vforce;
@@ -84,7 +84,7 @@ class Atom : protected Pointers {
// atom style and per-atom array existence flags
// customize by adding new flag
- int sphere_flag,ellipsoid_flag,peri_flag,electron_flag;
+ int sphere_flag,ellipsoid_flag,line_flag,tri_flag,peri_flag,electron_flag;
int wavepacket_flag,sph_flag;
int molecule_flag,q_flag,mu_flag;
diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp
index f7605d5552..80efd8a5bf 100644
--- a/src/compute_property_atom.cpp
+++ b/src/compute_property_atom.cpp
@@ -11,10 +11,14 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
+#include "math.h"
#include "string.h"
#include "compute_property_atom.h"
+#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "update.h"
#include "domain.h"
#include "memory.h"
@@ -173,39 +177,39 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
pack_choice[i] = &ComputePropertyAtom::pack_angmomz;
} else if (strcmp(arg[iarg],"shapex") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapex;
} else if (strcmp(arg[iarg],"shapey") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapey;
} else if (strcmp(arg[iarg],"shapez") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapez;
} else if (strcmp(arg[iarg],"quatw") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatw;
} else if (strcmp(arg[iarg],"quati") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quati;
} else if (strcmp(arg[iarg],"quatj") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatj;
} else if (strcmp(arg[iarg],"quatk") == 0) {
- avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- if (!avec) error->all(FLERR,"Compute property/atom for "
- "atom property that isn't allocated");
+ avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatk;
} else if (strcmp(arg[iarg],"tqx") == 0) {
if (!atom->torque_flag)
@@ -244,6 +248,83 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_erforce;
+ } else if (strcmp(arg[iarg],"end1x") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end1x;
+ } else if (strcmp(arg[iarg],"end1y") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end1y;
+ } else if (strcmp(arg[iarg],"end1z") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end1z;
+ } else if (strcmp(arg[iarg],"end2x") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end2x;
+ } else if (strcmp(arg[iarg],"end2y") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end2y;
+ } else if (strcmp(arg[iarg],"end2z") == 0) {
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ if (!avec_line) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_end2z;
+
+ } else if (strcmp(arg[iarg],"corner1x") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner1x;
+ } else if (strcmp(arg[iarg],"corner1y") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner1y;
+ } else if (strcmp(arg[iarg],"corner1z") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner1z;
+ } else if (strcmp(arg[iarg],"corner2x") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner2x;
+ } else if (strcmp(arg[iarg],"corner2y") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner2y;
+ } else if (strcmp(arg[iarg],"corner2z") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner2z;
+ } else if (strcmp(arg[iarg],"corner3x") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner3x;
+ } else if (strcmp(arg[iarg],"corner3y") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner3y;
+ } else if (strcmp(arg[iarg],"corner3z") == 0) {
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
+ if (!avec_tri) error->all(FLERR,"Compute property/atom for "
+ "atom property that isn't allocated");
+ pack_choice[i] = &ComputePropertyAtom::pack_corner3z;
+
} else error->all(FLERR,"Invalid keyword in compute property/atom command");
}
@@ -994,7 +1075,7 @@ void ComputePropertyAtom::pack_angmomz(int n)
void ComputePropertyAtom::pack_shapex(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1011,7 +1092,7 @@ void ComputePropertyAtom::pack_shapex(int n)
void ComputePropertyAtom::pack_shapey(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1028,7 +1109,7 @@ void ComputePropertyAtom::pack_shapey(int n)
void ComputePropertyAtom::pack_shapez(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1045,7 +1126,7 @@ void ComputePropertyAtom::pack_shapez(int n)
void ComputePropertyAtom::pack_quatw(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1062,7 +1143,7 @@ void ComputePropertyAtom::pack_quatw(int n)
void ComputePropertyAtom::pack_quati(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1079,7 +1160,7 @@ void ComputePropertyAtom::pack_quati(int n)
void ComputePropertyAtom::pack_quatj(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1096,7 +1177,7 @@ void ComputePropertyAtom::pack_quatj(int n)
void ComputePropertyAtom::pack_quatk(int n)
{
- AtomVecEllipsoid::Bonus *bonus = avec->bonus;
+ AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
@@ -1213,3 +1294,294 @@ void ComputePropertyAtom::pack_erforce(int n)
n += nvalues;
}
}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end1x(int n)
+{
+ AtomVecLine::Bonus *bonus = avec_line->bonus;
+ int *line = atom->line;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && line[i] >= 0)
+ buf[n] = x[i][0] - 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta);
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end1y(int n)
+{
+ AtomVecLine::Bonus *bonus = avec_line->bonus;
+ int *line = atom->line;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && line[i] >= 0)
+ buf[n] = x[i][1] - 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta);
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end1z(int n)
+{
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) buf[n] = x[i][2];
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end2x(int n)
+{
+ AtomVecLine::Bonus *bonus = avec_line->bonus;
+ int *line = atom->line;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && line[i] >= 0)
+ buf[n] = x[i][0] + 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta);
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end2y(int n)
+{
+ AtomVecLine::Bonus *bonus = avec_line->bonus;
+ int *line = atom->line;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && line[i] >= 0)
+ buf[n] = x[i][1] + 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta);
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_end2z(int n)
+{
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) buf[n] = x[i][2];
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner1x(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,c);
+ buf[n] = x[i][0] + c[0];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner1y(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,c);
+ buf[n] = x[i][1] + c[1];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner1z(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,c);
+ buf[n] = x[i][2] + c[2];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner2x(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c2,c);
+ buf[n] = x[i][0] + c[0];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner2y(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c2,c);
+ buf[n] = x[i][1] + c[1];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner2z(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c2,c);
+ buf[n] = x[i][2] + c[2];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner3x(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c3,c);
+ buf[n] = x[i][0] + c[0];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner3y(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c3,c);
+ buf[n] = x[i][1] + c[1];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputePropertyAtom::pack_corner3z(int n)
+{
+ AtomVecTri::Bonus *bonus = avec_tri->bonus;
+ int *tri = atom->tri;
+ double **x = atom->x;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double p[3][3],c[3];
+ for (int i = 0; i < nlocal; i++) {
+ if ((mask[i] & groupbit) && tri[i] >= 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c3,c);
+ buf[n] = x[i][2] + c[2];
+ } else buf[n] = 0.0;
+ n += nvalues;
+ }
+}
diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h
index b32d0a93df..8f675b6204 100644
--- a/src/compute_property_atom.h
+++ b/src/compute_property_atom.h
@@ -38,7 +38,9 @@ class ComputePropertyAtom : public Compute {
double *vector;
double **array;
double *buf;
- class AtomVecEllipsoid *avec;
+ class AtomVecEllipsoid *avec_ellipsoid;
+ class AtomVecLine *avec_line;
+ class AtomVecTri *avec_tri;
typedef void (ComputePropertyAtom::*FnPtrPack)(int);
FnPtrPack *pack_choice; // ptrs to pack functions
@@ -101,6 +103,21 @@ class ComputePropertyAtom : public Compute {
void pack_eradius(int);
void pack_ervel(int);
void pack_erforce(int);
+ void pack_end1x(int);
+ void pack_end1y(int);
+ void pack_end1z(int);
+ void pack_end2x(int);
+ void pack_end2y(int);
+ void pack_end2z(int);
+ void pack_corner1x(int);
+ void pack_corner1y(int);
+ void pack_corner1z(int);
+ void pack_corner2x(int);
+ void pack_corner2y(int);
+ void pack_corner2z(int);
+ void pack_corner3x(int);
+ void pack_corner3y(int);
+ void pack_corner3z(int);
};
}
diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp
index cf63dfa116..63df87b782 100644
--- a/src/fix_rigid.cpp
+++ b/src/fix_rigid.cpp
@@ -19,6 +19,8 @@
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "domain.h"
#include "update.h"
#include "respa.h"
@@ -28,14 +30,20 @@
#include "random_mars.h"
#include "force.h"
#include "output.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
#define TOLERANCE 1.0e-6
#define EPSILON 1.0e-7
+#define SINERTIA 0.4 // moment of inertia prefactor for sphere
+#define EINERTIA 0.4 // moment of inertia prefactor for ellipsoid
+#define LINERTIA (1.0/12.0) // moment of inertia prefactor for line segment
+
/* ---------------------------------------------------------------------- */
FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
@@ -56,12 +64,12 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
// perform initial allocation of atom-based arrays
// register with Atom class
- extended = dorientflag = qorientflag = 0;
+ extended = orientflag = dorientflag = 0;
body = NULL;
displace = NULL;
eflags = NULL;
+ orient = NULL;
dorient = NULL;
- qorient = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
@@ -278,7 +286,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
else error->all(FLERR,"Illegal fix rigid command");
if (domain->dimension == 2 && (xflag == 1.0 || yflag == 1.0))
- error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation");
+ error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation");
int count = 0;
for (int m = mlo; m <= mhi; m++) {
@@ -384,18 +392,24 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
// bitmasks for properties of extended particles
- INERTIA_POINT = 1;
- INERTIA_SPHERE = 2;
- INERTIA_ELLIPSOID = 4;
- ORIENT_DIPOLE = 8;
- ORIENT_QUAT = 16;
- OMEGA = 32;
- ANGMOM = 64;
- TORQUE = 128;
+ POINT = 1;
+ SPHERE = 2;
+ ELLIPSOID = 4;
+ LINE = 8;
+ TRIANGLE = 16;
+ DIPOLE = 32;
+ OMEGA = 64;
+ ANGMOM = 128;
+ TORQUE = 256;
+
+ MINUSPI = -MY_PI;
+ TWOPI = 2.0*MY_PI;
// atom style pointers to particles that store extra info
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
// print statistics
@@ -423,8 +437,8 @@ FixRigid::~FixRigid()
memory->destroy(body);
memory->destroy(displace);
memory->destroy(eflags);
+ memory->destroy(orient);
memory->destroy(dorient);
- memory->destroy(qorient);
// delete nbody-length arrays
@@ -469,7 +483,7 @@ int FixRigid::setmask()
void FixRigid::init()
{
- int i,ibody;
+ int i,itype,ibody;
triclinic = domain->triclinic;
@@ -504,24 +518,33 @@ void FixRigid::init()
// extended = 1 if any particle in a rigid body is finite size
// or has a dipole moment
- extended = dorientflag = qorientflag = 0;
+ extended = orientflag = dorientflag = 0;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double **mu = atom->mu;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
int *type = atom->type;
int nlocal = atom->nlocal;
- if (atom->radius_flag || atom->ellipsoid_flag || atom->mu_flag) {
+ if (atom->radius_flag || atom->ellipsoid_flag || atom->line_flag ||
+ atom->tri_flag || atom->mu_flag) {
int flag = 0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
if (radius && radius[i] > 0.0) flag = 1;
if (ellipsoid && ellipsoid[i] >= 0) flag = 1;
+ if (line && line[i] >= 0) flag = 1;
+ if (tri && tri[i] >= 0) flag = 1;
if (mu && mu[i][3] > 0.0) flag = 1;
}
@@ -529,35 +552,45 @@ void FixRigid::init()
}
// grow extended arrays and set extended flags for each particle
- // qorientflag = 1 if any particle stores quat orientation
+ // orientflag = 4 if any particle stores ellipsoid or tri orientation
+ // orientflag = 1 if any particle stores line orientation
// dorientflag = 1 if any particle stores dipole orientation
if (extended) {
+ if (atom->ellipsoid_flag) orientflag = 4;
+ if (atom->line_flag) orientflag = 1;
+ if (atom->tri_flag) orientflag = 4;
if (atom->mu_flag) dorientflag = 1;
- if (atom->ellipsoid_flag) qorientflag = 1;
grow_arrays(atom->nmax);
for (i = 0; i < nlocal; i++) {
eflags[i] = 0;
if (body[i] < 0) continue;
- // set INERTIA to POINT or SPHERE or ELLIPSOID
+ // set to POINT or SPHERE or ELLIPSOID or LINE
if (radius && radius[i] > 0.0) {
- eflags[i] |= INERTIA_SPHERE;
+ eflags[i] |= SPHERE;
eflags[i] |= OMEGA;
eflags[i] |= TORQUE;
} else if (ellipsoid && ellipsoid[i] >= 0) {
- eflags[i] |= INERTIA_ELLIPSOID;
- eflags[i] |= ORIENT_QUAT;
+ eflags[i] |= ELLIPSOID;
eflags[i] |= ANGMOM;
eflags[i] |= TORQUE;
- } else eflags[i] |= INERTIA_POINT;
+ } else if (line && line[i] >= 0) {
+ eflags[i] |= LINE;
+ eflags[i] |= OMEGA;
+ eflags[i] |= TORQUE;
+ } else if (tri && tri[i] >= 0) {
+ eflags[i] |= TRIANGLE;
+ eflags[i] |= ANGMOM;
+ eflags[i] |= TORQUE;
+ } else eflags[i] |= POINT;
// set DIPOLE if atom->mu and mu[3] > 0.0
if (atom->mu_flag && mu[i][3] > 0.0)
- eflags[i] |= ORIENT_DIPOLE;
+ eflags[i] |= DIPOLE;
}
}
@@ -592,8 +625,8 @@ void FixRigid::init()
if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) ||
(zbox && !periodicity[2]))
- error->one(FLERR,"Fix rigid atom has non-zero image flag "
- "in a non-periodic dimension");
+ error->one(FLERR,"Fix rigid atom has non-zero image flag "
+ "in a non-periodic dimension");
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
@@ -629,7 +662,7 @@ void FixRigid::init()
// dx,dy,dz = coords relative to center-of-mass
// symmetric 3x3 inertia tensor stored in Voigt notation as 6-vector
- double dx,dy,dz;
+ double dx,dy,dz,rad;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
@@ -671,18 +704,19 @@ void FixRigid::init()
if (extended) {
double ivec[6];
- double *shape,*quatatom;
+ double *shape,*quatatom,*inertiaatom;
+ double length,theta;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
massone = rmass[i];
- if (eflags[i] & INERTIA_SPHERE) {
- sum[ibody][0] += 0.4 * massone * radius[i]*radius[i];
- sum[ibody][1] += 0.4 * massone * radius[i]*radius[i];
- sum[ibody][2] += 0.4 * massone * radius[i]*radius[i];
- } else if (eflags[i] & INERTIA_ELLIPSOID) {
+ if (eflags[i] & SPHERE) {
+ sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i];
+ sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i];
+ sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i];
+ } else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
MathExtra::inertia_ellipsoid(shape,quatatom,massone,ivec);
@@ -692,6 +726,26 @@ void FixRigid::init()
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
+ } else if (eflags[i] & LINE) {
+ length = lbonus[line[i]].length;
+ theta = lbonus[line[i]].theta;
+ MathExtra::inertia_line(length,theta,massone,ivec);
+ sum[ibody][0] += ivec[0];
+ sum[ibody][1] += ivec[1];
+ sum[ibody][2] += ivec[2];
+ sum[ibody][3] += ivec[3];
+ sum[ibody][4] += ivec[4];
+ sum[ibody][5] += ivec[5];
+ } else if (eflags[i] & TRIANGLE) {
+ inertiaatom = tbonus[tri[i]].inertia;
+ quatatom = tbonus[tri[i]].quat;
+ MathExtra::inertia_triangle(inertiaatom,quatatom,massone,ivec);
+ sum[ibody][0] += ivec[0];
+ sum[ibody][1] += ivec[1];
+ sum[ibody][2] += ivec[2];
+ sum[ibody][3] += ivec[3];
+ sum[ibody][4] += ivec[4];
+ sum[ibody][5] += ivec[5];
}
}
}
@@ -715,7 +769,8 @@ void FixRigid::init()
tensor[0][1] = tensor[1][0] = all[ibody][5];
ierror = MathExtra::jacobi(tensor,inertia[ibody],evectors);
- if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for rigid body");
+ if (ierror) error->all(FLERR,
+ "Insufficient Jacobi rotations for rigid body");
ex_space[ibody][0] = evectors[0][0];
ex_space[ibody][1] = evectors[1][0];
@@ -756,6 +811,7 @@ void FixRigid::init()
double qc[4],delta[3];
double *quatatom;
+ double theta_body;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) {
@@ -786,20 +842,34 @@ void FixRigid::init()
ez_space[ibody],delta,displace[i]);
if (extended) {
- if (eflags[i] & ORIENT_DIPOLE) {
+ if (eflags[i] & ELLIPSOID) {
+ quatatom = ebonus[ellipsoid[i]].quat;
+ MathExtra::qconjugate(quat[ibody],qc);
+ MathExtra::quatquat(qc,quatatom,orient[i]);
+ MathExtra::qnormalize(orient[i]);
+ } else if (eflags[i] & LINE) {
+ if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]);
+ else theta_body = -2.0*acos(quat[ibody][0]);
+ orient[i][0] = lbonus[line[i]].theta - theta_body;
+ while (orient[i][0] <= MINUSPI) orient[i][0] += TWOPI;
+ while (orient[i][0] > MY_PI) orient[i][0] -= TWOPI;
+ if (orientflag == 4) orient[i][1] = orient[i][2] = orient[i][3] = 0.0;
+ } else if (eflags[i] & TRIANGLE) {
+ quatatom = tbonus[tri[i]].quat;
+ MathExtra::qconjugate(quat[ibody],qc);
+ MathExtra::quatquat(qc,quatatom,orient[i]);
+ MathExtra::qnormalize(orient[i]);
+ } else if (orientflag == 4) {
+ orient[i][0] = orient[i][1] = orient[i][2] = orient[i][3] = 0.0;
+ } else if (orientflag == 1)
+ orient[i][0] = 0.0;
+
+ if (eflags[i] & DIPOLE) {
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],
ez_space[ibody],mu[i],dorient[i]);
MathExtra::snormalize3(mu[i][3],dorient[i],dorient[i]);
} else if (dorientflag)
dorient[i][0] = dorient[i][1] = dorient[i][2] = 0.0;
-
- if (eflags[i] & ORIENT_QUAT) {
- quatatom = ebonus[ellipsoid[i]].quat;
- MathExtra::qconjugate(quat[ibody],qc);
- MathExtra::quatquat(qc,quatatom,qorient[i]);
- MathExtra::qnormalize(qorient[i]);
- } else if (qorientflag)
- qorient[i][0] = qorient[i][1] = qorient[i][2] = qorient[i][3] = 0.0;
}
}
@@ -831,20 +901,39 @@ void FixRigid::init()
if (extended) {
double ivec[6];
- double *shape;
+ double *shape,*inertiaatom;
+ double length;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
massone = rmass[i];
- if (eflags[i] & INERTIA_SPHERE) {
- sum[ibody][0] += 0.4 * massone * radius[i]*radius[i];
- sum[ibody][1] += 0.4 * massone * radius[i]*radius[i];
- sum[ibody][2] += 0.4 * massone * radius[i]*radius[i];
- } else if (eflags[i] & INERTIA_ELLIPSOID) {
+ if (eflags[i] & SPHERE) {
+ sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i];
+ sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i];
+ sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i];
+ } else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
- MathExtra::inertia_ellipsoid(shape,qorient[i],massone,ivec);
+ MathExtra::inertia_ellipsoid(shape,orient[i],massone,ivec);
+ sum[ibody][0] += ivec[0];
+ sum[ibody][1] += ivec[1];
+ sum[ibody][2] += ivec[2];
+ sum[ibody][3] += ivec[3];
+ sum[ibody][4] += ivec[4];
+ sum[ibody][5] += ivec[5];
+ } else if (eflags[i] & LINE) {
+ length = lbonus[line[i]].length;
+ MathExtra::inertia_line(length,orient[i][0],massone,ivec);
+ sum[ibody][0] += ivec[0];
+ sum[ibody][1] += ivec[1];
+ sum[ibody][2] += ivec[2];
+ sum[ibody][3] += ivec[3];
+ sum[ibody][4] += ivec[4];
+ sum[ibody][5] += ivec[5];
+ } else if (eflags[i] & TRIANGLE) {
+ inertiaatom = tbonus[tri[i]].inertia;
+ MathExtra::inertia_triangle(inertiaatom,orient[i],massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
@@ -894,7 +983,8 @@ void FixRigid::init()
ndof += fflag[ibody][0] + fflag[ibody][1] + fflag[ibody][2];
ndof += tflag[ibody][0] + tflag[ibody][1] + tflag[ibody][2];
}
- tfactor = force->mvv2e / (ndof * force->boltz);
+ if (ndof > 0.0) tfactor = force->mvv2e / (ndof * force->boltz);
+ else tfactor = 0.0;
}
/* ---------------------------------------------------------------------- */
@@ -996,24 +1086,29 @@ void FixRigid::setup(int vflag)
// extended particles add their rotation/torque to angmom/torque of body
if (extended) {
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
double **torque_one = atom->torque;
double *radius = atom->radius;
+ int *line = atom->line;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & OMEGA) {
- if (rmass) massone = rmass[i];
- else massone = mass[type[i]];
- radone = radius[i];
- sum[ibody][0] += 0.4 * massone * radone*radone * omega_one[i][0];
- sum[ibody][1] += 0.4 * massone * radone*radone * omega_one[i][1];
- sum[ibody][2] += 0.4 * massone * radone*radone * omega_one[i][2];
+ if (eflags[i] & SPHERE) {
+ radone = radius[i];
+ sum[ibody][0] += SINERTIA*rmass[i] * radone*radone * omega_one[i][0];
+ sum[ibody][1] += SINERTIA*rmass[i] * radone*radone * omega_one[i][1];
+ sum[ibody][2] += SINERTIA*rmass[i] * radone*radone * omega_one[i][2];
+ } else if (eflags[i] & LINE) {
+ radone = lbonus[line[i]].length;
+ sum[ibody][2] += LINERTIA*rmass[i] * radone*radone * omega_one[i][2];
+ }
}
-
if (eflags[i] & ANGMOM) {
sum[ibody][0] += angmom_one[i][0];
sum[ibody][1] += angmom_one[i][1];
@@ -1516,7 +1611,7 @@ void FixRigid::deform(int flag)
void FixRigid::set_xv()
{
- int ibody;
+ int ibody,itype;
int xbox,ybox,zbox;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double xy,xz,yz;
@@ -1622,43 +1717,64 @@ void FixRigid::set_xv()
// set orientation, omega, angmom of each extended particle
if (extended) {
- double *shape,*quatatom;
+ double theta_body,theta;
+ double *shape,*quatatom,*inertiaatom;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecLine::Bonus *lbonus;
+ if (avec_line) lbonus = avec_line->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
double **mu = atom->mu;
int *ellipsoid = atom->ellipsoid;
+ int *line = atom->line;
+ int *tri = atom->tri;
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
-
- if (eflags[i] & ORIENT_DIPOLE) {
- MathExtra::quat_to_mat(quat[ibody],p);
- MathExtra::matvec(p,dorient[i],mu[i]);
- MathExtra::snormalize3(mu[i][3],mu[i],mu[i]);
- }
- if (eflags[i] & ORIENT_QUAT) {
- quatatom = ebonus[ellipsoid[i]].quat;
- MathExtra::quatquat(quat[ibody],qorient[i],quatatom);
- MathExtra::qnormalize(quatatom);
- }
- if (eflags[i] & OMEGA) {
+
+ if (eflags[i] & SPHERE) {
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
- }
- if (eflags[i] & ANGMOM) {
+ } else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
- ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
- ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
- ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
+ MathExtra::quatquat(quat[ibody],orient[i],quatatom);
+ MathExtra::qnormalize(quatatom);
+ ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
+ ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
+ ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione,
angmom_one[i]);
+ } else if (eflags[i] & LINE) {
+ if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]);
+ else theta_body = -2.0*acos(quat[ibody][0]);
+ theta = orient[i][0] + theta_body;
+ while (theta <= MINUSPI) theta += TWOPI;
+ while (theta > MY_PI) theta -= TWOPI;
+ lbonus[line[i]].theta = theta;
+ omega_one[i][0] = omega[ibody][0];
+ omega_one[i][1] = omega[ibody][1];
+ omega_one[i][2] = omega[ibody][2];
+ } else if (eflags[i] & TRIANGLE) {
+ inertiaatom = tbonus[tri[i]].inertia;
+ quatatom = tbonus[tri[i]].quat;
+ MathExtra::quatquat(quat[ibody],orient[i],quatatom);
+ MathExtra::qnormalize(quatatom);
+ MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
+ MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,
+ inertiaatom,angmom_one[i]);
+ }
+ if (eflags[i] & DIPOLE) {
+ MathExtra::quat_to_mat(quat[ibody],p);
+ MathExtra::matvec(p,dorient[i],mu[i]);
+ MathExtra::snormalize3(mu[i][3],mu[i],mu[i]);
}
}
}
@@ -1672,8 +1788,9 @@ void FixRigid::set_xv()
void FixRigid::set_v()
{
- int ibody;
+ int ibody,itype;
int xbox,ybox,zbox;
+ double dx,dy,dz;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double xy,xz,yz;
double ione[3],exone[3],eyone[3],ezone[3],delta[3],vr[6];
@@ -1761,32 +1878,44 @@ void FixRigid::set_v()
// set omega, angmom of each extended particle
if (extended) {
- double *shape,*quatatom;
+ double *shape,*quatatom,*inertiaatom;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
+ AtomVecTri::Bonus *tbonus;
+ if (avec_tri) tbonus = avec_tri->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
int *ellipsoid = atom->ellipsoid;
+ int *tri = atom->tri;
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
- if (eflags[i] & OMEGA) {
+ if (eflags[i] & SPHERE) {
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
- }
- if (eflags[i] & ANGMOM) {
+ } else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
- ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
- ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
- ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
+ ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
+ ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
+ ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione,
angmom_one[i]);
+ } else if (eflags[i] & LINE) {
+ omega_one[i][0] = omega[ibody][0];
+ omega_one[i][1] = omega[ibody][1];
+ omega_one[i][2] = omega[ibody][2];
+ } else if (eflags[i] & TRIANGLE) {
+ inertiaatom = tbonus[tri[i]].inertia;
+ quatatom = tbonus[tri[i]].quat;
+ MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
+ MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,
+ inertiaatom,angmom_one[i]);
}
}
}
@@ -1804,8 +1933,8 @@ double FixRigid::memory_usage()
bytes += maxvatom*6 * sizeof(double);
if (extended) {
bytes += nmax * sizeof(int);
+ if (orientflag) bytes = nmax*orientflag * sizeof(double);
if (dorientflag) bytes = nmax*3 * sizeof(double);
- if (qorientflag) bytes = nmax*4 * sizeof(double);
}
return bytes;
}
@@ -1820,8 +1949,8 @@ void FixRigid::grow_arrays(int nmax)
memory->grow(displace,nmax,3,"rigid:displace");
if (extended) {
memory->grow(eflags,nmax,"rigid:eflags");
+ if (orientflag) memory->grow(orient,nmax,orientflag,"rigid:orient");
if (dorientflag) memory->grow(dorient,nmax,3,"rigid:dorient");
- if (qorientflag) memory->grow(qorient,nmax,4,"rigid:qorient");
}
}
@@ -1837,17 +1966,13 @@ void FixRigid::copy_arrays(int i, int j)
displace[j][2] = displace[i][2];
if (extended) {
eflags[j] = eflags[i];
+ for (int k = 0; k < orientflag; k++)
+ orient[j][k] = orient[i][k];
if (dorientflag) {
dorient[j][0] = dorient[i][0];
dorient[j][1] = dorient[i][1];
dorient[j][2] = dorient[i][2];
}
- if (qorientflag) {
- qorient[j][0] = qorient[i][0];
- qorient[j][1] = qorient[i][1];
- qorient[j][2] = qorient[i][2];
- qorient[j][3] = qorient[i][3];
- }
}
}
@@ -1877,17 +2002,13 @@ int FixRigid::pack_exchange(int i, double *buf)
int m = 4;
buf[m++] = eflags[i];
+ for (int j = 0; j < orientflag; j++)
+ buf[m++] = orient[i][j];
if (dorientflag) {
buf[m++] = dorient[i][0];
buf[m++] = dorient[i][1];
buf[m++] = dorient[i][2];
}
- if (qorientflag) {
- buf[m++] = qorient[i][0];
- buf[m++] = qorient[i][1];
- buf[m++] = qorient[i][2];
- buf[m++] = qorient[i][3];
- }
return m;
}
@@ -1905,17 +2026,13 @@ int FixRigid::unpack_exchange(int nlocal, double *buf)
int m = 4;
eflags[nlocal] = static_cast (buf[m++]);
+ for (int j = 0; j < orientflag; j++)
+ orient[nlocal][j] = buf[m++];
if (dorientflag) {
dorient[nlocal][0] = buf[m++];
dorient[nlocal][1] = buf[m++];
dorient[nlocal][2] = buf[m++];
}
- if (qorientflag) {
- qorient[nlocal][0] = buf[m++];
- qorient[nlocal][1] = buf[m++];
- qorient[nlocal][2] = buf[m++];
- qorient[nlocal][3] = buf[m++];
- }
return m;
}
diff --git a/src/fix_rigid.h b/src/fix_rigid.h
index 06121ad47a..fa803df5f7 100644
--- a/src/fix_rigid.h
+++ b/src/fix_rigid.h
@@ -56,6 +56,7 @@ class FixRigid : public Fix {
double dtv,dtf,dtq;
double *step_respa;
int triclinic;
+ double MINUSPI,TWOPI;
int nbody; // # of rigid bodies
int *nrigid; // # of atoms in each rigid body
@@ -82,11 +83,11 @@ class FixRigid : public Fix {
int **remapflag; // PBC remap flags for each rigid body
int extended; // 1 if any particles have extended attributes
+ int orientflag; // 1 if particles store spatial orientation
int dorientflag; // 1 if particles store dipole orientation
- int qorientflag; // 1 if particles store quat orientation
int *eflags; // flags for extended particles
- double **qorient; // rotation state of ext particle wrt rigid body
+ double **orient; // orientation vector of particle wrt rigid body
double **dorient; // orientation of dipole mu wrt rigid body
double tfactor; // scale factor on temperature of rigid bodies
@@ -104,10 +105,10 @@ class FixRigid : public Fix {
class RanMars *random;
class AtomVecEllipsoid *avec_ellipsoid;
+ class AtomVecLine *avec_line;
+ class AtomVecTri *avec_tri;
- // bitmasks for eflags
- int INERTIA_POINT,INERTIA_SPHERE,INERTIA_ELLIPSOID;
- int ORIENT_DIPOLE,ORIENT_QUAT;
+ int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags
int OMEGA,ANGMOM,TORQUE;
void no_squish_rotate(int, double *, double *, double *, double);
diff --git a/src/read_data.cpp b/src/read_data.cpp
index a5a5e47ccb..772c3a3824 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -21,6 +21,8 @@
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "comm.h"
#include "update.h"
#include "force.h"
@@ -42,7 +44,10 @@ using namespace LAMMPS_NS;
#define DELTA 4 // must be 2 or larger
// customize for new sections
-#define NSECTIONS 21 // change when add to header::section_keywords
+#define NSECTIONS 23 // change when add to header::section_keywords
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* ---------------------------------------------------------------------- */
@@ -60,6 +65,10 @@ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp)
nellipsoids = 0;
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ nlines = 0;
+ avec_line = (AtomVecLine *) atom->style_match("line");
+ ntris = 0;
+ avec_tri = (AtomVecTri *) atom->style_match("tri");
}
/* ---------------------------------------------------------------------- */
@@ -151,7 +160,17 @@ void ReadData::command(int narg, char **arg)
if (!avec_ellipsoid)
error->all(FLERR,"Invalid data file section: Ellipsoids");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
- ellipsoids();
+ bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
+ } else if (strcmp(keyword,"Lines") == 0) {
+ if (!avec_line)
+ error->all(FLERR,"Invalid data file section: Lines");
+ if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
+ bonus(nlines,(AtomVec *) avec_line,"lines");
+ } else if (strcmp(keyword,"Triangles") == 0) {
+ if (!avec_tri)
+ error->all(FLERR,"Invalid data file section: Triangles");
+ if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
+ bonus(ntris,(AtomVec *) avec_tri,"triangles");
} else if (strcmp(keyword,"Bonds") == 0) {
if (atom->avec->bonds_allow == 0)
@@ -222,25 +241,31 @@ void ReadData::command(int narg, char **arg)
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before "
+ "MiddleBondTorsion Coeffs");
dihedralcoeffs(1);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before EndBondTorsion Coeffs");
dihedralcoeffs(2);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before AngleTorsion Coeffs");
dihedralcoeffs(3);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before "
+ "AngleAngleTorsion Coeffs");
dihedralcoeffs(4);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
@@ -274,7 +299,8 @@ void ReadData::command(int narg, char **arg)
// error if natoms > 0 yet no atoms were read
- if (atom->natoms > 0 && atomflag == 0) error->all(FLERR,"No atoms in data file");
+ if (atom->natoms > 0 && atomflag == 0)
+ error->all(FLERR,"No atoms in data file");
// create bond topology now that system is defined
@@ -303,7 +329,7 @@ void ReadData::header(int flag)
// customize for new sections
char *section_keywords[NSECTIONS] =
- {"Atoms","Velocities","Ellipsoids",
+ {"Atoms","Velocities","Ellipsoids","Lines","Triangles",
"Bonds","Angles","Dihedrals","Impropers",
"Masses","Pair Coeffs","Bond Coeffs","Angle Coeffs",
"Dihedral Coeffs","Improper Coeffs",
@@ -373,6 +399,14 @@ void ReadData::header(int flag)
if (!avec_ellipsoid)
error->all(FLERR,"No ellipsoids allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nellipsoids);
+ } else if (strstr(line,"lines")) {
+ if (!avec_line)
+ error->all(FLERR,"No lines allowed with this atom style");
+ sscanf(line,BIGINT_FORMAT,&nlines);
+ } else if (strstr(line,"triangles")) {
+ if (!avec_tri)
+ error->all(FLERR,"No triangles allowed with this atom style");
+ sscanf(line,BIGINT_FORMAT,&ntris);
}
else if (strstr(line,"xlo xhi"))
@@ -475,7 +509,8 @@ void ReadData::atoms()
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
- if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly");
+ if (natoms != atom->natoms)
+ error->all(FLERR,"Did not assign all atoms correctly");
// if any atom ID < 0, error
// if all atom IDs = 0, tag_enable = 0
@@ -568,11 +603,11 @@ void ReadData::velocities()
}
/* ----------------------------------------------------------------------
- read all ellipsoids
+ read all bonus data
to find atoms, must build atom map if not a molecular system
------------------------------------------------------------------------- */
-void ReadData::ellipsoids()
+void ReadData::bonus(bigint nbonus, AtomVec *ptr, char *type)
{
int i,m,nchunk;
@@ -585,7 +620,7 @@ void ReadData::ellipsoids()
}
bigint nread = 0;
- bigint natoms = nellipsoids;
+ bigint natoms = nbonus;
while (nread < natoms) {
if (natoms-nread > CHUNK) nchunk = CHUNK;
@@ -603,7 +638,7 @@ void ReadData::ellipsoids()
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
- atom->data_bonus(nchunk,buffer,avec_ellipsoid);
+ atom->data_bonus(nchunk,buffer,ptr);
nread += nchunk;
}
@@ -613,8 +648,8 @@ void ReadData::ellipsoids()
}
if (me == 0) {
- if (screen) fprintf(screen," " BIGINT_FORMAT " ellipsoids\n",natoms);
- if (logfile) fprintf(logfile," " BIGINT_FORMAT " ellipsoids\n",natoms);
+ if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type);
+ if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type);
}
}
@@ -660,7 +695,8 @@ void ReadData::bonds()
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor);
}
- if (sum != factor*atom->nbonds) error->all(FLERR,"Bonds assigned incorrectly");
+ if (sum != factor*atom->nbonds)
+ error->all(FLERR,"Bonds assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
@@ -705,7 +741,8 @@ void ReadData::angles()
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor);
}
- if (sum != factor*atom->nangles) error->all(FLERR,"Angles assigned incorrectly");
+ if (sum != factor*atom->nangles)
+ error->all(FLERR,"Angles assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
@@ -1010,6 +1047,8 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
int natoms = static_cast (atom->natoms);
bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
int ellipsoid_flag = 0;
+ int line_flag = 0;
+ int tri_flag = 0;
// customize for new sections
// allocate topology counting vector
@@ -1031,6 +1070,14 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
error->all(FLERR,"Invalid data file section: Ellipsoids");
ellipsoid_flag = 1;
skip_lines(nellipsoids);
+ } else if (strcmp(keyword,"Lines") == 0) {
+ if (!avec_line) error->all(FLERR,"Invalid data file section: Lines");
+ line_flag = 1;
+ skip_lines(nlines);
+ } else if (strcmp(keyword,"Triangles") == 0) {
+ if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles");
+ tri_flag = 1;
+ skip_lines(ntris);
} else if (strcmp(keyword,"Pair Coeffs") == 0) {
if (force->pair == NULL)
@@ -1077,25 +1124,31 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before "
+ "MiddleBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before EndBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before AngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs");
+ error->all(FLERR,
+ "Must define dihedral_style before "
+ "AngleAngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
@@ -1252,6 +1305,10 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
if (nellipsoids && !ellipsoid_flag)
error->one(FLERR,"Needed bonus data not in data file");
+ if (nlines && !line_flag)
+ error->one(FLERR,"Needed bonus data not in data file");
+ if (ntris && !tri_flag)
+ error->one(FLERR,"Needed bonus data not in data file");
}
/* ----------------------------------------------------------------------
diff --git a/src/read_data.h b/src/read_data.h
index 80fd441413..67398469c5 100644
--- a/src/read_data.h
+++ b/src/read_data.h
@@ -40,6 +40,10 @@ class ReadData : protected Pointers {
bigint nellipsoids;
class AtomVecEllipsoid *avec_ellipsoid;
+ bigint nlines;
+ class AtomVecLine *avec_line;
+ bigint ntris;
+ class AtomVecTri *avec_tri;
void open(char *);
void scan(int &, int &, int &, int &);
@@ -51,7 +55,7 @@ class ReadData : protected Pointers {
void atoms();
void velocities();
- void ellipsoids();
+ void bonus(bigint, class AtomVec *, char *);
void bonds();
void angles();
diff --git a/src/set.cpp b/src/set.cpp
index 4e76dfa2b4..2a4c25731b 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -19,6 +19,8 @@
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
+#include "atom_vec_line.h"
+#include "atom_vec_tri.h"
#include "domain.h"
#include "region.h"
#include "group.h"
@@ -35,8 +37,8 @@ using namespace LAMMPS_NS;
using namespace MathConst;
enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT};
-enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,
- DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,
+enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI,
+ DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,ANGMOM,
DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER,
MESO_E,MESO_CV,MESO_RHO};
@@ -150,6 +152,22 @@ void Set::command(int narg, char **arg)
}
set(SHAPE);
iarg += 4;
+ } else if (strcmp(arg[iarg],"length") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
+ dvalue = atof(arg[iarg+1]);
+ if (!atom->line_flag)
+ error->all(FLERR,"Cannot set this attribute for this atom style");
+ if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command");
+ set(LENGTH);
+ iarg += 2;
+ } else if (strcmp(arg[iarg],"tri") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
+ dvalue = atof(arg[iarg+1]);
+ if (!atom->tri_flag)
+ error->all(FLERR,"Cannot set this attribute for this atom style");
+ if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command");
+ set(TRI);
+ iarg += 2;
} else if (strcmp(arg[iarg],"dipole") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
xvalue = atof(arg[iarg+1]);
@@ -177,19 +195,36 @@ void Set::command(int narg, char **arg)
yvalue = atof(arg[iarg+2]);
zvalue = atof(arg[iarg+3]);
wvalue = atof(arg[iarg+4]);
- if (!atom->ellipsoid_flag)
+ if (!atom->ellipsoid_flag && !atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(QUAT);
iarg += 5;
} else if (strcmp(arg[iarg],"quat/random") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
- if (!atom->ellipsoid_flag)
+ if (!atom->ellipsoid_flag && !atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0)
error->all(FLERR,"Invalid random number seed in set command");
setrandom(QUAT_RANDOM);
iarg += 2;
+ } else if (strcmp(arg[iarg],"theta") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
+ dvalue = atof(arg[iarg+1]);
+ dvalue *= MY_PI/180.0;
+ if (!atom->line_flag)
+ error->all(FLERR,"Cannot set this attribute for this atom style");
+ set(THETA);
+ iarg += 2;
+ } else if (strcmp(arg[iarg],"angmom") == 0) {
+ if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
+ xvalue = atof(arg[iarg+1]);
+ yvalue = atof(arg[iarg+2]);
+ zvalue = atof(arg[iarg+3]);
+ if (!atom->ellipsoid_flag && !atom->tri_flag)
+ error->all(FLERR,"Cannot set this attribute for this atom style");
+ set(ANGMOM);
+ iarg += 4;
} else if (strcmp(arg[iarg],"diameter") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
@@ -385,6 +420,8 @@ void Set::set(int keyword)
{
AtomVecEllipsoid *avec_ellipsoid =
(AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line");
+ AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri");
selection(atom->nlocal);
@@ -405,23 +442,49 @@ void Set::set(int keyword)
else if (keyword == MESO_CV) atom->cv[i] = dvalue;
else if (keyword == MESO_RHO) atom->rho[i] = dvalue;
- // set shape
+ // set shape of ellipsoidal particle
else if (keyword == SHAPE)
avec_ellipsoid->set_shape(i,0.5*xvalue,0.5*yvalue,0.5*zvalue);
+ // set length of line particle
+
+ else if (keyword == LENGTH)
+ avec_line->set_length(i,dvalue);
+
+ // set corners of tri particle
+
+ else if (keyword == TRI)
+ avec_tri->set_equilateral(i,dvalue);
+
// set rmass via density
// if radius > 0.0, treat as sphere
// if shape > 0.0, treat as ellipsoid
+ // if length > 0.0, treat as line
+ // if area > 0.0, treat as tri
// else set rmass to density directly
else if (keyword == DENSITY) {
if (atom->radius_flag && atom->radius[i] > 0.0)
- atom->rmass[i] = 4.0*MY_PI*THIRD *
+ atom->rmass[i] = 4.0*MY_PI/3.0 *
atom->radius[i]*atom->radius[i]*atom->radius[i] * dvalue;
else if (atom->ellipsoid_flag && atom->ellipsoid[i] >= 0) {
double *shape = avec_ellipsoid->bonus[atom->ellipsoid[i]].shape;
- atom->rmass[i] = 4.0*MY_PI*THIRD * shape[0]*shape[1]*shape[2] * dvalue;
+ atom->rmass[i] = 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2] * dvalue;
+ } else if (atom->line_flag && atom->line[i] >= 0) {
+ double length = avec_line->bonus[atom->line[i]].length;
+ atom->rmass[i] = length * dvalue;
+ } else if (atom->tri_flag && atom->tri[i] >= 0) {
+ double *c1 = avec_tri->bonus[atom->tri[i]].c1;
+ double *c2 = avec_tri->bonus[atom->tri[i]].c2;
+ double *c3 = avec_tri->bonus[atom->tri[i]].c3;
+ double c2mc1[2],c3mc1[3];
+ MathExtra::sub3(c2,c1,c2mc1);
+ MathExtra::sub3(c3,c1,c3mc1);
+ double norm[3];
+ MathExtra::cross3(c2mc1,c3mc1,norm);
+ double area = 0.5 * MathExtra::len3(norm);
+ atom->rmass[i] = area * dvalue;
} else atom->rmass[i] = dvalue;
// reset any or all of 3 image flags
@@ -446,13 +509,17 @@ void Set::set(int keyword)
mu[i][3] = sqrt(mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] +
mu[i][2]*mu[i][2]);
- // set quaternion orientation
+ // set quaternion orientation of ellipsoid or tri particle
} else if (keyword == QUAT) {
- if (atom->ellipsoid[i] < 0)
- error->one(FLERR,
- "Cannot set quaternion for atom that is not an ellipsoid");
- double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
+ double *quat;
+ if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
+ quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
+ else if (avec_tri && atom->tri[i] >= 0)
+ quat = avec_tri->bonus[atom->tri[i]].quat;
+ else
+ error->one(FLERR,"Cannot set quaternion for atom that has none");
+
double theta2 = MY_PI2 * wvalue/180.0;
double sintheta2 = sin(theta2);
quat[0] = cos(theta2);
@@ -460,7 +527,22 @@ void Set::set(int keyword)
quat[2] = yvalue * sintheta2;
quat[3] = zvalue * sintheta2;
MathExtra::qnormalize(quat);
+
+ // set theta of line particle
+
+ } else if (keyword == THETA) {
+ if (atom->line[i] < 0)
+ error->one(FLERR,"Cannot set theta for atom that is not a line");
+ avec_line->bonus[atom->line[i]].theta = dvalue;
+
+ // set angmom of ellipsoidal or tri particle
+
+ } else if (keyword == ANGMOM) {
+ atom->angmom[i][0] = xvalue;
+ atom->angmom[i][1] = yvalue;
+ atom->angmom[i][2] = zvalue;
}
+
count++;
}
}
@@ -475,6 +557,11 @@ void Set::setrandom(int keyword)
{
int i;
+ AtomVecEllipsoid *avec_ellipsoid =
+ (AtomVecEllipsoid *) atom->style_match("ellipsoid");
+ AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line");
+ AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri");
+
selection(atom->nlocal);
RanPark *random = new RanPark(lmp,1);
double **x = atom->x;
@@ -535,13 +622,10 @@ void Set::setrandom(int keyword)
}
// set quaternions to random orientations in 3d or 2d
- // no need to normalize quats since creations algorithms already do
} else if (keyword == QUAT_RANDOM) {
- AtomVecEllipsoid *avec_ellipsoid =
- (AtomVecEllipsoid *) atom->style_match("ellipsoid");
- AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
+ int *tri = atom->tri;
int nlocal = atom->nlocal;
double *quat;
@@ -549,10 +633,13 @@ void Set::setrandom(int keyword)
double s,t1,t2,theta1,theta2;
for (i = 0; i < nlocal; i++)
if (select[i]) {
- if (ellipsoid[i] < 0)
- error->one(FLERR,"Cannot set quaternion for atom "
- "that is not an ellipsoid");
- quat = bonus[ellipsoid[i]].quat;
+ if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
+ quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
+ else if (avec_tri && atom->tri[i] >= 0)
+ quat = avec_tri->bonus[atom->tri[i]].quat;
+ else
+ error->one(FLERR,"Cannot set quaternion for atom that has none");
+
random->reset(seed,x[i]);
s = random->uniform();
t1 = sqrt(1.0-s);
@@ -570,10 +657,11 @@ void Set::setrandom(int keyword)
double theta2;
for (i = 0; i < nlocal; i++)
if (select[i]) {
- if (ellipsoid[i] < 0)
- error->one(FLERR,"Cannot set quaternion for atom "
- "that is not an ellipsoid");
- quat = bonus[ellipsoid[i]].quat;
+ if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
+ quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
+ else
+ error->one(FLERR,"Cannot set quaternion for atom that has none");
+
random->reset(seed,x[i]);
theta2 = MY_PI*random->uniform();
quat[0] = cos(theta2);
From c6d228775fc0b5d9aa433893f38c3f6083d2db05 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 14:58:00 +0000
Subject: [PATCH 32/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7147
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/atom_vec_line.cpp | 1167 ++++++++++++++++++++++++++++++
src/atom_vec_line.h | 96 +++
src/atom_vec_tri.cpp | 1561 +++++++++++++++++++++++++++++++++++++++++
src/atom_vec_tri.h | 97 +++
4 files changed, 2921 insertions(+)
create mode 100644 src/atom_vec_line.cpp
create mode 100644 src/atom_vec_line.h
create mode 100644 src/atom_vec_tri.cpp
create mode 100644 src/atom_vec_tri.h
diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp
new file mode 100644
index 0000000000..ebf8b7d7a8
--- /dev/null
+++ b/src/atom_vec_line.cpp
@@ -0,0 +1,1167 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "math.h"
+#include "stdlib.h"
+#include "string.h"
+#include "atom_vec_line.h"
+#include "atom.h"
+#include "domain.h"
+#include "modify.h"
+#include "force.h"
+#include "fix.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 10000
+#define DELTA_BONUS 10000
+#define EPSILON 0.001
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecLine::AtomVecLine(LAMMPS *lmp, int narg, char **arg) :
+ AtomVec(lmp, narg, arg)
+{
+ molecular = 0;
+
+ comm_x_only = comm_f_only = 0;
+ size_forward = 4;
+ size_reverse = 6;
+ size_border = 10;
+ size_velocity = 6;
+ size_data_atom = 8;
+ size_data_vel = 7;
+ size_data_bonus = 5;
+ xcol_data = 6;
+
+ atom->line_flag = 1;
+ atom->molecule_flag = atom->rmass_flag = 1;
+ atom->omega_flag = atom->torque_flag = 1;
+
+ nlocal_bonus = nghost_bonus = nmax_bonus = 0;
+ bonus = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecLine::~AtomVecLine()
+{
+ memory->sfree(bonus);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::init()
+{
+ AtomVec::init();
+
+ if (domain->dimension != 2)
+ error->all(FLERR,"Atom_style line can only be used in 2d simulations");
+}
+
+/* ----------------------------------------------------------------------
+ grow atom arrays
+ n = 0 grows arrays by DELTA
+ n > 0 allocates arrays to size n
+------------------------------------------------------------------------- */
+
+void AtomVecLine::grow(int n)
+{
+ if (n == 0) nmax += DELTA;
+ else nmax = n;
+ atom->nmax = nmax;
+
+ tag = memory->grow(atom->tag,nmax,"atom:tag");
+ type = memory->grow(atom->type,nmax,"atom:type");
+ mask = memory->grow(atom->mask,nmax,"atom:mask");
+ image = memory->grow(atom->image,nmax,"atom:image");
+ x = memory->grow(atom->x,nmax,3,"atom:x");
+ v = memory->grow(atom->v,nmax,3,"atom:v");
+ f = memory->grow(atom->f,nmax,3,"atom:f");
+
+ molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
+ rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
+ omega = memory->grow(atom->omega,nmax,3,"atom:omega");
+ torque = memory->grow(atom->torque,nmax,3,"atom:torque");
+ line = memory->grow(atom->line,nmax,"atom:line");
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ----------------------------------------------------------------------
+ reset local array ptrs
+------------------------------------------------------------------------- */
+
+void AtomVecLine::grow_reset()
+{
+ tag = atom->tag; type = atom->type;
+ mask = atom->mask; image = atom->image;
+ x = atom->x; v = atom->v; f = atom->f;
+ molecule = atom->molecule; rmass = atom->rmass;
+ omega = atom->omega; torque = atom->torque;
+}
+
+/* ----------------------------------------------------------------------
+ grow bonus data structure
+------------------------------------------------------------------------- */
+
+void AtomVecLine::grow_bonus()
+{
+ nmax_bonus += DELTA_BONUS;
+ if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus),
+ "atom:bonus");
+}
+
+/* ----------------------------------------------------------------------
+ copy atom I info to atom J
+------------------------------------------------------------------------- */
+
+void AtomVecLine::copy(int i, int j, int delflag)
+{
+ 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];
+ rmass[j] = rmass[i];
+ omega[j][0] = omega[i][0];
+ omega[j][1] = omega[i][1];
+ omega[j][2] = omega[i][2];
+
+ // if delflag and atom J has bonus data, then delete it
+
+ if (delflag && line[j] >= 0) {
+ copy_bonus(nlocal_bonus-1,line[j]);
+ nlocal_bonus--;
+ }
+
+ // if atom I has bonus data and not deleting I, repoint I's bonus to J
+
+ if (line[i] >= 0 && i != j) bonus[line[i]].ilocal = j;
+ line[j] = line[i];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
+}
+
+/* ----------------------------------------------------------------------
+ copy bonus data from I to J, effectively deleting the J entry
+ insure index pointers between per-atom and bonus data are updated
+------------------------------------------------------------------------- */
+
+void AtomVecLine::copy_bonus(int i, int j)
+{
+ memcpy(&bonus[j],&bonus[i],sizeof(Bonus));
+ line[bonus[j].ilocal] = j;
+}
+
+/* ----------------------------------------------------------------------
+ clear ghost info in bonus data
+ called before ghosts are recommunicated in comm and irregular
+------------------------------------------------------------------------- */
+
+void AtomVecLine::clear_bonus()
+{
+ nghost_bonus = 0;
+}
+
+/* ----------------------------------------------------------------------
+ set length value in bonus data for particle I
+ oriented along x axis
+ this may create or delete entry in bonus data
+------------------------------------------------------------------------- */
+
+void AtomVecLine::set_length(int i, double value)
+{
+ if (line[i] < 0) {
+ if (value == 0.0) return;
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ bonus[nlocal_bonus].length = value;
+ bonus[nlocal_bonus].theta = 0.0;
+ bonus[nlocal_bonus].ilocal = i;
+ line[i] = nlocal_bonus++;
+ } else if (value == 0.0) {
+ copy_bonus(nlocal_bonus-1,line[i]);
+ nlocal_bonus--;
+ line[i] = -1;
+ } else bonus[line[i]].length = value;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_comm(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ }
+ }
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_comm_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ }
+ }
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_comm_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::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++];
+ if (line[i] >= 0) bonus[line[i]].theta = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::unpack_comm_vel(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++];
+ if (line[i] >= 0) bonus[line[i]].theta = buf[m++];
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ omega[i][0] = buf[m++];
+ omega[i][1] = buf[m++];
+ omega[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::unpack_comm_hybrid(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++)
+ if (line[i] >= 0) bonus[line[i]].theta = buf[m++];
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_reverse(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = f[i][0];
+ buf[m++] = f[i][1];
+ buf[m++] = f[i][2];
+ buf[m++] = torque[i][0];
+ buf[m++] = torque[i][1];
+ buf[m++] = torque[i][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_reverse_hybrid(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = torque[i][0];
+ buf[m++] = torque[i][1];
+ buf[m++] = torque[i][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::unpack_reverse(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ f[j][0] += buf[m++];
+ f[j][1] += buf[m++];
+ f[j][2] += buf[m++];
+ torque[j][0] += buf[m++];
+ torque[j][1] += buf[m++];
+ torque[j][2] += buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::unpack_reverse_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ torque[j][0] += buf[m++];
+ torque[j][1] += buf[m++];
+ torque[j][2] += buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_border(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_border_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ buf[m++] = omega[j][0];
+ buf[m++] = omega[j][1];
+ buf[m++] = omega[j][2];
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::pack_border_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = molecule[j];
+ if (line[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ buf[m++] = bonus[line[j]].length;
+ buf[m++] = bonus[line[j]].theta;
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::unpack_border(int n, int first, double *buf)
+{
+ int i,j,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++]);
+ line[i] = static_cast (buf[m++]);
+ if (line[i] == 0) line[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ bonus[j].length = buf[m++];
+ bonus[j].theta = buf[m++];
+ bonus[j].ilocal = i;
+ line[i] = j;
+ nghost_bonus++;
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecLine::unpack_border_vel(int n, int first, double *buf)
+{
+ int i,j,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++]);
+ line[i] = static_cast (buf[m++]);
+ if (line[i] == 0) line[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ bonus[j].length = buf[m++];
+ bonus[j].theta = buf[m++];
+ bonus[j].ilocal = i;
+ line[i] = j;
+ nghost_bonus++;
+ }
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ omega[i][0] = buf[m++];
+ omega[i][1] = buf[m++];
+ omega[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::unpack_border_hybrid(int n, int first, double *buf)
+{
+ int i,j,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ molecule[i] = static_cast (buf[m++]);
+ line[i] = static_cast (buf[m++]);
+ if (line[i] == 0) line[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ bonus[j].length = buf[m++];
+ bonus[j].theta = buf[m++];
+ bonus[j].ilocal = i;
+ line[i] = j;
+ nghost_bonus++;
+ }
+ }
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+------------------------------------------------------------------------- */
+
+int AtomVecLine::pack_exchange(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = tag[i];
+ buf[m++] = type[i];
+ buf[m++] = mask[i];
+ buf[m++] = image[i];
+
+ buf[m++] = molecule[i];
+ buf[m++] = rmass[i];
+ buf[m++] = omega[i][0];
+ buf[m++] = omega[i][1];
+ buf[m++] = omega[i][2];
+
+ if (line[i] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ int j = line[i];
+ buf[m++] = bonus[j].length;
+ buf[m++] = bonus[j].theta;
+ }
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecLine::unpack_exchange(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ tag[nlocal] = static_cast (buf[m++]);
+ type[nlocal] = static_cast (buf[m++]);
+ mask[nlocal] = static_cast (buf[m++]);
+ image[nlocal] = static_cast (buf[m++]);
+
+ molecule[nlocal] = static_cast (buf[m++]);
+ rmass[nlocal] = buf[m++];
+ omega[nlocal][0] = buf[m++];
+ omega[nlocal][1] = buf[m++];
+ omega[nlocal][2] = buf[m++];
+
+ line[nlocal] = static_cast (buf[m++]);
+ if (line[nlocal] == 0) line[nlocal] = -1;
+ else {
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ bonus[nlocal_bonus].length = buf[m++];
+ bonus[nlocal_bonus].theta = buf[m++];
+ bonus[nlocal_bonus].ilocal = nlocal;
+ line[nlocal] = nlocal_bonus++;
+ }
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->
+ unpack_exchange(nlocal,&buf[m]);
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+------------------------------------------------------------------------- */
+
+int AtomVecLine::size_restart()
+{
+ int i;
+
+ int n = 0;
+ int nlocal = atom->nlocal;
+ for (i = 0; i < nlocal; i++)
+ if (line[i] >= 0) n += 19;
+ else n += 17;
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ for (i = 0; i < nlocal; i++)
+ n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+ return n;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom I's data for restart file including extra quantities
+ xyz must be 1st 3 values, so that read_restart can test on them
+ molecular types may be negative, but write as positive
+------------------------------------------------------------------------- */
+
+int AtomVecLine::pack_restart(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = tag[i];
+ buf[m++] = type[i];
+ buf[m++] = mask[i];
+ buf[m++] = image[i];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+
+ buf[m++] = molecule[i];
+ buf[m++] = rmass[i];
+ buf[m++] = omega[i][0];
+ buf[m++] = omega[i][1];
+ buf[m++] = omega[i][2];
+
+ if (line[i] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ int j = line[i];
+ buf[m++] = bonus[j].length;
+ buf[m++] = bonus[j].theta;
+ }
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ unpack data for one atom from restart file including extra quantities
+------------------------------------------------------------------------- */
+
+int AtomVecLine::unpack_restart(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
+ }
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ tag[nlocal] = static_cast (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++]);
+ rmass[nlocal] = buf[m++];
+ omega[nlocal][0] = buf[m++];
+ omega[nlocal][1] = buf[m++];
+ omega[nlocal][2] = buf[m++];
+
+ line[nlocal] = static_cast (buf[m++]);
+ if (line[nlocal] == 0) line[nlocal] = -1;
+ else {
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ bonus[nlocal_bonus].length = buf[m++];
+ bonus[nlocal_bonus].theta = buf[m++];
+ bonus[nlocal_bonus].ilocal = nlocal;
+ line[nlocal] = nlocal_bonus++;
+ }
+
+ double **extra = atom->extra;
+ if (atom->nextra_store) {
+ int size = static_cast (buf[0]) - m;
+ for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+ }
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ create one atom of itype at coord
+ set other values to defaults
+------------------------------------------------------------------------- */
+
+void AtomVecLine::create_atom(int itype, double *coord)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = 0;
+ type[nlocal] = itype;
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+ mask[nlocal] = 1;
+ image[nlocal] = (512 << 20) | (512 << 10) | 512;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ molecule[nlocal] = 0;
+ rmass[nlocal] = 1.0;
+ omega[nlocal][0] = 0.0;
+ omega[nlocal][1] = 0.0;
+ omega[nlocal][2] = 0.0;
+ line[nlocal] = -1;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Atoms section of data file
+ initialize other atom quantities
+------------------------------------------------------------------------- */
+
+void AtomVecLine::data_atom(double *coord, int imagetmp, char **values)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = atoi(values[0]);
+ if (tag[nlocal] <= 0)
+ error->one(FLERR,"Invalid atom ID in Atoms section of data file");
+
+ molecule[nlocal] = atoi(values[1]);
+
+ type[nlocal] = atoi(values[2]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ line[nlocal] = atoi(values[3]);
+ if (line[nlocal] == 0) line[nlocal] = -1;
+ else if (line[nlocal] == 1) line[nlocal] = 0;
+ else error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ rmass[nlocal] = atof(values[4]);
+ if (rmass[nlocal] <= 0.0)
+ error->one(FLERR,"Invalid density in Atoms section of data file");
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+ omega[nlocal][0] = 0.0;
+ omega[nlocal][1] = 0.0;
+ omega[nlocal][2] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack hybrid quantities from one line in Atoms section of data file
+ initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecLine::data_atom_hybrid(int nlocal, char **values)
+{
+ molecule[nlocal] = atoi(values[0]);
+
+ line[nlocal] = atoi(values[1]);
+ if (line[nlocal] == 0) line[nlocal] = -1;
+ else if (line[nlocal] == 1) line[nlocal] = 0;
+ else error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ rmass[nlocal] = atof(values[2]);
+ if (rmass[nlocal] <= 0.0)
+ error->one(FLERR,"Invalid density in Atoms section of data file");
+
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Lines section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecLine::data_atom_bonus(int m, char **values)
+{
+ if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom");
+
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+
+ double x1 = atof(values[0]);
+ double y1 = atof(values[1]);
+ double x2 = atof(values[2]);
+ double y2 = atof(values[3]);
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+ double length = sqrt(dx*dx + dy*dy);
+
+ bonus[nlocal_bonus].length = length;
+ if (dy >= 0.0) bonus[nlocal_bonus].theta = acos(dx/length);
+ else bonus[nlocal_bonus].theta = -acos(dx/length);
+
+ double xc = 0.5*(x1+x2);
+ double yc = 0.5*(y1+y2);
+ dx = xc - x[m][0];
+ dy = yc - x[m][1];
+ double delta = sqrt(dx*dx + dy*dy);
+
+ if (delta/length > EPSILON)
+ error->one(FLERR,"Inconsistent line segment in data file");
+
+ x[m][0] = xc;
+ x[m][1] = yc;
+
+ // reset line mass
+ // previously stored density in rmass
+
+ rmass[m] *= length;
+
+ bonus[nlocal_bonus].ilocal = m;
+ line[m] = nlocal_bonus++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Velocities section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecLine::data_vel(int m, char **values)
+{
+ v[m][0] = atof(values[0]);
+ v[m][1] = atof(values[1]);
+ v[m][2] = atof(values[2]);
+ omega[m][0] = atof(values[3]);
+ omega[m][1] = atof(values[4]);
+ omega[m][2] = atof(values[5]);
+}
+
+/* ----------------------------------------------------------------------
+ unpack hybrid quantities from one line in Velocities section of data file
+------------------------------------------------------------------------- */
+
+int AtomVecLine::data_vel_hybrid(int m, char **values)
+{
+ omega[m][0] = atof(values[0]);
+ omega[m][1] = atof(values[1]);
+ omega[m][2] = atof(values[2]);
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ return # of bytes of allocated memory
+------------------------------------------------------------------------- */
+
+bigint AtomVecLine::memory_usage()
+{
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
+ if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
+ if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
+ if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
+ if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
+ if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
+ if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3);
+
+ if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
+ if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
+ if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3);
+ if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3);
+ if (atom->memcheck("line")) bytes += memory->usage(line,nmax);
+
+ bytes += nmax_bonus*sizeof(Bonus);
+
+ return bytes;
+}
+
+/* ----------------------------------------------------------------------
+ check consistency of internal Bonus data structure
+ n = # of atoms in regular structure to check against
+------------------------------------------------------------------------- */
+
+/*
+void AtomVecLine::consistency_check(int n, char *str)
+{
+ int iflag = 0;
+ int count = 0;
+ for (int i = 0; i < n; i++) {
+
+ if (line[i] >= 0) {
+ count++;
+ if (line[i] >= nlocal_bonus) iflag++;
+ if (bonus[line[i]].ilocal != i) iflag++;
+ //if (comm->me == 1 && update->ntimestep == 873)
+ // printf("CCHK %s: %d %d: %d %d: %d %d\n",
+ // str,i,n,line[i],nlocal_bonus,bonus[line[i]].ilocal,iflag);
+ }
+ }
+
+ if (iflag) {
+ char msg[128];
+ sprintf(msg,"BAD VECLINE PTRS: %s: %d %d: %d\n",str,comm->me,
+ update->ntimestep,iflag);
+ error->one(FLERR,msg);
+ }
+
+ if (count != nlocal_bonus) {
+ char msg[128];
+ sprintf(msg,"BAD VECLINE COUNT: %s: %d %d: %d %d\n",
+ str,comm->me,update->ntimestep,count,nlocal_bonus);
+ error->one(FLERR,msg);
+ }
+}
+*/
diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h
new file mode 100644
index 0000000000..3dd6d6e37c
--- /dev/null
+++ b/src/atom_vec_line.h
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef ATOM_CLASS
+
+AtomStyle(line,AtomVecLine)
+
+#else
+
+#ifndef LMP_ATOM_VEC_LINE_H
+#define LMP_ATOM_VEC_LINE_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecLine : public AtomVec {
+ public:
+ struct Bonus {
+ double length,theta;
+ int ilocal;
+ };
+ struct Bonus *bonus;
+
+ AtomVecLine(class LAMMPS *, int, char **);
+ ~AtomVecLine();
+ void init();
+ void grow(int);
+ void grow_reset();
+ void copy(int, int, int);
+ int pack_comm(int, int *, double *, int, int *);
+ int pack_comm_vel(int, int *, double *, int, int *);
+ int pack_comm_hybrid(int, int *, double *);
+ void unpack_comm(int, int, double *);
+ void unpack_comm_vel(int, int, double *);
+ int unpack_comm_hybrid(int, int, double *);
+ int pack_reverse(int, int, double *);
+ int pack_reverse_hybrid(int, int, double *);
+ void unpack_reverse(int, int *, double *);
+ int unpack_reverse_hybrid(int, int *, double *);
+ int pack_border(int, int *, double *, int, int *);
+ int pack_border_vel(int, int *, double *, int, int *);
+ int pack_border_hybrid(int, int *, double *);
+ void unpack_border(int, int, double *);
+ void unpack_border_vel(int, int, double *);
+ int unpack_border_hybrid(int, int, double *);
+ int pack_exchange(int, double *);
+ int unpack_exchange(double *);
+ int size_restart();
+ int pack_restart(int, double *);
+ int unpack_restart(double *);
+ void create_atom(int, double *);
+ void data_atom(double *, int, char **);
+ int data_atom_hybrid(int, char **);
+ void data_vel(int, char **);
+ int data_vel_hybrid(int, char **);
+ bigint memory_usage();
+
+ // manipulate Bonus data structure for extra atom info
+
+ void clear_bonus();
+ void data_atom_bonus(int, char **);
+
+ // unique to AtomVecLine
+
+ void set_length(int, double);
+
+ private:
+ int *tag,*type,*mask,*image;
+ double **x,**v,**f;
+ int *molecule;
+ double *rmass;
+ double **omega,**torque;
+ int *line;
+
+ int nlocal_bonus,nghost_bonus,nmax_bonus;
+
+ void grow_bonus();
+ void copy_bonus(int, int);
+ // void consistency_check(int, char *);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp
new file mode 100644
index 0000000000..03aed7aa65
--- /dev/null
+++ b/src/atom_vec_tri.cpp
@@ -0,0 +1,1561 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "math.h"
+#include "stdlib.h"
+#include "string.h"
+#include "atom_vec_tri.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "domain.h"
+#include "modify.h"
+#include "force.h"
+#include "fix.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 10000
+#define DELTA_BONUS 10000
+#define EPSILON 0.001
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecTri::AtomVecTri(LAMMPS *lmp, int narg, char **arg) :
+ AtomVec(lmp, narg, arg)
+{
+ molecular = 0;
+
+ comm_x_only = comm_f_only = 0;
+ size_forward = 7;
+ size_reverse = 6;
+ size_border = 24;
+ size_velocity = 6;
+ size_data_atom = 8;
+ size_data_vel = 7;
+ size_data_bonus = 10;
+ xcol_data = 6;
+
+ atom->tri_flag = 1;
+ atom->molecule_flag = atom->rmass_flag = 1;
+ atom->angmom_flag = atom->torque_flag = 1;
+
+ nlocal_bonus = nghost_bonus = nmax_bonus = 0;
+ bonus = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecTri::~AtomVecTri()
+{
+ memory->sfree(bonus);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::init()
+{
+ AtomVec::init();
+
+ if (domain->dimension != 3)
+ error->all(FLERR,"Atom_style tri can only be used in 3d simulations");
+}
+
+/* ----------------------------------------------------------------------
+ grow atom arrays
+ n = 0 grows arrays by DELTA
+ n > 0 allocates arrays to size n
+------------------------------------------------------------------------- */
+
+void AtomVecTri::grow(int n)
+{
+ if (n == 0) nmax += DELTA;
+ else nmax = n;
+ atom->nmax = nmax;
+
+ tag = memory->grow(atom->tag,nmax,"atom:tag");
+ type = memory->grow(atom->type,nmax,"atom:type");
+ mask = memory->grow(atom->mask,nmax,"atom:mask");
+ image = memory->grow(atom->image,nmax,"atom:image");
+ x = memory->grow(atom->x,nmax,3,"atom:x");
+ v = memory->grow(atom->v,nmax,3,"atom:v");
+ f = memory->grow(atom->f,nmax,3,"atom:f");
+
+ molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
+ rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
+ angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom");
+ torque = memory->grow(atom->torque,nmax,3,"atom:torque");
+ tri = memory->grow(atom->tri,nmax,"atom:tri");
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ----------------------------------------------------------------------
+ reset local array ptrs
+------------------------------------------------------------------------- */
+
+void AtomVecTri::grow_reset()
+{
+ tag = atom->tag; type = atom->type;
+ mask = atom->mask; image = atom->image;
+ x = atom->x; v = atom->v; f = atom->f;
+ molecule = atom->molecule; rmass = atom->rmass;
+ angmom = atom->angmom; torque = atom->torque;
+}
+
+/* ----------------------------------------------------------------------
+ grow bonus data structure
+------------------------------------------------------------------------- */
+
+void AtomVecTri::grow_bonus()
+{
+ nmax_bonus += DELTA_BONUS;
+ if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus),
+ "atom:bonus");
+}
+
+/* ----------------------------------------------------------------------
+ copy atom I info to atom J
+ if delflag and atom J has bonus data, then delete it
+------------------------------------------------------------------------- */
+
+void AtomVecTri::copy(int i, int j, int delflag)
+{
+ 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];
+ rmass[j] = rmass[i];
+ angmom[j][0] = angmom[i][0];
+ angmom[j][1] = angmom[i][1];
+ angmom[j][2] = angmom[i][2];
+
+ // if delflag and atom J has bonus data, then delete it
+
+ if (delflag && tri[j] >= 0) {
+ copy_bonus(nlocal_bonus-1,tri[j]);
+ nlocal_bonus--;
+ }
+
+ // if atom I has bonus data and not deleting I, repoint I's bonus to J
+
+ if (tri[i] >= 0 && i != j) bonus[tri[i]].ilocal = j;
+ tri[j] = tri[i];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
+}
+
+/* ----------------------------------------------------------------------
+ copy bonus data from I to J, effectively deleting the J entry
+ insure index pointers between per-atom and bonus data are updated
+------------------------------------------------------------------------- */
+
+void AtomVecTri::copy_bonus(int i, int j)
+{
+ memcpy(&bonus[j],&bonus[i],sizeof(Bonus));
+ tri[bonus[j].ilocal] = j;
+}
+
+/* ----------------------------------------------------------------------
+ clear ghost info in bonus data
+ called before ghosts are recommunicated in comm and irregular
+------------------------------------------------------------------------- */
+
+void AtomVecTri::clear_bonus()
+{
+ nghost_bonus = 0;
+}
+
+/* ----------------------------------------------------------------------
+ set equilateral tri of size in bonus data for particle I
+ oriented symmetrically in xy plane
+ this may create or delete entry in bonus data
+------------------------------------------------------------------------- */
+
+void AtomVecTri::set_equilateral(int i, double size)
+{
+ if (tri[i] < 0) {
+ if (size == 0.0) return;
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ double *quat = bonus[nlocal_bonus].quat;
+ double *c1 = bonus[nlocal_bonus].c1;
+ double *c2 = bonus[nlocal_bonus].c2;
+ double *c3 = bonus[nlocal_bonus].c3;
+ double *inertia = bonus[nlocal_bonus].inertia;
+ quat[0] = 1.0;
+ quat[1] = 0.0;
+ quat[2] = 0.0;
+ quat[3] = 0.0;
+ c1[0] = -size/2.0;
+ c1[1] = -sqrt(3.0)/2.0 * size / 3.0;
+ c1[2] = 0.0;
+ c2[0] = size/2.0;
+ c2[1] = -sqrt(3.0)/2.0 * size / 3.0;
+ c2[2] = 0.0;
+ c3[0] = 0.0;
+ c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0;
+ c3[2] = 0.0;
+ inertia[0] = sqrt(3.0)/96.0 * size*size*size*size;
+ inertia[1] = sqrt(3.0)/96.0 * size*size*size*size;
+ inertia[2] = sqrt(3.0)/48.0 * size*size*size*size;
+ bonus[nlocal_bonus].ilocal = i;
+ tri[i] = nlocal_bonus++;
+ } else if (size == 0.0) {
+ copy_bonus(nlocal_bonus-1,tri[i]);
+ nlocal_bonus--;
+ tri[i] = -1;
+ } else {
+ double *c1 = bonus[tri[i]].c1;
+ double *c2 = bonus[tri[i]].c2;
+ double *c3 = bonus[tri[i]].c3;
+ double *inertia = bonus[tri[i]].inertia;
+ c1[0] = -size/2.0;
+ c1[1] = -sqrt(3.0)/2.0 * size / 3.0;
+ c1[2] = 0.0;
+ c2[0] = size/2.0;
+ c2[1] = -sqrt(3.0)/2.0 * size / 3.0;
+ c2[2] = 0.0;
+ c3[0] = 0.0;
+ c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0;
+ c3[2] = 0.0;
+ inertia[0] = sqrt(3.0)/96.0 * size*size*size*size;
+ inertia[1] = sqrt(3.0)/96.0 * size*size*size*size;
+ inertia[2] = sqrt(3.0)/48.0 * size*size*size*size;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_comm(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+ double *quat;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ }
+ }
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_comm_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+ double *quat;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ }
+ }
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_comm_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+ double *quat;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ if (tri[j] >= 0) {
+ quat = bonus[tri[j]].quat;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::unpack_comm(int n, int first, double *buf)
+{
+ int i,m,last;
+ double *quat;
+
+ 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++];
+ if (tri[i] >= 0) {
+ quat = bonus[tri[i]].quat;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::unpack_comm_vel(int n, int first, double *buf)
+{
+ int i,m,last;
+ double *quat;
+
+ 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++];
+ if (tri[i] >= 0) {
+ quat = bonus[tri[i]].quat;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ }
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ angmom[i][0] = buf[m++];
+ angmom[i][1] = buf[m++];
+ angmom[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::unpack_comm_hybrid(int n, int first, double *buf)
+{
+ int i,m,last;
+ double *quat;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++)
+ if (tri[i] >= 0) {
+ quat = bonus[tri[i]].quat;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_reverse(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = f[i][0];
+ buf[m++] = f[i][1];
+ buf[m++] = f[i][2];
+ buf[m++] = torque[i][0];
+ buf[m++] = torque[i][1];
+ buf[m++] = torque[i][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_reverse_hybrid(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = torque[i][0];
+ buf[m++] = torque[i][1];
+ buf[m++] = torque[i][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::unpack_reverse(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ f[j][0] += buf[m++];
+ f[j][1] += buf[m++];
+ f[j][2] += buf[m++];
+ torque[j][0] += buf[m++];
+ torque[j][1] += buf[m++];
+ torque[j][2] += buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::unpack_reverse_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ torque[j][0] += buf[m++];
+ torque[j][1] += buf[m++];
+ torque[j][2] += buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_border(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_border_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = tag[j];
+ buf[m++] = type[j];
+ buf[m++] = mask[j];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ buf[m++] = angmom[j][0];
+ buf[m++] = angmom[j][1];
+ buf[m++] = angmom[j][2];
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::pack_border_hybrid(int n, int *list, double *buf)
+{
+ int i,j,m;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = molecule[j];
+ if (tri[j] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ quat = bonus[tri[j]].quat;
+ c1 = bonus[tri[j]].c1;
+ c2 = bonus[tri[j]].c2;
+ c3 = bonus[tri[j]].c3;
+ inertia = bonus[tri[j]].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::unpack_border(int n, int first, double *buf)
+{
+ int i,j,m,last;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ 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++]);
+ tri[i] = static_cast (buf[m++]);
+ if (tri[i] == 0) tri[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ quat = bonus[j].quat;
+ c1 = bonus[j].c1;
+ c2 = bonus[j].c2;
+ c3 = bonus[j].c3;
+ inertia = bonus[j].inertia;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ c1[0] = buf[m++];
+ c1[1] = buf[m++];
+ c1[2] = buf[m++];
+ c2[0] = buf[m++];
+ c2[1] = buf[m++];
+ c2[2] = buf[m++];
+ c3[0] = buf[m++];
+ c3[1] = buf[m++];
+ c3[2] = buf[m++];
+ inertia[0] = buf[m++];
+ inertia[1] = buf[m++];
+ inertia[2] = buf[m++];
+ bonus[j].ilocal = i;
+ tri[i] = j;
+ nghost_bonus++;
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTri::unpack_border_vel(int n, int first, double *buf)
+{
+ int i,j,m,last;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ 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++]);
+ tri[i] = static_cast (buf[m++]);
+ if (tri[i] == 0) tri[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ quat = bonus[j].quat;
+ c1 = bonus[j].c1;
+ c2 = bonus[j].c2;
+ c3 = bonus[j].c3;
+ inertia = bonus[j].inertia;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ c1[0] = buf[m++];
+ c1[1] = buf[m++];
+ c1[2] = buf[m++];
+ c2[0] = buf[m++];
+ c2[1] = buf[m++];
+ c2[2] = buf[m++];
+ c3[0] = buf[m++];
+ c3[1] = buf[m++];
+ c3[2] = buf[m++];
+ inertia[0] = buf[m++];
+ inertia[1] = buf[m++];
+ inertia[2] = buf[m++];
+ bonus[j].ilocal = i;
+ tri[i] = j;
+ nghost_bonus++;
+ }
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ angmom[i][0] = buf[m++];
+ angmom[i][1] = buf[m++];
+ angmom[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::unpack_border_hybrid(int n, int first, double *buf)
+{
+ int i,j,m,last;
+ double *quat,*c1,*c2,*c3,*inertia;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ molecule[i] = static_cast (buf[m++]);
+ tri[i] = static_cast (buf[m++]);
+ if (tri[i] == 0) tri[i] = -1;
+ else {
+ j = nlocal_bonus + nghost_bonus;
+ if (j == nmax_bonus) grow_bonus();
+ quat = bonus[j].quat;
+ c1 = bonus[j].c1;
+ c2 = bonus[j].c2;
+ c3 = bonus[j].c3;
+ inertia = bonus[j].inertia;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ c1[0] = buf[m++];
+ c1[1] = buf[m++];
+ c1[2] = buf[m++];
+ c2[0] = buf[m++];
+ c2[1] = buf[m++];
+ c2[2] = buf[m++];
+ c3[0] = buf[m++];
+ c3[1] = buf[m++];
+ c3[2] = buf[m++];
+ inertia[0] = buf[m++];
+ inertia[1] = buf[m++];
+ inertia[2] = buf[m++];
+ bonus[j].ilocal = i;
+ tri[i] = j;
+ nghost_bonus++;
+ }
+ }
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+------------------------------------------------------------------------- */
+
+int AtomVecTri::pack_exchange(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = tag[i];
+ buf[m++] = type[i];
+ buf[m++] = mask[i];
+ buf[m++] = image[i];
+
+ buf[m++] = molecule[i];
+ buf[m++] = rmass[i];
+ buf[m++] = angmom[i][0];
+ buf[m++] = angmom[i][1];
+ buf[m++] = angmom[i][2];
+
+ if (tri[i] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ int j = tri[i];
+ double *quat = bonus[j].quat;
+ double *c1 = bonus[j].c1;
+ double *c2 = bonus[j].c2;
+ double *c3 = bonus[j].c3;
+ double *inertia = bonus[j].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTri::unpack_exchange(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ tag[nlocal] = static_cast (buf[m++]);
+ type[nlocal] = static_cast (buf[m++]);
+ mask[nlocal] = static_cast (buf[m++]);
+ image[nlocal] = static_cast (buf[m++]);
+
+ molecule[nlocal] = static_cast (buf[m++]);
+ rmass[nlocal] = buf[m++];
+ angmom[nlocal][0] = buf[m++];
+ angmom[nlocal][1] = buf[m++];
+ angmom[nlocal][2] = buf[m++];
+
+ tri[nlocal] = static_cast (buf[m++]);
+ if (tri[nlocal] == 0) tri[nlocal] = -1;
+ else {
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ double *quat = bonus[nlocal_bonus].quat;
+ double *c1 = bonus[nlocal_bonus].c1;
+ double *c2 = bonus[nlocal_bonus].c2;
+ double *c3 = bonus[nlocal_bonus].c3;
+ double *inertia = bonus[nlocal_bonus].inertia;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ c1[0] = buf[m++];
+ c1[1] = buf[m++];
+ c1[2] = buf[m++];
+ c2[0] = buf[m++];
+ c2[1] = buf[m++];
+ c2[2] = buf[m++];
+ c3[0] = buf[m++];
+ c3[1] = buf[m++];
+ c3[2] = buf[m++];
+ inertia[0] = buf[m++];
+ inertia[1] = buf[m++];
+ inertia[2] = buf[m++];
+ bonus[nlocal_bonus].ilocal = nlocal;
+ tri[nlocal] = nlocal_bonus++;
+ }
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->
+ unpack_exchange(nlocal,&buf[m]);
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+------------------------------------------------------------------------- */
+
+int AtomVecTri::size_restart()
+{
+ int i;
+
+ int n = 0;
+ int nlocal = atom->nlocal;
+ for (i = 0; i < nlocal; i++)
+ if (tri[i] >= 0) n += 33;
+ else n += 17;
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ for (i = 0; i < nlocal; i++)
+ n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+ return n;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom I's data for restart file including extra quantities
+ xyz must be 1st 3 values, so that read_restart can test on them
+ molecular types may be negative, but write as positive
+------------------------------------------------------------------------- */
+
+int AtomVecTri::pack_restart(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = tag[i];
+ buf[m++] = type[i];
+ buf[m++] = mask[i];
+ buf[m++] = image[i];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+
+ buf[m++] = molecule[i];
+ buf[m++] = rmass[i];
+ buf[m++] = angmom[i][0];
+ buf[m++] = angmom[i][1];
+ buf[m++] = angmom[i][2];
+
+ if (tri[i] < 0) buf[m++] = 0;
+ else {
+ buf[m++] = 1;
+ int j = tri[i];
+ double *quat = bonus[j].quat;
+ double *c1 = bonus[j].c1;
+ double *c2 = bonus[j].c2;
+ double *c3 = bonus[j].c3;
+ double *inertia = bonus[j].inertia;
+ buf[m++] = quat[0];
+ buf[m++] = quat[1];
+ buf[m++] = quat[2];
+ buf[m++] = quat[3];
+ buf[m++] = c1[0];
+ buf[m++] = c1[1];
+ buf[m++] = c1[2];
+ buf[m++] = c2[0];
+ buf[m++] = c2[1];
+ buf[m++] = c2[2];
+ buf[m++] = c3[0];
+ buf[m++] = c3[1];
+ buf[m++] = c3[2];
+ buf[m++] = inertia[0];
+ buf[m++] = inertia[1];
+ buf[m++] = inertia[2];
+ }
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ unpack data for one atom from restart file including extra quantities
+------------------------------------------------------------------------- */
+
+int AtomVecTri::unpack_restart(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
+ }
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ tag[nlocal] = static_cast (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++]);
+ rmass[nlocal] = buf[m++];
+ angmom[nlocal][0] = buf[m++];
+ angmom[nlocal][1] = buf[m++];
+ angmom[nlocal][2] = buf[m++];
+
+ tri[nlocal] = static_cast (buf[m++]);
+ if (tri[nlocal] == 0) tri[nlocal] = -1;
+ else {
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+ double *quat = bonus[nlocal_bonus].quat;
+ double *c1 = bonus[nlocal_bonus].c1;
+ double *c2 = bonus[nlocal_bonus].c2;
+ double *c3 = bonus[nlocal_bonus].c3;
+ double *inertia = bonus[nlocal_bonus].inertia;
+ quat[0] = buf[m++];
+ quat[1] = buf[m++];
+ quat[2] = buf[m++];
+ quat[3] = buf[m++];
+ c1[0] = buf[m++];
+ c1[1] = buf[m++];
+ c1[2] = buf[m++];
+ c2[0] = buf[m++];
+ c2[1] = buf[m++];
+ c2[2] = buf[m++];
+ c3[0] = buf[m++];
+ c3[1] = buf[m++];
+ c3[2] = buf[m++];
+ inertia[0] = buf[m++];
+ inertia[1] = buf[m++];
+ inertia[2] = buf[m++];
+ bonus[nlocal_bonus].ilocal = nlocal;
+ tri[nlocal] = nlocal_bonus++;
+ }
+
+ double **extra = atom->extra;
+ if (atom->nextra_store) {
+ int size = static_cast (buf[0]) - m;
+ for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+ }
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ create one atom of itype at coord
+ set other values to defaults
+------------------------------------------------------------------------- */
+
+void AtomVecTri::create_atom(int itype, double *coord)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = 0;
+ type[nlocal] = itype;
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+ mask[nlocal] = 1;
+ image[nlocal] = (512 << 20) | (512 << 10) | 512;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ molecule[nlocal] = 0;
+ rmass[nlocal] = 1.0;
+ angmom[nlocal][0] = 0.0;
+ angmom[nlocal][1] = 0.0;
+ angmom[nlocal][2] = 0.0;
+ tri[nlocal] = -1;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one tri from Atoms section of data file
+ initialize other atom quantities
+------------------------------------------------------------------------- */
+
+void AtomVecTri::data_atom(double *coord, int imagetmp, char **values)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = atoi(values[0]);
+ if (tag[nlocal] <= 0)
+ error->one(FLERR,"Invalid atom ID in Atoms section of data file");
+
+ molecule[nlocal] = atoi(values[1]);
+
+ type[nlocal] = atoi(values[2]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ tri[nlocal] = atoi(values[3]);
+ if (tri[nlocal] == 0) tri[nlocal] = -1;
+ else if (tri[nlocal] == 1) tri[nlocal] = 0;
+ else error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ rmass[nlocal] = atof(values[4]);
+ if (rmass[nlocal] <= 0.0)
+ error->one(FLERR,"Invalid density in Atoms section of data file");
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+ angmom[nlocal][0] = 0.0;
+ angmom[nlocal][1] = 0.0;
+ angmom[nlocal][2] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack hybrid quantities from one tri in Atoms section of data file
+ initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecTri::data_atom_hybrid(int nlocal, char **values)
+{
+ molecule[nlocal] = atoi(values[0]);
+
+ tri[nlocal] = atoi(values[1]);
+ if (tri[nlocal] == 0) tri[nlocal] = -1;
+ else if (tri[nlocal] == 1) tri[nlocal] = 0;
+ else error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ rmass[nlocal] = atof(values[2]);
+ if (rmass[nlocal] <= 0.0)
+ error->one(FLERR,"Invalid density in Atoms section of data file");
+
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one tri from Tris section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecTri::data_atom_bonus(int m, char **values)
+{
+ if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom");
+
+ if (nlocal_bonus == nmax_bonus) grow_bonus();
+
+ double c1[3],c2[3],c3[3];
+ c1[0] = atof(values[0]);
+ c1[1] = atof(values[1]);
+ c1[2] = atof(values[2]);
+ c2[0] = atof(values[3]);
+ c2[1] = atof(values[4]);
+ c2[2] = atof(values[5]);
+ c3[0] = atof(values[6]);
+ c3[1] = atof(values[7]);
+ c3[2] = atof(values[8]);
+
+ // check for duplicate points
+
+ if (c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2])
+ error->one(FLERR,"Invalid shape in Triangles section of data file");
+ if (c1[0] == c3[0] && c1[1] == c3[1] && c1[2] == c3[2])
+ error->one(FLERR,"Invalid shape in Triangles section of data file");
+ if (c2[0] == c3[0] && c2[1] == c3[1] && c2[2] == c3[2])
+ error->one(FLERR,"Invalid shape in Triangles section of data file");
+
+ // size = length of one edge
+
+ double c2mc1[2],c3mc1[3];
+ MathExtra::sub3(c2,c1,c2mc1);
+ MathExtra::sub3(c3,c1,c3mc1);
+ double size = MAX(MathExtra::len3(c2mc1),MathExtra::len3(c3mc1));
+
+ // centroid = 1/3 of sum of vertices
+
+ double centroid[3];
+ centroid[0] = (c1[0]+c2[0]+c3[0]) / 3.0;
+ centroid[1] = (c1[1]+c2[1]+c3[1]) / 3.0;
+ centroid[2] = (c1[2]+c2[2]+c3[2]) / 3.0;
+
+ double dx = centroid[0] - x[m][0];
+ double dy = centroid[1] - x[m][1];
+ double dz = centroid[2] - x[m][2];
+ double delta = sqrt(dx*dx + dy*dy + dz*dz);
+
+ if (delta/size > EPSILON)
+ error->one(FLERR,"Inconsistent triangle in data file");
+
+ x[m][0] = centroid[0];
+ x[m][1] = centroid[1];
+ x[m][2] = centroid[2];
+
+ // reset tri mass
+ // previously stored density in rmass
+ // tri area = 0.5 len(U x V), where U,V are edge vectors from one vertex
+
+ double norm[3];
+ MathExtra::cross3(c2mc1,c3mc1,norm);
+ double area = 0.5 * MathExtra::len3(norm);
+ rmass[m] *= area;
+
+ // inertia = inertia tensor of triangle as 6-vector in Voigt notation
+
+ double inertia[6];
+ MathExtra::inertia_triangle(c1,c2,c3,rmass[m],inertia);
+
+ // diagonalize inertia tensor via Jacobi rotations
+ // bonus[].inertia = 3 eigenvalues = principal moments of inertia
+ // evectors and exzy_space = 3 evectors = principal axes of triangle
+
+ double tensor[3][3],evectors[3][3];
+ tensor[0][0] = inertia[0];
+ tensor[1][1] = inertia[1];
+ tensor[2][2] = inertia[2];
+ tensor[1][2] = tensor[2][1] = inertia[3];
+ tensor[0][2] = tensor[2][0] = inertia[4];
+ tensor[0][1] = tensor[1][0] = inertia[5];
+
+ int ierror = MathExtra::jacobi(tensor,bonus[nlocal_bonus].inertia,evectors);
+ if (ierror) error->one(FLERR,"Insufficient Jacobi rotations for triangle");
+
+ double ex_space[3],ey_space[3],ez_space[3];
+ ex_space[0] = evectors[0][0];
+ ex_space[1] = evectors[1][0];
+ ex_space[2] = evectors[2][0];
+ ey_space[0] = evectors[0][1];
+ ey_space[1] = evectors[1][1];
+ ey_space[2] = evectors[2][1];
+ ez_space[0] = evectors[0][2];
+ ez_space[1] = evectors[1][2];
+ ez_space[2] = evectors[2][2];
+
+ // enforce 3 orthogonal vectors as a right-handed coordinate system
+ // flip 3rd vector if needed
+
+ MathExtra::cross3(ex_space,ey_space,norm);
+ if (MathExtra::dot3(norm,ez_space) < 0.0) MathExtra::negate3(ez_space);
+
+ // create initial quaternion
+
+ MathExtra::exyz_to_q(ex_space,ey_space,ez_space,bonus[nlocal_bonus].quat);
+
+ // bonus c1,c2,c3 = displacement of c1,c2,c3 from centroid
+ // in basis of principal axes
+
+ double disp[3];
+ MathExtra::sub3(c1,centroid,disp);
+ MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
+ disp,bonus[nlocal_bonus].c1);
+ MathExtra::sub3(c2,centroid,disp);
+ MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
+ disp,bonus[nlocal_bonus].c2);
+ MathExtra::sub3(c3,centroid,disp);
+ MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
+ disp,bonus[nlocal_bonus].c3);
+
+ bonus[nlocal_bonus].ilocal = m;
+ tri[m] = nlocal_bonus++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one tri from Velocities section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecTri::data_vel(int m, char **values)
+{
+ v[m][0] = atof(values[0]);
+ v[m][1] = atof(values[1]);
+ v[m][2] = atof(values[2]);
+ angmom[m][0] = atof(values[3]);
+ angmom[m][1] = atof(values[4]);
+ angmom[m][2] = atof(values[5]);
+}
+
+/* ----------------------------------------------------------------------
+ unpack hybrid quantities from one tri in Velocities section of data file
+------------------------------------------------------------------------- */
+
+int AtomVecTri::data_vel_hybrid(int m, char **values)
+{
+ angmom[m][0] = atof(values[0]);
+ angmom[m][1] = atof(values[1]);
+ angmom[m][2] = atof(values[2]);
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ return # of bytes of allocated memory
+------------------------------------------------------------------------- */
+
+bigint AtomVecTri::memory_usage()
+{
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
+ if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
+ if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
+ if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
+ if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
+ if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
+ if (atom->memcheck("f")) bytes += memory->usage(f,nmax,3);
+
+ if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
+ if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
+ if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3);
+ if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3);
+ if (atom->memcheck("tri")) bytes += memory->usage(tri,nmax);
+
+ bytes += nmax_bonus*sizeof(Bonus);
+
+ return bytes;
+}
diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h
new file mode 100644
index 0000000000..33f3e9cd6e
--- /dev/null
+++ b/src/atom_vec_tri.h
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef ATOM_CLASS
+
+AtomStyle(tri,AtomVecTri)
+
+#else
+
+#ifndef LMP_ATOM_VEC_TRI_H
+#define LMP_ATOM_VEC_TRI_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecTri : public AtomVec {
+ public:
+ struct Bonus {
+ double quat[4];
+ double c1[3],c2[3],c3[3];
+ double inertia[3];
+ int ilocal;
+ };
+ struct Bonus *bonus;
+
+ AtomVecTri(class LAMMPS *, int, char **);
+ ~AtomVecTri();
+ void init();
+ void grow(int);
+ void grow_reset();
+ void copy(int, int, int);
+ int pack_comm(int, int *, double *, int, int *);
+ int pack_comm_vel(int, int *, double *, int, int *);
+ int pack_comm_hybrid(int, int *, double *);
+ void unpack_comm(int, int, double *);
+ void unpack_comm_vel(int, int, double *);
+ int unpack_comm_hybrid(int, int, double *);
+ int pack_reverse(int, int, double *);
+ int pack_reverse_hybrid(int, int, double *);
+ void unpack_reverse(int, int *, double *);
+ int unpack_reverse_hybrid(int, int *, double *);
+ int pack_border(int, int *, double *, int, int *);
+ int pack_border_vel(int, int *, double *, int, int *);
+ int pack_border_hybrid(int, int *, double *);
+ void unpack_border(int, int, double *);
+ void unpack_border_vel(int, int, double *);
+ int unpack_border_hybrid(int, int, double *);
+ int pack_exchange(int, double *);
+ int unpack_exchange(double *);
+ int size_restart();
+ int pack_restart(int, double *);
+ int unpack_restart(double *);
+ void create_atom(int, double *);
+ void data_atom(double *, int, char **);
+ int data_atom_hybrid(int, char **);
+ void data_vel(int, char **);
+ int data_vel_hybrid(int, char **);
+ bigint memory_usage();
+
+ // manipulate Bonus data structure for extra atom info
+
+ void clear_bonus();
+ void data_atom_bonus(int, char **);
+
+ // unique to AtomVecTri
+
+ void set_equilateral(int, double);
+
+ private:
+ int *tag,*type,*mask,*image;
+ double **x,**v,**f;
+ int *molecule;
+ double *rmass;
+ double **angmom,**torque;
+ int *tri;
+
+ int nlocal_bonus,nghost_bonus,nmax_bonus;
+
+ void grow_bonus();
+ void copy_bonus(int, int);
+};
+
+}
+
+#endif
+#endif
From 89a39c742569da723d22d37e581f7e045cfdf82c Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:01:42 +0000
Subject: [PATCH 33/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7148
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/Install.sh | 8 +
src/ASPHERE/pair_line.cpp | 444 ++++++++++++++++++++++++++
src/ASPHERE/pair_line.h | 61 ++++
src/ASPHERE/pair_tri.cpp | 637 ++++++++++++++++++++++++++++++++++++++
src/ASPHERE/pair_tri.h | 61 ++++
5 files changed, 1211 insertions(+)
create mode 100644 src/ASPHERE/pair_line.cpp
create mode 100644 src/ASPHERE/pair_line.h
create mode 100644 src/ASPHERE/pair_tri.cpp
create mode 100644 src/ASPHERE/pair_tri.h
diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh
index c896a5c285..2f6f974332 100644
--- a/src/ASPHERE/Install.sh
+++ b/src/ASPHERE/Install.sh
@@ -12,7 +12,9 @@ if (test $1 = 1) then
cp fix_nve_tri.cpp ..
cp fix_nvt_asphere.cpp ..
cp pair_gayberne.cpp ..
+ cp pair_line.cpp ..
cp pair_resquared.cpp ..
+ cp pair_tri.cpp ..
cp compute_erotate_asphere.h ..
cp compute_temp_asphere.h ..
@@ -24,7 +26,9 @@ if (test $1 = 1) then
cp fix_nve_tri.h ..
cp fix_nvt_asphere.h ..
cp pair_gayberne.h ..
+ cp pair_line.h ..
cp pair_resquared.h ..
+ cp pair_tri.h ..
elif (test $1 = 0) then
@@ -38,7 +42,9 @@ elif (test $1 = 0) then
rm -f ../fix_nve_tri.cpp
rm -f ../fix_nvt_asphere.cpp
rm -f ../pair_gayberne.cpp
+ rm -f ../pair_line.cpp
rm -f ../pair_resquared.cpp
+ rm -f ../pair_tri.cpp
rm -f ../compute_erotate_asphere.h
rm -f ../compute_temp_asphere.h
@@ -50,6 +56,8 @@ elif (test $1 = 0) then
rm -f ../fix_nve_tri.h
rm -f ../fix_nvt_asphere.h
rm -f ../pair_gayberne.h
+ rm -f ../pair_line.h
rm -f ../pair_resquared.h
+ rm -f ../pair_tri.h
fi
diff --git a/src/ASPHERE/pair_line.cpp b/src/ASPHERE/pair_line.cpp
new file mode 100644
index 0000000000..4a3902c888
--- /dev/null
+++ b/src/ASPHERE/pair_line.cpp
@@ -0,0 +1,444 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_line.h"
+#include "atom.h"
+#include "atom_vec_line.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 10000
+
+/* ---------------------------------------------------------------------- */
+
+PairLine::PairLine(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecLine *) atom->style_match("line");
+ if (!avec) error->all(FLERR,"Pair line requires atom style line");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLine::~PairLine()
+{
+ memory->sfree(discrete);
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLine::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ double **torque = atom->torque;
+ int *line = atom->line;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ for (i = 0; i < nall; i++) dnum[i] = 0;
+ ndiscrete = 0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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]) continue;
+
+ // line/line interactions = NxN particles
+
+ evdwl = 0.0;
+ if (line[i] >= 0 && line[j] >= 0) {
+ if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
+ npi = dnum[i];
+ ifirst = dfirst[i];
+ if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ torque[i][2] += dxi*fi[1] - dyi*fi[0];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ torque[j][2] += dxj*fj[1] - dyj*fj[0];
+ }
+ }
+ }
+
+ // line/particle interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[i] >= 0) {
+ if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ torque[i][2] += dxi*fi[1] - dyi*fi[0];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ }
+ }
+
+ // particle/line interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[j] >= 0) {
+ if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+
+ if (newton_pair || j < nlocal) {
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ torque[j][2] += dxj*fj[1] - dyj*fj[0];
+ }
+ }
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (eflag)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairLine::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairLine::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // 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[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairLine::coeff(int narg, char **arg)
+{
+ if (narg < 4 || narg > 5)
+ error->all(FLERR,"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 = force->numeric(arg[2]);
+ double sigma_one = force->numeric(arg[3]);
+
+ double cut_one = cut_global;
+ if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairLine::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[i][j] = mix_distance(cut[i][i],cut[j][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);
+
+ epsilon[j][i] = epsilon[i][j];
+ sigma[j][i] = sigma[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];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ discretize line segment I into N sub-segments no more than sigma in length
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+void PairLine::discretize(int i, double sigma)
+{
+ AtomVecLine::Bonus *bonus = avec->bonus;
+ double length = bonus[atom->line[i]].length;
+ double theta = bonus[atom->line[i]].theta;
+ int n = static_cast (length/sigma) + 1;
+ dnum[i] = n;
+ dfirst[i] = ndiscrete;
+
+ if (ndiscrete + n > dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+
+ double *x = atom->x[i];
+ sigma = length/n;
+ double delta;
+
+ for (int m = 0; m < n; m++) {
+ delta = -0.5 + (2*m+1)/(2.0*n);
+ discrete[ndiscrete].dx = delta*length*cos(theta);
+ discrete[ndiscrete].dy = delta*length*sin(theta);
+ discrete[ndiscrete].sigma = sigma;
+ ndiscrete++;
+ }
+}
diff --git a/src/ASPHERE/pair_line.h b/src/ASPHERE/pair_line.h
new file mode 100644
index 0000000000..6598bfe6c1
--- /dev/null
+++ b/src/ASPHERE/pair_line.h
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(line,PairLine)
+
+#else
+
+#ifndef LMP_PAIR_LINE_H
+#define LMP_PAIR_LINE_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairLine : public Pair {
+ public:
+ PairLine(class LAMMPS *);
+ ~PairLine();
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+
+ protected:
+ double cut_global;
+ double **cut;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4;
+ class AtomVecLine *avec;
+
+ struct Discrete {
+ double dx,dy;
+ double sigma;
+ };
+ Discrete *discrete; // list of all discretes for all lines
+ int ndiscrete; // number of discretes in list
+ int dmax; // allocated size of discrete list
+ int *dnum; // number of discretes per line, 0 if uninit
+ int *dfirst; // index of first discrete per each line
+ int nmax; // allocated size of dnum,dfirst vectors
+
+ void allocate();
+ void discretize(int, double);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/ASPHERE/pair_tri.cpp b/src/ASPHERE/pair_tri.cpp
new file mode 100644
index 0000000000..0a40b8fb06
--- /dev/null
+++ b/src/ASPHERE/pair_tri.cpp
@@ -0,0 +1,637 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_tri.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "atom_vec_tri.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 20
+
+/* ---------------------------------------------------------------------- */
+
+PairTri::PairTri(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecTri *) atom->style_match("tri");
+ if (!avec) error->all(FLERR,"Pair tri requires atom style tri");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairTri::~PairTri()
+{
+ memory->sfree(discrete);
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTri::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double dxi,dxj,dyi,dyj,dzi,dzj;
+ double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3];
+ double dc1[3],dc2[3],dc3[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ AtomVecTri::Bonus *bonus = avec->bonus;
+ double **x = atom->x;
+ double **f = atom->f;
+ double **torque = atom->torque;
+ int *tri = atom->tri;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ for (i = 0; i < nall; i++) dnum[i] = 0;
+ ndiscrete = 0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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]) continue;
+
+ // tri/tri interactions = NxN particles
+ // c1,c2,c3 = corner pts of triangle I or J
+
+ evdwl = 0.0;
+ if (tri[i] >= 0 && tri[j] >= 0) {
+ if (dnum[i] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
+ dfirst[i] = ndiscrete;
+ discretize(i,sigma[itype][itype],dc1,dc2,dc3);
+ dnum[i] = ndiscrete - dfirst[i];
+ }
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ if (dnum[j] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
+ MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
+ dfirst[j] = ndiscrete;
+ discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
+ dnum[j] = ndiscrete - dfirst[j];
+ }
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ ti[0] = dyi*fi[2] - dzi*fi[1];
+ ti[1] = dzi*fi[0] - dxi*fi[2];
+ ti[2] = dxi*fi[1] - dyi*fi[0];
+ torque[i][0] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ tj[0] = dyj*fj[2] - dzj*fj[1];
+ tj[1] = dzj*fj[0] - dxj*fj[2];
+ tj[2] = dxj*fj[1] - dyj*fj[0];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+ }
+ }
+ }
+
+ // tri/particle interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle I
+
+ } else if (tri[i] >= 0) {
+
+ if (dnum[i] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
+ dfirst[i] = ndiscrete;
+ discretize(i,sigma[itype][itype],dc1,dc2,dc3);
+ dnum[i] = ndiscrete - dfirst[i];
+ }
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+ xj[2] = x[j][2];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ ti[0] = dyi*fi[2] - dzi*fi[1];
+ ti[1] = dzi*fi[0] - dxi*fi[2];
+ ti[2] = dxi*fi[1] - dyi*fi[0];
+ torque[i][2] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ }
+ }
+
+ // particle/tri interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle J
+
+ } else if (tri[j] >= 0) {
+ if (dnum[j] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
+ MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
+ dfirst[j] = ndiscrete;
+ discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
+ dnum[j] = ndiscrete - dfirst[j];
+ }
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xi[2] = x[i][2];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ tj[0] = dyj*fj[2] - dzj*fj[1];
+ tj[1] = dzj*fj[0] - dxj*fj[2];
+ tj[2] = dxj*fj[1] - dyj*fj[0];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+ }
+ }
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (eflag)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairTri::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairTri::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // 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[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairTri::coeff(int narg, char **arg)
+{
+ if (narg < 4 || narg > 5)
+ error->all(FLERR,"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 = force->numeric(arg[2]);
+ double sigma_one = force->numeric(arg[3]);
+
+ double cut_one = cut_global;
+ if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairTri::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[i][j] = mix_distance(cut[i][i],cut[j][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);
+
+ epsilon[j][i] = epsilon[i][j];
+ sigma[j][i] = sigma[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];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ recursively discretize triangle I with displaced corners c1,c2,c3
+ into N sub-tris no more than sigma in size
+ recurse by making 2 tris via bisecting longest side
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+void PairTri::discretize(int i, double sigma,
+ double *c1, double *c2, double *c3)
+{
+ double c1c2[3],c2c3[3],c1c3[3];
+
+ double centroid[3],dc1[3],dc2[3],dc3[3];
+
+ centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
+ centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
+ centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
+
+ MathExtra::sub3(c1,centroid,dc1);
+ MathExtra::sub3(c2,centroid,dc2);
+ MathExtra::sub3(c3,centroid,dc3);
+
+ double sigmasq = 0.25 * sigma*sigma;
+ double len1sq = MathExtra::lensq3(dc1);
+ double len2sq = MathExtra::lensq3(dc2);
+ double len3sq = MathExtra::lensq3(dc3);
+
+ // if sigma sphere overlaps all corner points, add particle at centroid
+
+ if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
+ if (ndiscrete == dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+ discrete[ndiscrete].dx = centroid[0];
+ discrete[ndiscrete].dy = centroid[1];
+ discrete[ndiscrete].dz = centroid[2];
+ sigmasq = MAX(len1sq,len2sq);
+ sigmasq = MAX(sigmasq,len3sq);
+ discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
+ ndiscrete++;
+ return;
+ }
+
+ // else break triangle into 2 sub-triangles and recurse
+
+ double c12[3],c23[3],c13[3],mid[3];
+
+ MathExtra::sub3(c2,c3,c23);
+ len1sq = MathExtra::lensq3(c23);
+ MathExtra::sub3(c1,c3,c13);
+ len2sq = MathExtra::lensq3(c13);
+ MathExtra::sub3(c1,c2,c12);
+ len3sq = MathExtra::lensq3(c12);
+
+ double maxsq = MAX(len1sq,len2sq);
+ maxsq = MAX(maxsq,len3sq);
+
+ if (len1sq == maxsq) {
+ MathExtra::add3(c2,c3,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c1,c2,mid);
+ discretize(i,sigma,c1,c3,mid);
+ } else if (len2sq == maxsq) {
+ MathExtra::add3(c1,c3,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c2,c1,mid);
+ discretize(i,sigma,c2,c3,mid);
+ } else {
+ MathExtra::add3(c1,c2,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c3,c1,mid);
+ discretize(i,sigma,c3,c2,mid);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ recursively discretize triangle I with displaced corners c1,c2,c3
+ into N sub-tris no more than sigma in size
+ recurse by making 6 tris via centroid
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+/*
+void PairTri::discretize(int i, double sigma,
+ double *c1, double *c2, double *c3)
+{
+ double centroid[3],dc1[3],dc2[3],dc3[3];
+
+ centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
+ centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
+ centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
+
+ MathExtra::sub3(c1,centroid,dc1);
+ MathExtra::sub3(c2,centroid,dc2);
+ MathExtra::sub3(c3,centroid,dc3);
+
+ double sigmasq = 0.25 * sigma*sigma;
+ double len1sq = MathExtra::lensq3(dc1);
+ double len2sq = MathExtra::lensq3(dc2);
+ double len3sq = MathExtra::lensq3(dc3);
+
+ // if sigma sphere overlaps all corner points, add particle at centroid
+
+ if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
+ if (ndiscrete == dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+ discrete[ndiscrete].dx = centroid[0];
+ discrete[ndiscrete].dy = centroid[1];
+ discrete[ndiscrete].dz = centroid[2];
+ sigmasq = MAX(len1sq,len2sq);
+ sigmasq = MAX(sigmasq,len3sq);
+ discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
+ ndiscrete++;
+ return;
+ }
+
+ // else break triangle into 6 sub-triangles and recurse
+
+ double c1c2mid[3],c2c3mid[3],c1c3mid[3];
+
+ MathExtra::add3(c1,c2,c1c2mid);
+ MathExtra::scale3(0.5,c1c2mid);
+ MathExtra::add3(c2,c3,c2c3mid);
+ MathExtra::scale3(0.5,c2c3mid);
+ MathExtra::add3(c1,c3,c1c3mid);
+ MathExtra::scale3(0.5,c1c3mid);
+
+ discretize(i,sigma,c1,c1c2mid,centroid);
+ discretize(i,sigma,c1,c1c3mid,centroid);
+ discretize(i,sigma,c2,c2c3mid,centroid);
+ discretize(i,sigma,c2,c1c2mid,centroid);
+ discretize(i,sigma,c3,c1c3mid,centroid);
+ discretize(i,sigma,c3,c2c3mid,centroid);
+}
+
+*/
diff --git a/src/ASPHERE/pair_tri.h b/src/ASPHERE/pair_tri.h
new file mode 100644
index 0000000000..fd1fe08bac
--- /dev/null
+++ b/src/ASPHERE/pair_tri.h
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tri,PairTri)
+
+#else
+
+#ifndef LMP_PAIR_TRI_H
+#define LMP_PAIR_TRI_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairTri : public Pair {
+ public:
+ PairTri(class LAMMPS *);
+ ~PairTri();
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+
+ protected:
+ double cut_global;
+ double **cut;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4;
+ class AtomVecTri *avec;
+
+ struct Discrete {
+ double dx,dy,dz;
+ double sigma;
+ };
+ Discrete *discrete; // list of all discretes for all lines
+ int ndiscrete; // number of discretes in list
+ int dmax; // allocated size of discrete list
+ int *dnum; // number of discretes per line, 0 if uninit
+ int *dfirst; // index of first discrete per each line
+ int nmax; // allocated size of dnum,dfirst vectors
+
+ void allocate();
+ void discretize(int, double, double *, double *, double *);
+};
+
+}
+
+#endif
+#endif
From b0f09063e0ee5dfdc72dba28a877b4a1c1b442d4 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:01:56 +0000
Subject: [PATCH 34/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7149
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/atom_style.html | 32 ++++++---
doc/atom_style.txt | 34 +++++----
doc/compute_erotate_asphere.html | 32 ++++++---
doc/compute_erotate_asphere.txt | 32 ++++++---
doc/compute_property_atom.html | 19 ++++-
doc/compute_property_atom.txt | 20 ++++--
doc/fix.html | 3 +
doc/fix.txt | 3 +
doc/fix_rigid.html | 29 ++++----
doc/fix_rigid.txt | 29 ++++----
doc/fix_srd.html | 44 ++++++------
doc/fix_srd.txt | 44 ++++++------
doc/read_data.html | 99 +++++++++++++++++++++++---
doc/read_data.txt | 91 +++++++++++++++++++++---
doc/set.html | 115 ++++++++++++++++++++++--------
doc/set.txt | 118 ++++++++++++++++++++++---------
16 files changed, 539 insertions(+), 205 deletions(-)
diff --git a/doc/atom_style.html b/doc/atom_style.html
index 8356e44dfc..8b16f36569 100644
--- a/doc/atom_style.html
+++ b/doc/atom_style.html
@@ -15,7 +15,7 @@
atom_style style args
-- style = angle or atomic or bond or charge or dipole or electron or ellipsoid or full or meso or molecular or peri or sphere or hybrid
+
- style = angle or atomic or bond or charge or dipole or electron or ellipsoid or full or line or meso or molecular or peri or sphere or tri or hybrid
args = none for any style except hybrid
hybrid args = list of one or more sub-styles
@@ -61,10 +61,12 @@ quantities.
| electron | charge and spin and eradius | electronic force field |
| ellipsoid | shape, quaternion for particle orientation, angular momentum | extended aspherical particles |
| full | molecular + charge | bio-molecules |
+| line | end points, angular velocity | rigid bodies |
| meso | rho, e, cv | SPH particles |
| molecular | bonds, angles, dihedrals, impropers | uncharged molecules |
| peri | mass, volume | mesocopic Peridynamic models |
| sphere | diameter, mass, angular velocity | granular models |
+| tri | corner points, angular momentum | rigid bodies |
| wavepacket | charge, spin, eradius, etag, cs_re, cs_im | AWPMD
|
@@ -73,8 +75,8 @@ the mass command, except for the finite-size particle
styles discussed below. They assign mass on a per-atom basis.
All of the styles define point particles, except the sphere,
-ellipsoid, electron, peri, and wavepacket styles, which define
-finite-size particles.
+ellipsoid, electron, peri, wavepacket, line, and tri
+styles, which define finite-size particles.
For the sphere style, the particles are spheres and each stores a
per-particle diameter and mass. If the diameter > 0.0, the particle
@@ -104,6 +106,14 @@ cs= (cs_re,cs_im). Each of the wave packets is treated as a separate
particle in LAMMPS, wave packets belonging to the same electron must
have identical etag values.
+For the line style, the particles are idealized line segments and
+each stores a per-particle mass and length and orientation (i.e. the
+end points of the line segment).
+
+For the tri style, the particles are planar triangles and each
+stores a per-particle mass and size and orientation (i.e. the corner
+points of the triangle).
+
Typically, simulations require only a single (non-hybrid) atom style.
@@ -130,14 +140,14 @@ section.
The angle, bond, full, and molecular styles are part of the
MOLECULAR package. The dipole style is part of the "dipole"
-package. The ellipsoid style is part of the "asphere" package. The
-peri style is part of the PERI package for Peridynamics. The
-electron style is part of the USER-EFF package for electronic force
-fields. The meso style is part of the USER-SPH
-package for smoothed particle hydrodyanmics (SPH). See this PDF
-guide to using SPH in LAMMPS. The
-wavepacket style is part of the USER-AWPMD package for the
-antisymmetrized wave packet MD method. They are
+package. The ellipsoid, line, and tri styles are part of the
+"asphere" package. The peri style is part of the PERI package for
+Peridynamics. The electron style is part of the USER-EFF package
+for electronic force fields. The meso style is part
+of the USER-SPH package for smoothed particle hydrodyanmics (SPH).
+See this PDF guide to using SPH in
+LAMMPS. The wavepacket style is part of the USER-AWPMD package for
+the antisymmetrized wave packet MD method. They are
only enabled if LAMMPS was built with that package. See the Making
LAMMPS section for more info.
diff --git a/doc/atom_style.txt b/doc/atom_style.txt
index 8925291bc4..5f85786a7a 100644
--- a/doc/atom_style.txt
+++ b/doc/atom_style.txt
@@ -13,8 +13,8 @@ atom_style command :h3
atom_style style args :pre
style = {angle} or {atomic} or {bond} or {charge} or {dipole} or \
- {electron} or {ellipsoid} or {full} or {meso} or {molecular} or \
- {peri} or {sphere} or {hybrid} :ul
+ {electron} or {ellipsoid} or {full} or {line} or {meso} or \
+ {molecular} or {peri} or {sphere} or {tri} or {hybrid} :ul
args = none for any style except {hybrid}
{hybrid} args = list of one or more sub-styles :pre
@@ -58,10 +58,12 @@ quantities.
{electron} | charge and spin and eradius | electronic force field |
{ellipsoid} | shape, quaternion for particle orientation, angular momentum | extended aspherical particles |
{full} | molecular + charge | bio-molecules |
+{line} | end points, angular velocity | rigid bodies |
{meso} | rho, e, cv | SPH particles |
{molecular} | bonds, angles, dihedrals, impropers | uncharged molecules |
{peri} | mass, volume | mesocopic Peridynamic models |
{sphere} | diameter, mass, angular velocity | granular models |
+{tri} | corner points, angular momentum | rigid bodies |
{wavepacket} | charge, spin, eradius, etag, cs_re, cs_im | AWPMD :tb(c=3,s=|)
All of the styles assign mass to particles on a per-type basis, using
@@ -69,8 +71,8 @@ the "mass"_mass.html command, except for the finite-size particle
styles discussed below. They assign mass on a per-atom basis.
All of the styles define point particles, except the {sphere},
-{ellipsoid}, {electron}, {peri}, and {wavepacket} styles, which define
-finite-size particles.
+{ellipsoid}, {electron}, {peri}, {wavepacket}, {line}, and {tri}
+styles, which define finite-size particles.
For the {sphere} style, the particles are spheres and each stores a
per-particle diameter and mass. If the diameter > 0.0, the particle
@@ -100,6 +102,14 @@ cs= (cs_re,cs_im). Each of the wave packets is treated as a separate
particle in LAMMPS, wave packets belonging to the same electron must
have identical {etag} values.
+For the {line} style, the particles are idealized line segments and
+each stores a per-particle mass and length and orientation (i.e. the
+end points of the line segment).
+
+For the {tri} style, the particles are planar triangles and each
+stores a per-particle mass and size and orientation (i.e. the corner
+points of the triangle).
+
:line
Typically, simulations require only a single (non-hybrid) atom style.
@@ -126,14 +136,14 @@ This command cannot be used after the simulation box is defined by a
The {angle}, {bond}, {full}, and {molecular} styles are part of the
MOLECULAR package. The {dipole} style is part of the "dipole"
-package. The {ellipsoid} style is part of the "asphere" package. The
-{peri} style is part of the PERI package for Peridynamics. The
-{electron} style is part of the USER-EFF package for "electronic force
-fields"_pair_eff.html. The {meso} style is part of the USER-SPH
-package for smoothed particle hydrodyanmics (SPH). See "this PDF
-guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS. The
-{wavepacket} style is part of the USER-AWPMD package for the
-"antisymmetrized wave packet MD method"_pair_awpmd.html. They are
+package. The {ellipsoid}, {line}, and {tri} styles are part of the
+"asphere" package. The {peri} style is part of the PERI package for
+Peridynamics. The {electron} style is part of the USER-EFF package
+for "electronic force fields"_pair_eff.html. The {meso} style is part
+of the USER-SPH package for smoothed particle hydrodyanmics (SPH).
+See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
+LAMMPS. The {wavepacket} style is part of the USER-AWPMD package for
+the "antisymmetrized wave packet MD method"_pair_awpmd.html. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
diff --git a/doc/compute_erotate_asphere.html b/doc/compute_erotate_asphere.html
index 642fb57767..161aef27c2 100644
--- a/doc/compute_erotate_asphere.html
+++ b/doc/compute_erotate_asphere.html
@@ -25,15 +25,19 @@
Description:
Define a computation that calculates the rotational kinetic energy of
-a group of aspherical particles.
+a group of aspherical particles. The aspherical particles can be
+ellipsoids, or line segments, or triangles. See the
+atom_style and read_data commands
+for descriptions of these options.
-The rotational kinetic energy is computed as 1/2 I w^2, where I is the
-inertia tensor for the aspherical particle and w is its angular
-velocity, which is computed from its angular momentum.
+
For all 3 types of particles, the rotational kinetic energy is
+computed as 1/2 I w^2, where I is the inertia tensor for the
+aspherical particle and w is its angular velocity, which is computed
+from its angular momentum if needed.
-IMPORTANT NOTE: For 2d models, particles are treated
-as ellipsoids, not ellipses, meaning their moments of inertia will be
-the same as in 3d.
+
IMPORTANT NOTE: For 2d models, ellipsoidal particles
+are treated as ellipsoids, not ellipses, meaning their moments of
+inertia will be the same as in 3d.
Output info:
@@ -47,9 +51,17 @@ scalar value will be in energy units.
Restrictions:
-This compute requires that atoms store a shape and quaternion
-orientation and angular momentum as defined by the atom_style
-ellipsoid command.
+
This compute requires that ellipsoidal particles atoms store a shape
+and quaternion orientation and angular momentum as defined by the
+atom_style ellipsoid command.
+
+This compute requires that line segment particles atoms store a length
+and orientation and angular velocity as defined by the atom_style
+line command.
+
+This compute requires that triangular particles atoms store a size and
+shape and quaternion orientation and angular momentum as defined by
+the atom_style tri command.
All particles in the group must be finite-size. They cannot be point
particles.
diff --git a/doc/compute_erotate_asphere.txt b/doc/compute_erotate_asphere.txt
index 607d9d4425..39aded0ed7 100644
--- a/doc/compute_erotate_asphere.txt
+++ b/doc/compute_erotate_asphere.txt
@@ -22,15 +22,19 @@ compute 1 all erotate/asphere :pre
[Description:]
Define a computation that calculates the rotational kinetic energy of
-a group of aspherical particles.
+a group of aspherical particles. The aspherical particles can be
+ellipsoids, or line segments, or triangles. See the
+"atom_style"_atom_style.html and "read_data"_read_data.html commands
+for descriptions of these options.
-The rotational kinetic energy is computed as 1/2 I w^2, where I is the
-inertia tensor for the aspherical particle and w is its angular
-velocity, which is computed from its angular momentum.
+For all 3 types of particles, the rotational kinetic energy is
+computed as 1/2 I w^2, where I is the inertia tensor for the
+aspherical particle and w is its angular velocity, which is computed
+from its angular momentum if needed.
-IMPORTANT NOTE: For "2d models"_dimension.html, particles are treated
-as ellipsoids, not ellipses, meaning their moments of inertia will be
-the same as in 3d.
+IMPORTANT NOTE: For "2d models"_dimension.html, ellipsoidal particles
+are treated as ellipsoids, not ellipses, meaning their moments of
+inertia will be the same as in 3d.
[Output info:]
@@ -44,9 +48,17 @@ scalar value will be in energy "units"_units.html.
[Restrictions:]
-This compute requires that atoms store a shape and quaternion
-orientation and angular momentum as defined by the "atom_style
-ellipsoid"_atom_style.html command.
+This compute requires that ellipsoidal particles atoms store a shape
+and quaternion orientation and angular momentum as defined by the
+"atom_style ellipsoid"_atom_style.html command.
+
+This compute requires that line segment particles atoms store a length
+and orientation and angular velocity as defined by the "atom_style
+line"_atom_style.html command.
+
+This compute requires that triangular particles atoms store a size and
+shape and quaternion orientation and angular momentum as defined by
+the "atom_style tri"_atom_style.html command.
All particles in the group must be finite-size. They cannot be point
particles.
diff --git a/doc/compute_property_atom.html b/doc/compute_property_atom.html
index aec547b978..3adf2535dc 100644
--- a/doc/compute_property_atom.html
+++ b/doc/compute_property_atom.html
@@ -29,7 +29,11 @@
angmomx, angmomy, angmomz,
shapex,shapey, shapez,
quatw, quati, quatj, quatk, tqx, tqy, tqz,
- spin, eradius, ervel, erforce
+ spin, eradius, ervel, erforce
+ end1x, end1y, end1z, end2x, end2y, end2z,
+ corner1x, corner1y, corner1z,
+ corner2x, corner2y, corner2z,
+ corner3x, corner3y, corner3z
id = atom ID
mol = molecule ID
@@ -47,13 +51,15 @@
radius,diameter = radius,diameter of spherical particle
omegax,omegay,omegaz = angular velocity of extended particle
angmomx,angmomy,angmomz = angular momentum of extended particle
+ shapex,shapey,shapez = 3 diameters of aspherical particle
+ quatw,quati,quatj,quatk = quaternion components for aspherical particles
tqx,tqy,tqz = torque on extended particles
spin = electron spin
eradius = electron radius
ervel = electron radial velocity
erforce = electron radial force
- shapex,shapey,shapez = 3 diameters of aspherical particle
- quatw,quati,quatj,quatk = quaternion components for aspherical particles
+ end12x, end12y, end12z = end points of line segment
+ coner123x, corner123y, corner123z = corner points of triangle
@@ -94,6 +100,13 @@ and quatk are also defined for ellipsoidal particles and store the
See the set command for an explanation of the quaternion
vector.
+End1x, end1y, end1z, end2x, end2y, end2z, are defined for
+line segment particles and define the end points of each line segment.
+
+Corner1x, corner1y, corner1z, corner2x, corner2y,
+corner2z, corner3x, corner3y, corner3z, are defined for
+triangular particles and define the corner points of each triangle.
+
Output info:
This compute calculates a per-atom vector or per-atom array depending
diff --git a/doc/compute_property_atom.txt b/doc/compute_property_atom.txt
index f2a088be34..500ca25df4 100644
--- a/doc/compute_property_atom.txt
+++ b/doc/compute_property_atom.txt
@@ -23,8 +23,11 @@ input = one or more atom attributes :l
angmomx, angmomy, angmomz,
shapex,shapey, shapez,
quatw, quati, quatj, quatk, tqx, tqy, tqz,
- spin, eradius, ervel, erforce :pre
-
+ spin, eradius, ervel, erforce
+ end1x, end1y, end1z, end2x, end2y, end2z,
+ corner1x, corner1y, corner1z,
+ corner2x, corner2y, corner2z,
+ corner3x, corner3y, corner3z :pre
id = atom ID
mol = molecule ID
type = atom type
@@ -41,13 +44,15 @@ input = one or more atom attributes :l
radius,diameter = radius,diameter of spherical particle
omegax,omegay,omegaz = angular velocity of extended particle
angmomx,angmomy,angmomz = angular momentum of extended particle
+ shapex,shapey,shapez = 3 diameters of aspherical particle
+ quatw,quati,quatj,quatk = quaternion components for aspherical particles
tqx,tqy,tqz = torque on extended particles
spin = electron spin
eradius = electron radius
ervel = electron radial velocity
erforce = electron radial force
- shapex,shapey,shapez = 3 diameters of aspherical particle
- quatw,quati,quatj,quatk = quaternion components for aspherical particles :pre
+ end12x, end12y, end12z = end points of line segment
+ coner123x, corner123y, corner123z = corner points of triangle :pre
:ule
[Examples:]
@@ -87,6 +92,13 @@ and {quatk} are also defined for ellipsoidal particles and store the
See the "set"_set.html command for an explanation of the quaternion
vector.
+{End1x}, {end1y}, {end1z}, {end2x}, {end2y}, {end2z}, are defined for
+line segment particles and define the end points of each line segment.
+
+{Corner1x}, {corner1y}, {corner1z}, {corner2x}, {corner2y},
+{corner2z}, {corner3x}, {corner3y}, {corner3z}, are defined for
+triangular particles and define the corner points of each triangle.
+
[Output info:]
This compute calculates a per-atom vector or per-atom array depending
diff --git a/doc/fix.html b/doc/fix.html
index e73695d95e..c005536590 100644
--- a/doc/fix.html
+++ b/doc/fix.html
@@ -184,6 +184,7 @@ list of fix styles available in LAMMPS:
gcmc - grand canonical insertions/deletions
heat - add/subtract momentum-conserving heat
indent - impose force due to an indenter
+integrateU - Stokesian Dynamics evolution
langevin - Langevin temperature control
lineforce - constrain atoms to move in a line
momentum - zero the linear and/or angular momentum of a group of atoms
@@ -200,8 +201,10 @@ list of fix styles available in LAMMPS:
nve - constant NVE time integration
nve/asphere - NVT for aspherical particles
nve/limit - NVE with limited step length
+nve/line - NVE for line segments
nve/noforce - NVE without forces (v only)
nve/sphere - NVT for spherical particles
+nve/tri - NVE for triangles
nvt - constant NVT time integration via Nose/Hoover
nvt/asphere - NVT for aspherical particles
nvt/sllod - NVT for NEMD with SLLOD equations
diff --git a/doc/fix.txt b/doc/fix.txt
index a31f5bf0b2..6f59881200 100644
--- a/doc/fix.txt
+++ b/doc/fix.txt
@@ -179,6 +179,7 @@ list of fix styles available in LAMMPS:
"gcmc"_fix_gcmc.html - grand canonical insertions/deletions
"heat"_fix_heat.html - add/subtract momentum-conserving heat
"indent"_fix_indent.html - impose force due to an indenter
+"integrateU"_fix_integrateU.html - Stokesian Dynamics evolution
"langevin"_fix_langevin.html - Langevin temperature control
"lineforce"_fix_lineforce.html - constrain atoms to move in a line
"momentum"_fix_momentum.html - zero the linear and/or angular momentum of a group of atoms
@@ -195,8 +196,10 @@ list of fix styles available in LAMMPS:
"nve"_fix_nve.html - constant NVE time integration
"nve/asphere"_fix_nve_asphere.html - NVT for aspherical particles
"nve/limit"_fix_nve_limit.html - NVE with limited step length
+"nve/line"_fix_nve_line.html - NVE for line segments
"nve/noforce"_fix_nve_noforce.html - NVE without forces (v only)
"nve/sphere"_fix_nve_sphere.html - NVT for spherical particles
+"nve/tri"_fix_nve_tri.html - NVE for triangles
"nvt"_fix_nh.html - constant NVT time integration via Nose/Hoover
"nvt/asphere"_fix_nvt_asphere.html - NVT for aspherical particles
"nvt/sllod"_fix_nvt_sllod.html - NVT for NEMD with SLLOD equations
diff --git a/doc/fix_rigid.html b/doc/fix_rigid.html
index 6d92361151..c15ed3ecfe 100644
--- a/doc/fix_rigid.html
+++ b/doc/fix_rigid.html
@@ -78,12 +78,13 @@ portions of a large biomolecule such as a protein.
Example of small rigid bodies are patchy nanoparticles, such as those
modeled in this paper by Sharon Glotzer's group, clumps of
granular particles, lipid molecules consiting of one or more point
-dipoles connected to other spheroids or ellipsoids, and coarse-grain
-models of nano or colloidal particles consisting of a small number of
-constituent particles. Note that the fix shake
-command can also be used to rigidify small molecules of 2, 3, or 4
-atoms, e.g. water molecules. That fix treats the constituent atoms as
-point masses.
+dipoles connected to other spheroids or ellipsoids, irregular
+particles built from line segments (2d) or triangles (3d), and
+coarse-grain models of nano or colloidal particles consisting of a
+small number of constituent particles. Note that the fix
+shake command can also be used to rigidify small
+molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats
+the constituent atoms as point masses.
These fixes also update the positions and velocities of the atoms in
each rigid body via time integration. The rigid and rigid/nve
@@ -118,14 +119,14 @@ setforce command), and integrating them as usual
The constituent particles within a rigid body can be point particles
-(the default in LAMMPS) or finite-size particles, such as spheres and
-ellipsoids. See the atom_style sphere and ellipsoid
-commands for more details on these kinds of particles. Finite-size
-particles contribute differently to the moment of inertia of a rigid
-body than do point particles. Finite-size particles can also
-experience torque (e.g. due to frictional granular
-interactions) and have an orientation. These
-contributions are accounted for by these fixes.
+(the default in LAMMPS) or finite-size particles, such as spheres or
+ellipsoids or line segments or triangles. See the atom_style sphere
+and ellipsoid and line and tri commands for more
+details on these kinds of particles. Finite-size particles contribute
+differently to the moment of inertia of a rigid body than do point
+particles. Finite-size particles can also experience torque (e.g. due
+to frictional granular interactions) and have an
+orientation. These contributions are accounted for by these fixes.
Forces between particles within a body do not contribute to the
external force or torque on the body. Thus for computational
diff --git a/doc/fix_rigid.txt b/doc/fix_rigid.txt
index a6e50b2c07..3d49aedd6d 100644
--- a/doc/fix_rigid.txt
+++ b/doc/fix_rigid.txt
@@ -67,12 +67,13 @@ portions of a large biomolecule such as a protein.
Example of small rigid bodies are patchy nanoparticles, such as those
modeled in "this paper"_#Zhang by Sharon Glotzer's group, clumps of
granular particles, lipid molecules consiting of one or more point
-dipoles connected to other spheroids or ellipsoids, and coarse-grain
-models of nano or colloidal particles consisting of a small number of
-constituent particles. Note that the "fix shake"_fix_shake.html
-command can also be used to rigidify small molecules of 2, 3, or 4
-atoms, e.g. water molecules. That fix treats the constituent atoms as
-point masses.
+dipoles connected to other spheroids or ellipsoids, irregular
+particles built from line segments (2d) or triangles (3d), and
+coarse-grain models of nano or colloidal particles consisting of a
+small number of constituent particles. Note that the "fix
+shake"_fix_shake.html command can also be used to rigidify small
+molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats
+the constituent atoms as point masses.
These fixes also update the positions and velocities of the atoms in
each rigid body via time integration. The {rigid} and {rigid/nve}
@@ -107,14 +108,14 @@ setforce"_fix_setforce.html command), and integrating them as usual
:line
The constituent particles within a rigid body can be point particles
-(the default in LAMMPS) or finite-size particles, such as spheres and
-ellipsoids. See the "atom_style sphere and ellipsoid"_atom_style.html
-commands for more details on these kinds of particles. Finite-size
-particles contribute differently to the moment of inertia of a rigid
-body than do point particles. Finite-size particles can also
-experience torque (e.g. due to "frictional granular
-interactions"_pair_gran.html) and have an orientation. These
-contributions are accounted for by these fixes.
+(the default in LAMMPS) or finite-size particles, such as spheres or
+ellipsoids or line segments or triangles. See the "atom_style sphere
+and ellipsoid and line and tri"_atom_style.html commands for more
+details on these kinds of particles. Finite-size particles contribute
+differently to the moment of inertia of a rigid body than do point
+particles. Finite-size particles can also experience torque (e.g. due
+to "frictional granular interactions"_pair_gran.html) and have an
+orientation. These contributions are accounted for by these fixes.
Forces between particles within a body do not contribute to the
external force or torque on the body. Thus for computational
diff --git a/doc/fix_srd.html b/doc/fix_srd.html
index df029d06fd..8746be8e54 100644
--- a/doc/fix_srd.html
+++ b/doc/fix_srd.html
@@ -38,10 +38,7 @@
cubic values = style tolerance
style = error or warn
tolerance = fractional difference allowed (0 <= tol <= 1)
- shift values = style seed
- style = no or yes or possible
- seed = random # seed (positive integer)
- stream value = yes or no = whether or not streaming velocity is added for shear deformation
+ tstat value = yes or no = thermostat SRD particles or not
@@ -58,13 +55,14 @@ particles that serve as a background solvent when interacting with big
in (Hecht). The key idea behind using SRD particles as a
cheap coarse-grained solvent is that SRD particles do not interact
with each other, but only with the solute particles, which in LAMMPS
-can be spheroids, ellipsoids, or rigid bodies containing multiples
-spherioids and ellipsoids. The collision and rotation properties of
-the model imbue the SRD particles with fluid-like properties,
-including an effective viscosity. Thus simulations with large solute
-particles can be run more quickly, to measure solute propoerties like
-diffusivity and viscosity in a background fluid. The usual LAMMPS
-fixes for such simulations, such as fix deform, fix
+can be spheroids, ellipsoids, or line segments, or triangles, or rigid
+bodies containing multiple spherioids or ellipsoids or line segments
+or triangles. The collision and rotation properties of the model
+imbue the SRD particles with fluid-like properties, including an
+effective viscosity. Thus simulations with large solute particles can
+be run more quickly, to measure solute propoerties like diffusivity
+and viscosity in a background fluid. The usual LAMMPS fixes for such
+simulations, such as fix deform, fix
viscosity, and fix nvt/sllod,
can be used in conjunction with the SRD model.
@@ -272,15 +270,19 @@ must still be specified.
Note that shifting of SRD coordinates requires extra communication,
hence it should not normally be enabled unless required.
-The stream keyword should be used when SRD particles are used with
-the fix deform command to perform a simulation
-undergoing shear, e.g. to measure a viscosity. If the stream style
-is set to yes, then the mean velocity of each bin of SRD particles
-is set to the streaming velocity of the deforming box, each time SRD
-velocities are reset, every N timesteps. If the stream style is set
-to no, then the mean velocity is unchanged, which may mean that it
-takes a long time for the SRD fluid to come to equilibrium with a
-velocity profile that matches the simulation box deformation.
+
The tstat keyword will thermostat the SRD particles to the specified
+Tsrd. This is done every N timesteps, during the velocity rotation
+operation, by rescaling the thermal velocity of particles in each SRD
+bin to the desired temperature. If there is a streaming velocity
+associated with the system, e.g. due to use of the fix
+deform command to perform a simulation undergoing
+shear, then that is also accounted for. The mean velocity of each bin
+of SRD particles is set to the position-dependent streaming velocity,
+based on the coordinates of the center of the SRD bin. Note that for
+streaming simulations, if no thermostatting is performed (the
+default), then it may take a long time for the SRD fluid to come to
+equilibrium with a velocity profile that matches the simulation box
+deformation.
@@ -358,7 +360,7 @@ for more info on packages.
The option defaults are lamda inferred from Tsrd, collision = noslip,
overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0,
-search = hgrid, cubic = error 0.01, shift = no, stream = yes.
+search = hgrid, cubic = error 0.01, shift = no, tstat = no.
diff --git a/doc/fix_srd.txt b/doc/fix_srd.txt
index a45c21392e..07dd49b861 100644
--- a/doc/fix_srd.txt
+++ b/doc/fix_srd.txt
@@ -33,10 +33,7 @@ keyword = {lamda} or {collision} or {overlap} or {inside} or {exact} or {radius}
{cubic} values = style tolerance
style = {error} or {warn}
tolerance = fractional difference allowed (0 <= tol <= 1)
- {shift} values = style seed
- style = {no} or {yes} or {possible}
- seed = random # seed (positive integer)
- {stream} value = {yes} or {no} = whether or not streaming velocity is added for shear deformation :pre
+ {tstat} value = {yes} or {no} = thermostat SRD particles or not :pre
:ule
[Examples:]
@@ -52,13 +49,14 @@ particles that serve as a background solvent when interacting with big
in "(Hecht)"_#Hecht. The key idea behind using SRD particles as a
cheap coarse-grained solvent is that SRD particles do not interact
with each other, but only with the solute particles, which in LAMMPS
-can be spheroids, ellipsoids, or rigid bodies containing multiples
-spherioids and ellipsoids. The collision and rotation properties of
-the model imbue the SRD particles with fluid-like properties,
-including an effective viscosity. Thus simulations with large solute
-particles can be run more quickly, to measure solute propoerties like
-diffusivity and viscosity in a background fluid. The usual LAMMPS
-fixes for such simulations, such as "fix deform"_fix_deform.html, "fix
+can be spheroids, ellipsoids, or line segments, or triangles, or rigid
+bodies containing multiple spherioids or ellipsoids or line segments
+or triangles. The collision and rotation properties of the model
+imbue the SRD particles with fluid-like properties, including an
+effective viscosity. Thus simulations with large solute particles can
+be run more quickly, to measure solute propoerties like diffusivity
+and viscosity in a background fluid. The usual LAMMPS fixes for such
+simulations, such as "fix deform"_fix_deform.html, "fix
viscosity"_fix_viscosity.html, and "fix nvt/sllod"_fix_nvt_sllod.html,
can be used in conjunction with the SRD model.
@@ -266,15 +264,19 @@ must still be specified.
Note that shifting of SRD coordinates requires extra communication,
hence it should not normally be enabled unless required.
-The {stream} keyword should be used when SRD particles are used with
-the "fix deform"_fix_deform.html command to perform a simulation
-undergoing shear, e.g. to measure a viscosity. If the {stream} style
-is set to {yes}, then the mean velocity of each bin of SRD particles
-is set to the streaming velocity of the deforming box, each time SRD
-velocities are reset, every N timesteps. If the {stream} style is set
-to {no}, then the mean velocity is unchanged, which may mean that it
-takes a long time for the SRD fluid to come to equilibrium with a
-velocity profile that matches the simulation box deformation.
+The {tstat} keyword will thermostat the SRD particles to the specified
+{Tsrd}. This is done every N timesteps, during the velocity rotation
+operation, by rescaling the thermal velocity of particles in each SRD
+bin to the desired temperature. If there is a streaming velocity
+associated with the system, e.g. due to use of the "fix
+deform"_fix_deform.html command to perform a simulation undergoing
+shear, then that is also accounted for. The mean velocity of each bin
+of SRD particles is set to the position-dependent streaming velocity,
+based on the coordinates of the center of the SRD bin. Note that for
+streaming simulations, if no thermostatting is performed (the
+default), then it may take a long time for the SRD fluid to come to
+equilibrium with a velocity profile that matches the simulation box
+deformation.
:line
@@ -352,7 +354,7 @@ for more info on packages.
The option defaults are lamda inferred from Tsrd, collision = noslip,
overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0,
-search = hgrid, cubic = error 0.01, shift = no, stream = yes.
+search = hgrid, cubic = error 0.01, shift = no, tstat = no.
:line
diff --git a/doc/read_data.html b/doc/read_data.html
index 2eced78fe0..fcf68f4680 100644
--- a/doc/read_data.html
+++ b/doc/read_data.html
@@ -80,6 +80,8 @@ is different than the default.
improper types = # of improper types in system
extra bond per atom = leave space for this many new bonds per atom
ellipsoids = # of ellipsoids in system
+lines = # of line segments in system
+triangles = # of triangles in system
xlo xhi = simulation box boundaries in x dimension
ylo yhi = simulation box boundaries in y dimension
zlo zhi = simulation box boundaries in z dimension
@@ -156,16 +158,19 @@ added to the system when a simulation runs, e.g. by using the setting is only used with atom_style
-ellipsoid and specifies how many of the atoms are
-finite-size ellipsoids; the remainder are point particles. See the
-discussion of ellipsoidflag and the Ellipsoids section below.
+The "ellipsoids" and "lines" and "triangles" settings are only used
+with atom_style ellipsoid or line or tri and
+specifies how many of the atoms are finite-size ellipsoids or lines or
+triangles; the remainder are point particles. See the discussion of
+ellipsoidflag and the Ellipsoids section below. See the discussion
+of lineflag and the Lines section below. See the discussion of
+triangleflag and the Triangles section below.
These are the section keywords for the body of the file.
-- Atoms, Velocities, Ellipsoids, Masses = atom-property sections
+
- Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles = atom-property sections
- Bonds, Angles, Dihedrals, Impropers = molecular topology sections
- Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, Improper Coeffs = force field sections
- BondBond Coeffs, BondAngle Coeffs, MiddleBondTorsion Coeffs, EndBondTorsion Coeffs, AngleTorsion Coeffs, AngleAngleTorsion Coeffs, BondBond13 Coeffs, AngleAngle Coeffs = class 2 force field sections
@@ -290,10 +295,12 @@ of analysis.
| electron | atom-ID atom-type q spin eradius x y z |
| ellipsoid | atom-ID atom-type ellipsoidflag density x y z |
| full | atom-ID molecule-ID atom-type q x y z |
+| line | atom-ID molecule-ID atom-type lineflag density x y z |
| meso | atom-ID atom-type rho e cv x y z |
| molecular | atom-ID molecule-ID atom-type x y z |
| peri | atom-ID atom-type volume density x y z |
| sphere | atom-ID atom-type diameter density x y z |
+| tri | atom-ID molecule-ID atom-type triangleflag density x y z |
| wavepacket | atom-ID atom-type charge spin eradius etag cs_re cs_im x y z |
| hybrid | atom-ID atom-type x y z sub-style1 sub-style2 ...
|
@@ -306,7 +313,9 @@ of analysis.
- q = charge on atom (charge units)
- diameter = diameter of spherical atom (distance units)
- ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles
-
- density = density of atom (mass/distance^3 units)
+
- lineflag = 1 for line segment particles, 0 for point particles
+
- triangleflag = 1 for triangular particles, 0 for point particles
+
- density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
- volume = volume of atom (distance^3 units)
- x,y,z = coordinates of atom
- mux,muy,muz = components of dipole moment of atom (dipole units)
@@ -342,9 +351,13 @@ keep track of molecule assignments.
The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
-The ellipsoidflag determines whether the particle is a finite-size
-ellipsoid of finite size, or a point particle. Additional attributes
-must be defined for each ellipsoid in the Ellipsoids section.
+
The ellipsoidflag, lineflag, and triangleflag determine whether the
+particle is a finite-size ellipsoid or line or triangle of finite
+size, or a point particle. Additional attributes must be defined for
+each ellipsoid in the Ellipsoids section. Additional attributes
+must be defined for each line in the Lines section. Additional
+attributes must be defined for each triangle in the Triangles
+section.
Some pair styles and fixes and computes that operate on finite-size
particles allow for a mixture of finite-size and point particles. See
@@ -352,8 +365,10 @@ the doc pages of individual commands for details.
The density is used in conjunction with the particle volume for
finite-size particles to set the mass of the particle as mass =
-density * volume. If the volume is 0.0, meaning a point particle,
-then the density value is used as the mass.
+density * volume. In this context, volume can be a 3d quantity (for
+spheres or ellipsoids), a 2d quantity (for triangles), or a 1d
+quantity (for line segments). If the volume is 0.0, meaning a point
+particle, then the density value is used as the mass.
For atom_style hybrid, following the 5 initial values (ID,type,x,y,z),
specific values for each sub-style must be listed. The order of the
@@ -627,6 +642,37 @@ values in this section must be integers (1, not 1.0).
+Lines section:
+
+- one line per line segment
+
+
- line syntax: atom-ID x1 y1 x2 y2
+
+
- atom-ID = ID of atom which is a line segment
+ x1,y1 = 1st end point
+ x2,y2 = 2nd end point
+example:
+
+
12 1.0 0.0 2.0 0.0
+
+
+
+The Lines section must appear if atom_style line
+is used and any atoms are listed in the Atoms section with a
+lineflag = 1. The number of lines should be specified in the header
+section via the "lines" keyword.
+
+The 2 end points are the end points of the line segment. The ordering
+of the 2 points should be such that using a right-hand rule to cross
+the line segment with a unit vector in the +z direction, gives an
+"outward" normal vector perpendicular to the line segment.
+I.e. normal = (c2-c1) x (0,0,1). This orientation may be important
+for defining some interactions.
+
+The Lines section must appear after the Atoms section.
+
+
+
Masses section:
- one line per atom type
@@ -685,6 +731,37 @@ script.
+Triangles section:
+
+
+The Triangles section must appear if atom_style
+tri is used and any atoms are listed in the Atoms
+section with a triangleflag = 1. The number of lines should be
+specified in the header section via the "triangles" keyword.
+
+The 3 corner points are the corner points of the triangle. The
+ordering of the 3 points should be such that using a right-hand rule
+to go from point1 to point2 to point3 gives an "outward" normal vector
+to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This
+orientation may be important for defining some interactions.
+
+The Triangles section must appear after the Atoms section.
+
+
+
Velocities section:
- one line per atom
diff --git a/doc/read_data.txt b/doc/read_data.txt
index d023d5de6e..b9fcccd0f6 100644
--- a/doc/read_data.txt
+++ b/doc/read_data.txt
@@ -77,6 +77,8 @@ is different than the default.
{improper types} = # of improper types in system
{extra bond per atom} = leave space for this many new bonds per atom
{ellipsoids} = # of ellipsoids in system
+{lines} = # of line segments in system
+{triangles} = # of triangles in system
{xlo xhi} = simulation box boundaries in x dimension
{ylo yhi} = simulation box boundaries in y dimension
{zlo zhi} = simulation box boundaries in z dimension
@@ -153,16 +155,19 @@ added to the system when a simulation runs, e.g. by using the "fix
bond/create"_fix_bond_create.html command. This will pre-allocate
space in LAMMPS data structures for storing the new bonds.
-The "ellipsoids" setting is only used with atom_style
-ellipsoid"_atom_style.html and specifies how many of the atoms are
-finite-size ellipsoids; the remainder are point particles. See the
-discussion of ellipsoidflag and the {Ellipsoids} section below.
+The "ellipsoids" and "lines" and "triangles" settings are only used
+with "atom_style ellipsoid or line or tri"_atom_style.html and
+specifies how many of the atoms are finite-size ellipsoids or lines or
+triangles; the remainder are point particles. See the discussion of
+ellipsoidflag and the {Ellipsoids} section below. See the discussion
+of lineflag and the {Lines} section below. See the discussion of
+triangleflag and the {Triangles} section below.
:line
These are the section keywords for the body of the file.
-{Atoms, Velocities, Ellipsoids, Masses} = atom-property sections
+{Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles} = atom-property sections
{Bonds, Angles, Dihedrals, Impropers} = molecular topology sections
{Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, \
Improper Coeffs} = force field sections
@@ -270,10 +275,12 @@ dipole: atom-ID atom-type q x y z mux muy muz
electron: atom-ID atom-type q spin eradius x y z
ellipsoid: atom-ID atom-type ellipsoidflag density x y z
full: atom-ID molecule-ID atom-type q x y z
+line: atom-ID molecule-ID atom-type lineflag density x y z
meso: atom-ID atom-type rho e cv x y z
molecular: atom-ID molecule-ID atom-type x y z
peri: atom-ID atom-type volume density x y z
sphere: atom-ID atom-type diameter density x y z
+tri: atom-ID molecule-ID atom-type triangleflag density x y z
wavepacket: atom-ID atom-type charge spin eradius etag cs_re cs_im x y z
hybrid: atom-ID atom-type x y z sub-style1 sub-style2 ... :tb(s=:)
@@ -285,7 +292,9 @@ atom-type = type of atom (1-Ntype)
q = charge on atom (charge units)
diameter = diameter of spherical atom (distance units)
ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles
-density = density of atom (mass/distance^3 units)
+lineflag = 1 for line segment particles, 0 for point particles
+triangleflag = 1 for triangular particles, 0 for point particles
+density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
volume = volume of atom (distance^3 units)
x,y,z = coordinates of atom
mux,muy,muz = components of dipole moment of atom (dipole units)
@@ -321,9 +330,13 @@ keep track of molecule assignments.
The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
-The ellipsoidflag determines whether the particle is a finite-size
-ellipsoid of finite size, or a point particle. Additional attributes
-must be defined for each ellipsoid in the {Ellipsoids} section.
+The ellipsoidflag, lineflag, and triangleflag determine whether the
+particle is a finite-size ellipsoid or line or triangle of finite
+size, or a point particle. Additional attributes must be defined for
+each ellipsoid in the {Ellipsoids} section. Additional attributes
+must be defined for each line in the {Lines} section. Additional
+attributes must be defined for each triangle in the {Triangles}
+section.
Some pair styles and fixes and computes that operate on finite-size
particles allow for a mixture of finite-size and point particles. See
@@ -331,8 +344,10 @@ the doc pages of individual commands for details.
The density is used in conjunction with the particle volume for
finite-size particles to set the mass of the particle as mass =
-density * volume. If the volume is 0.0, meaning a point particle,
-then the density value is used as the mass.
+density * volume. In this context, volume can be a 3d quantity (for
+spheres or ellipsoids), a 2d quantity (for triangles), or a 1d
+quantity (for line segments). If the volume is 0.0, meaning a point
+particle, then the density value is used as the mass.
For atom_style hybrid, following the 5 initial values (ID,type,x,y,z),
specific values for each sub-style must be listed. The order of the
@@ -560,6 +575,33 @@ values in this section must be integers (1, not 1.0).
:line
+{Lines} section:
+
+one line per line segment :ulb,l
+line syntax: atom-ID x1 y1 x2 y2 :l
+ atom-ID = ID of atom which is a line segment
+ x1,y1 = 1st end point
+ x2,y2 = 2nd end point
+example: :l
+ 12 1.0 0.0 2.0 0.0 :pre
+:ule
+
+The {Lines} section must appear if "atom_style line"_atom_style.html
+is used and any atoms are listed in the {Atoms} section with a
+lineflag = 1. The number of lines should be specified in the header
+section via the "lines" keyword.
+
+The 2 end points are the end points of the line segment. The ordering
+of the 2 points should be such that using a right-hand rule to cross
+the line segment with a unit vector in the +z direction, gives an
+"outward" normal vector perpendicular to the line segment.
+I.e. normal = (c2-c1) x (0,0,1). This orientation may be important
+for defining some interactions.
+
+The {Lines} section must appear after the {Atoms} section.
+
+:line
+
{Masses} section:
one line per atom type :ulb,l
@@ -605,6 +647,33 @@ script.
:line
+{Triangles} section:
+
+one line per triangle :ulb,l
+line syntax: atom-ID x1 y1 x2 y2 :l
+ atom-ID = ID of atom which is a line segment
+ x1,y1,z1 = 1st corner point
+ x2,y2,z2 = 2nd corner point
+ x3,y3,z3 = 3rd corner point
+example: :l
+ 12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 :pre
+:ule
+
+The {Triangles} section must appear if "atom_style
+tri"_atom_style.html is used and any atoms are listed in the {Atoms}
+section with a triangleflag = 1. The number of lines should be
+specified in the header section via the "triangles" keyword.
+
+The 3 corner points are the corner points of the triangle. The
+ordering of the 3 points should be such that using a right-hand rule
+to go from point1 to point2 to point3 gives an "outward" normal vector
+to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This
+orientation may be important for defining some interactions.
+
+The {Triangles} section must appear after the {Atoms} section.
+
+:line
+
{Velocities} section:
one line per atom
diff --git a/doc/set.html b/doc/set.html
index a1feb65a31..06be9fb51c 100644
--- a/doc/set.html
+++ b/doc/set.html
@@ -21,7 +21,7 @@
- one or more keyword/value pairs may be appended
-
- keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or mass or density or volume or image or
+
- keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or length or tri or theta or angmom or mass or density or volume or image or
bond or angle or dihedral or improper or
meso_e or meso_cv or meso_rho
@@ -40,14 +40,22 @@
Dlen = magnitude of dipole moment (dipole units)
quat values = a b c theta
a,b,c = unit vector to rotate particle around via right-hand rule
- theta = rotation angle in degrees
+ theta = rotation angle (degrees)
quat/random value = seed
seed = random # seed (positive integer) for quaternion orientations
diameter value = diameter of spherical particle (distance units)
shape value = Sx Sy Sz
Sx,Sy,Sz = 3 diameters of ellipsoid (distance units)
+ length value = len
+ len = length of line segment (distance units)
+ tri value = side
+ side = side length of equilateral triangle (distance units)
+ theta value = angle (degrees)
+ angle = orientation of line segment with respect to x-axis
+ angmom values = Lx Ly Lz
+ Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units)
mass value = per-atom mass (mass units)
- density value = particle density for sphere or ellipsoid (mass/distance^3 units)
+ density value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
volume value = particle volume for Peridynamic particle (distance^3 units)
image nx ny nz
nx,ny,nz = which periodic image of the simulation box the atom is in
@@ -143,26 +151,31 @@ the orientation of a particular atom is the same, regardless of how
many processors are being used.
Keyword quat uses the specified values to create a quaternion
-(4-vector) that represents the orientation of the selected atoms.
-Note that particles defined by atom_style ellipsoid
-have 3 shape parameters. The 3 values must be non-zero for each
-particle set by this command. They are used to specify the aspect
-ratios of an ellipsoidal particle, which is oriented by default with
-its x-axis along the simulation box's x-axis, and similarly for y and
-z. If this body is rotated (via the right-hand rule) by an angle
-theta around a unit rotation vector (a,b,c), then the quaternion that
-represents its new orientation is given by (cos(theta/2),
-a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c
-values are the arguments to the quat keyword. LAMMPS normalizes the
-quaternion in case (a,b,c) was not specified as a unit vector. For 2d
-systems, the a,b,c values are ignored, since a rotation vector of
-(0,0,1) is the only valid choice.
+(4-vector) that represents the orientation of the selected atoms. The
+particles must be ellipsoids as defined by the atom_style
+ellipsoid command or triangles as defined by the
+atom_style tri command. Note that particles defined
+by atom_style ellipsoid have 3 shape parameters.
+The 3 values must be non-zero for each particle set by this command.
+They are used to specify the aspect ratios of an ellipsoidal particle,
+which is oriented by default with its x-axis along the simulation
+box's x-axis, and similarly for y and z. If this body is rotated (via
+the right-hand rule) by an angle theta around a unit rotation vector
+(a,b,c), then the quaternion that represents its new orientation is
+given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2),
+c*sin(theta/2)). The theta and a,b,c values are the arguments to the
+quat keyword. LAMMPS normalizes the quaternion in case (a,b,c) was
+not specified as a unit vector. For 2d systems, the a,b,c values are
+ignored, since a rotation vector of (0,0,1) is the only valid choice.
Keyword quat/random randomizes the orientation of the quaternion of
-the selected atoms. Random numbers are used in such a way that the
-orientation of a particular atom is the same, regardless of how many
-processors are being used. For 2d systems, only orientations in the
-xy plane are generated. As with keyword quat, the 3 shape values
+the selected atoms. The particles must be ellipsoids as defined by
+the atom_style ellipsoid command or triangles as
+defined by the atom_style tri command. Random
+numbers are used in such a way that the orientation of a particular
+atom is the same, regardless of how many processors are being used.
+For 2d systems, only orientations in the xy plane are generated. As
+with keyword quat, for ellipsoidal particles, the 3 shape values
must be non-zero for each particle set by this command.
Keyword diameter sets the size of the selected atoms. The particles
@@ -174,7 +187,7 @@ defined with a density, e.g. via the read_data
command.
Keyword shape sets the size and shape of the selected atoms. The
-particles must be aspherical ellipsoids as defined by the atom_style
+particles must be ellipsoids as defined by the atom_style
ellipsoid command. The Sx, Sy, Sz settings are
the 3 diameters of the ellipsoid in each direction. All 3 can be set
to the same value, which means the ellipsoid is effectively a sphere.
@@ -183,20 +196,60 @@ treated as a point particle. Note that this command does not adjust
the particle mass, even if it was defined with a density, e.g. via the
read_data command.
+Keyword length sets the length of selected atoms. The particles
+must be line segments as defined by the atom_style
+line command. If the specified value is non-zero the
+line segment is (re)set to a length = the specified value, centered
+around the particle position, with an orientation along the x-axis.
+If the specified value is 0.0, the particle will become a point
+particle. Note that this command does not adjust the particle mass,
+even if it was defined with a density, e.g. via the
+read_data command.
+
+Keyword tri sets the size of selected atoms. The particles must be
+triangles as defined by the atom_style tri command.
+If the specified value is non-zero the triangle is (re)set to be an
+equilateral triangle in the xy plane with side length = the specified
+value, with a centroid at the particle position, with its base
+parallel to the x axis, and the y-axis running from the center of the
+base to the top point of the triangle. If the specified value is 0.0,
+the particle will become a point particle. Note that this command
+does not adjust the particle mass, even if it was defined with a
+density, e.g. via the read_data command.
+
+Keyword theta sets the orientation of selected atoms. The particles
+must be line segments as defined by the atom_style
+line command. The specified value is used to set the
+orientation angle of the line segments with respect to the x axis.
+
+Keyword angmom sets the angular momentum of selected atoms. The
+particles must be ellipsoids as defined by the atom_style
+ellipsoid command or triangles as defined by the
+atom_style tri command. The angular momentum vector
+of the particles is set to the 3 specified components.
+
Keyword mass sets the mass of all selected particles. The particles
must have a per-atom mass attribute, as defined by the
atom_style command. See the "mass" command for how
to set mass values on a per-type basis.
-Keyword density sets the mass of all selected particles. The
-particles must have a per-atom mass attribute, as defined by the
-atom_style command. See the "mass" command for how
-to set mass values on a per-type basis. If the atom has a radius
-attribute (see atom_style sphere) and its radius is
-non-zero, its mass is set from the density and particle volume. The
-same is true if the atom has a shape attribute (see atom_style
-ellipsoid) and its 3 shape parameters are non-zero.
-Otherwise the mass is set to the density value directly.
+
Keyword density also sets the mass of all selected particles, but in
+a different way. The particles must have a per-atom mass attribute,
+as defined by the atom_style command. If the atom
+has a radius attribute (see atom_style sphere) and
+its radius is non-zero, its mass is set from the density and particle
+volume. If the atom has a shape attribute (see atom_style
+ellipsoid) and its 3 shape parameters are non-zero,
+then its mass is set from the density and particle volume. If the
+atom has a length attribute (see atom_style line)
+and its length is non-zero, then its mass is set from the density and
+line segment length (the input density is assumed to be in
+mass/distance units). If the atom has an area attribute (see
+atom_style tri) and its area is non-zero, then its
+mass is set from the density and triangle area (the input density is
+assumed to be in mass/distance^2 units). If none of these cases are
+valid, then the mass is set to the density value directly (the input
+density is assumed to be in mass units).
Keyword volume sets the volume of all selected particles.
Currently, only the atom_style peri command defines
diff --git a/doc/set.txt b/doc/set.txt
index 8f37b29f1b..0c352d0958 100644
--- a/doc/set.txt
+++ b/doc/set.txt
@@ -17,8 +17,9 @@ ID = atom ID range or type range or mol ID range or group ID or region ID :l
one or more keyword/value pairs may be appended :l
keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \
{charge} or {dipole} or {dipole/random} or {quat} or \
- {quat/random} or {diameter} or {shape} or {mass} or \
- {density} or {volume} or {image} or
+ {quat/random} or {diameter} or {shape} or \
+ {length} or {tri} or {theta} or {angmom} or \
+ {mass} or {density} or {volume} or {image} or
{bond} or {angle} or {dihedral} or {improper} or
{meso_e} or {meso_cv} or {meso_rho} :l
{type} value = atom type
@@ -36,14 +37,22 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \
Dlen = magnitude of dipole moment (dipole units)
{quat} values = a b c theta
a,b,c = unit vector to rotate particle around via right-hand rule
- theta = rotation angle in degrees
+ theta = rotation angle (degrees)
{quat/random} value = seed
seed = random # seed (positive integer) for quaternion orientations
{diameter} value = diameter of spherical particle (distance units)
{shape} value = Sx Sy Sz
Sx,Sy,Sz = 3 diameters of ellipsoid (distance units)
+ {length} value = len
+ len = length of line segment (distance units)
+ {tri} value = side
+ side = side length of equilateral triangle (distance units)
+ {theta} value = angle (degrees)
+ angle = orientation of line segment with respect to x-axis
+ {angmom} values = Lx Ly Lz
+ Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units)
{mass} value = per-atom mass (mass units)
- {density} value = particle density for sphere or ellipsoid (mass/distance^3 units)
+ {density} value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
{volume} value = particle volume for Peridynamic particle (distance^3 units)
{image} nx ny nz
nx,ny,nz = which periodic image of the simulation box the atom is in
@@ -138,26 +147,31 @@ the orientation of a particular atom is the same, regardless of how
many processors are being used.
Keyword {quat} uses the specified values to create a quaternion
-(4-vector) that represents the orientation of the selected atoms.
-Note that particles defined by "atom_style ellipsoid"_atom_style.html
-have 3 shape parameters. The 3 values must be non-zero for each
-particle set by this command. They are used to specify the aspect
-ratios of an ellipsoidal particle, which is oriented by default with
-its x-axis along the simulation box's x-axis, and similarly for y and
-z. If this body is rotated (via the right-hand rule) by an angle
-theta around a unit rotation vector (a,b,c), then the quaternion that
-represents its new orientation is given by (cos(theta/2),
-a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c
-values are the arguments to the {quat} keyword. LAMMPS normalizes the
-quaternion in case (a,b,c) was not specified as a unit vector. For 2d
-systems, the a,b,c values are ignored, since a rotation vector of
-(0,0,1) is the only valid choice.
+(4-vector) that represents the orientation of the selected atoms. The
+particles must be ellipsoids as defined by the "atom_style
+ellipsoid"_atom_style.html command or triangles as defined by the
+"atom_style tri"_atom_style.html command. Note that particles defined
+by "atom_style ellipsoid"_atom_style.html have 3 shape parameters.
+The 3 values must be non-zero for each particle set by this command.
+They are used to specify the aspect ratios of an ellipsoidal particle,
+which is oriented by default with its x-axis along the simulation
+box's x-axis, and similarly for y and z. If this body is rotated (via
+the right-hand rule) by an angle theta around a unit rotation vector
+(a,b,c), then the quaternion that represents its new orientation is
+given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2),
+c*sin(theta/2)). The theta and a,b,c values are the arguments to the
+{quat} keyword. LAMMPS normalizes the quaternion in case (a,b,c) was
+not specified as a unit vector. For 2d systems, the a,b,c values are
+ignored, since a rotation vector of (0,0,1) is the only valid choice.
Keyword {quat/random} randomizes the orientation of the quaternion of
-the selected atoms. Random numbers are used in such a way that the
-orientation of a particular atom is the same, regardless of how many
-processors are being used. For 2d systems, only orientations in the
-xy plane are generated. As with keyword {quat}, the 3 shape values
+the selected atoms. The particles must be ellipsoids as defined by
+the "atom_style ellipsoid"_atom_style.html command or triangles as
+defined by the "atom_style tri"_atom_style.html command. Random
+numbers are used in such a way that the orientation of a particular
+atom is the same, regardless of how many processors are being used.
+For 2d systems, only orientations in the xy plane are generated. As
+with keyword {quat}, for ellipsoidal particles, the 3 shape values
must be non-zero for each particle set by this command.
Keyword {diameter} sets the size of the selected atoms. The particles
@@ -169,7 +183,7 @@ defined with a density, e.g. via the "read_data"_read_data.html
command.
Keyword {shape} sets the size and shape of the selected atoms. The
-particles must be aspherical ellipsoids as defined by the "atom_style
+particles must be ellipsoids as defined by the "atom_style
ellipsoid"_atom_style.html command. The {Sx}, {Sy}, {Sz} settings are
the 3 diameters of the ellipsoid in each direction. All 3 can be set
to the same value, which means the ellipsoid is effectively a sphere.
@@ -178,20 +192,60 @@ treated as a point particle. Note that this command does not adjust
the particle mass, even if it was defined with a density, e.g. via the
"read_data"_read_data.html command.
+Keyword {length} sets the length of selected atoms. The particles
+must be line segments as defined by the "atom_style
+line"_atom_style.html command. If the specified value is non-zero the
+line segment is (re)set to a length = the specified value, centered
+around the particle position, with an orientation along the x-axis.
+If the specified value is 0.0, the particle will become a point
+particle. Note that this command does not adjust the particle mass,
+even if it was defined with a density, e.g. via the
+"read_data"_read_data.html command.
+
+Keyword {tri} sets the size of selected atoms. The particles must be
+triangles as defined by the "atom_style tri"_atom_style.html command.
+If the specified value is non-zero the triangle is (re)set to be an
+equilateral triangle in the xy plane with side length = the specified
+value, with a centroid at the particle position, with its base
+parallel to the x axis, and the y-axis running from the center of the
+base to the top point of the triangle. If the specified value is 0.0,
+the particle will become a point particle. Note that this command
+does not adjust the particle mass, even if it was defined with a
+density, e.g. via the "read_data"_read_data.html command.
+
+Keyword {theta} sets the orientation of selected atoms. The particles
+must be line segments as defined by the "atom_style
+line"_atom_style.html command. The specified value is used to set the
+orientation angle of the line segments with respect to the x axis.
+
+Keyword {angmom} sets the angular momentum of selected atoms. The
+particles must be ellipsoids as defined by the "atom_style
+ellipsoid"_atom_style.html command or triangles as defined by the
+"atom_style tri"_atom_style.html command. The angular momentum vector
+of the particles is set to the 3 specified components.
+
Keyword {mass} sets the mass of all selected particles. The particles
must have a per-atom mass attribute, as defined by the
"atom_style"_atom_style.html command. See the "mass" command for how
to set mass values on a per-type basis.
-Keyword {density} sets the mass of all selected particles. The
-particles must have a per-atom mass attribute, as defined by the
-"atom_style"_atom_style.html command. See the "mass" command for how
-to set mass values on a per-type basis. If the atom has a radius
-attribute (see "atom_style sphere"_atom_style.html) and its radius is
-non-zero, its mass is set from the density and particle volume. The
-same is true if the atom has a shape attribute (see "atom_style
-ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero.
-Otherwise the mass is set to the density value directly.
+Keyword {density} also sets the mass of all selected particles, but in
+a different way. The particles must have a per-atom mass attribute,
+as defined by the "atom_style"_atom_style.html command. If the atom
+has a radius attribute (see "atom_style sphere"_atom_style.html) and
+its radius is non-zero, its mass is set from the density and particle
+volume. If the atom has a shape attribute (see "atom_style
+ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero,
+then its mass is set from the density and particle volume. If the
+atom has a length attribute (see "atom_style line"_atom_style.html)
+and its length is non-zero, then its mass is set from the density and
+line segment length (the input density is assumed to be in
+mass/distance units). If the atom has an area attribute (see
+"atom_style tri"_atom_style.html) and its area is non-zero, then its
+mass is set from the density and triangle area (the input density is
+assumed to be in mass/distance^2 units). If none of these cases are
+valid, then the mass is set to the density value directly (the input
+density is assumed to be in mass units).
Keyword {volume} sets the volume of all selected particles.
Currently, only the "atom_style peri"_atom_style.html command defines
From 35aaafdfa7503889291ef6299bcaaf5021c7a8e0 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:02:14 +0000
Subject: [PATCH 35/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7150
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/fix_nve_line.html | 60 +++++++++++++++++++++
doc/fix_nve_line.txt | 55 +++++++++++++++++++
doc/fix_nve_tri.html | 60 +++++++++++++++++++++
doc/fix_nve_tri.txt | 55 +++++++++++++++++++
doc/pair_line.html | 117 ++++++++++++++++++++++++++++++++++++++++
doc/pair_line.txt | 112 +++++++++++++++++++++++++++++++++++++++
doc/pair_tri.html | 120 ++++++++++++++++++++++++++++++++++++++++++
doc/pair_tri.txt | 115 ++++++++++++++++++++++++++++++++++++++++
8 files changed, 694 insertions(+)
create mode 100644 doc/fix_nve_line.html
create mode 100755 doc/fix_nve_line.txt
create mode 100644 doc/fix_nve_tri.html
create mode 100755 doc/fix_nve_tri.txt
create mode 100644 doc/pair_line.html
create mode 100644 doc/pair_line.txt
create mode 100644 doc/pair_tri.html
create mode 100644 doc/pair_tri.txt
diff --git a/doc/fix_nve_line.html b/doc/fix_nve_line.html
new file mode 100644
index 0000000000..2a39e7b177
--- /dev/null
+++ b/doc/fix_nve_line.html
@@ -0,0 +1,60 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+fix nve/line command
+
+Syntax:
+
+fix ID group-ID nve/line
+
+- ID, group-ID are documented in fix command
+
- nve/line = style name of this fix command
+
+Examples:
+
+fix 1 all nve/line
+
+Description:
+
+Perform constant NVE integration to update position, velocity,
+orientation, and angular velocity for line segment particles in the
+group each timestep. V is volume; E is energy. This creates a system
+trajectory consistent with the microcanonical ensemble.
+
+This fix differs from the fix nve command, which
+assumes point particles and only updates their position and velocity.
+
+Restart, fix_modify, output, run start/stop, minimize info:
+
+No information about this fix is written to binary restart
+files. None of the fix_modify options
+are relevant to this fix. No global or per-atom quantities are stored
+by this fix for access by various output
+commands. No parameter of this fix can
+be used with the start/stop keywords of the run command.
+This fix is not invoked during energy minimization.
+
+Restrictions:
+
+This fix is part of the ASPHERE package. It is only enabled if LAMMPS
+was built with that package. See the Making
+LAMMPS section for more info.
+
+This fix requires that particles be line segments as defined by the
+atom_style line command.
+
+Related commands:
+
+fix nve, fix nve/asphere
+
+Default: none
+
+
diff --git a/doc/fix_nve_line.txt b/doc/fix_nve_line.txt
new file mode 100755
index 0000000000..da93f30dbb
--- /dev/null
+++ b/doc/fix_nve_line.txt
@@ -0,0 +1,55 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+fix nve/line command :h3
+
+[Syntax:]
+
+fix ID group-ID nve/line :pre
+
+ID, group-ID are documented in "fix"_fix.html command
+nve/line = style name of this fix command :ul
+
+[Examples:]
+
+fix 1 all nve/line :pre
+
+[Description:]
+
+Perform constant NVE integration to update position, velocity,
+orientation, and angular velocity for line segment particles in the
+group each timestep. V is volume; E is energy. This creates a system
+trajectory consistent with the microcanonical ensemble.
+
+This fix differs from the "fix nve"_fix_nve.html command, which
+assumes point particles and only updates their position and velocity.
+
+[Restart, fix_modify, output, run start/stop, minimize info:]
+
+No information about this fix is written to "binary restart
+files"_restart.html. None of the "fix_modify"_fix_modify.html options
+are relevant to this fix. No global or per-atom quantities are stored
+by this fix for access by various "output
+commands"_Section_howto.html#howto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
+This fix is not invoked during "energy minimization"_minimize.html.
+
+[Restrictions:]
+
+This fix is part of the ASPHERE package. It is only enabled if LAMMPS
+was built with that package. See the "Making
+LAMMPS"_Section_start.html#start_3 section for more info.
+
+This fix requires that particles be line segments as defined by the
+"atom_style line"_atom_style.html command.
+
+[Related commands:]
+
+"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html
+
+[Default:] none
diff --git a/doc/fix_nve_tri.html b/doc/fix_nve_tri.html
new file mode 100644
index 0000000000..cddb90aba3
--- /dev/null
+++ b/doc/fix_nve_tri.html
@@ -0,0 +1,60 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+fix nve/tri command
+
+Syntax:
+
+fix ID group-ID nve/tri
+
+- ID, group-ID are documented in fix command
+
- nve/tri = style name of this fix command
+
+Examples:
+
+fix 1 all nve/tri
+
+Description:
+
+Perform constant NVE integration to update position, velocity,
+orientation, and angular momentum for triangular particles in the
+group each timestep. V is volume; E is energy. This creates a system
+trajectory consistent with the microcanonical ensemble.
+
+This fix differs from the fix nve command, which
+assumes point particles and only updates their position and velocity.
+
+Restart, fix_modify, output, run start/stop, minimize info:
+
+No information about this fix is written to binary restart
+files. None of the fix_modify options
+are relevant to this fix. No global or per-atom quantities are stored
+by this fix for access by various output
+commands. No parameter of this fix can
+be used with the start/stop keywords of the run command.
+This fix is not invoked during energy minimization.
+
+Restrictions:
+
+This fix is part of the ASPHERE package. It is only enabled if LAMMPS
+was built with that package. See the Making
+LAMMPS section for more info.
+
+This fix requires that particles be triangles as defined by the
+atom_style tri command.
+
+Related commands:
+
+fix nve, fix nve/asphere
+
+Default: none
+
+
diff --git a/doc/fix_nve_tri.txt b/doc/fix_nve_tri.txt
new file mode 100755
index 0000000000..6ea568b4ea
--- /dev/null
+++ b/doc/fix_nve_tri.txt
@@ -0,0 +1,55 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+fix nve/tri command :h3
+
+[Syntax:]
+
+fix ID group-ID nve/tri :pre
+
+ID, group-ID are documented in "fix"_fix.html command
+nve/tri = style name of this fix command :ul
+
+[Examples:]
+
+fix 1 all nve/tri :pre
+
+[Description:]
+
+Perform constant NVE integration to update position, velocity,
+orientation, and angular momentum for triangular particles in the
+group each timestep. V is volume; E is energy. This creates a system
+trajectory consistent with the microcanonical ensemble.
+
+This fix differs from the "fix nve"_fix_nve.html command, which
+assumes point particles and only updates their position and velocity.
+
+[Restart, fix_modify, output, run start/stop, minimize info:]
+
+No information about this fix is written to "binary restart
+files"_restart.html. None of the "fix_modify"_fix_modify.html options
+are relevant to this fix. No global or per-atom quantities are stored
+by this fix for access by various "output
+commands"_Section_howto.html#howto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
+This fix is not invoked during "energy minimization"_minimize.html.
+
+[Restrictions:]
+
+This fix is part of the ASPHERE package. It is only enabled if LAMMPS
+was built with that package. See the "Making
+LAMMPS"_Section_start.html#start_3 section for more info.
+
+This fix requires that particles be triangles as defined by the
+"atom_style tri"_atom_style.html command.
+
+[Related commands:]
+
+"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html
+
+[Default:] none
diff --git a/doc/pair_line.html b/doc/pair_line.html
new file mode 100644
index 0000000000..205c5f3f91
--- /dev/null
+++ b/doc/pair_line.html
@@ -0,0 +1,117 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+pair_style line command
+
+Syntax:
+
+pair_style line cutoff
+
+cutoff = global cutoff for interactions (distance units)
+
+Examples:
+
+pair_style line 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5
+
+Description:
+
+Style line treats particles which are line segments as a set of
+small spherical particles that tile the line segment length as
+explained below. Interactions between two line segments, each with N1
+and N2 spherical particles, are calculated as the pairwise sum of
+N1*N2 Lennard-Jones interactions. Interactions between a line segment
+with N spherical particles and a point particle are treated as the
+pairwise sum of N Lennard-Jones interactions. See the pair_style
+lj/cut doc page for the definition of Lennard-Jones
+interactions.
+
+The cutoff distance for an interaction between 2 line segments, or
+between a line segment and a point particle, is calculated from the
+position of the line segment (its center), not between pairs of
+individual spheres comprising the line segment. Thus an interaction
+is either calculated in its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a line
+segment, for purposes of this pair style, are generated in the
+following manner. Their size is a function of the line segment length
+and the specified sigma for that particle type. If a line segment has
+a length L and is of type I, then the number of spheres N that
+represent the segment is calculated as N = L/sigma_II, rounded up to
+an integer value. Thus if L is not evenly divisibly by sigam_II, N is
+incremented to include one extra sphere. In this case, the spheres
+must be slightly smaller than sigma_II so as not to overlap, so a new
+sigma-prime is chosen as the sphere diameter, such that L/N =
+sigma-prime. Thus the line segment interacts with other segments or
+point particles as a collection of N spheres of diameter sigma-prime,
+evenly spaced along the line segment, so as to exactly cover its
+length.
+
+The LJ interaction between 2 spheres on different line segments of
+types I,J is computed with an arithmetic mixing of the sigma values of
+the 2 spheres and using the specified epsilon value for I,J atom
+types. Note that because the sigma values for line segment spheres is
+computed using only sigma_II values, specific to the line segment's
+type, this means that any specified sigma_IJ values (for I != J) are
+effectively ignored.
+
+For style line, the following coefficients must be defined for each
+pair of atoms types via the pair_coeff command as in
+the examples above, or in the data file or restart files read by the
+read_data or read_restart
+commands:
+
+- epsilon (energy units)
+
- sigma (distance units)
+
- cutoff (distance units)
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+
+
+Mixing, shift, table, tail correction, restart, rRESPA info:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is geometric. See the "pair_modify" command for
+details.
+
+This pair style does not support the pair_modify
+shift, table, and tail options.
+
+This pair style does not write its information to binary restart
+files.
+
+This pair style can only be used via the pair keyword of the
+run_style respa command. It does not support the
+inner, middle, outer keywords.
+
+
+
+Restrictions:
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the Making
+LAMMPS section for more info.
+
+Defining particles to be line segments so they participate in
+line/line or line/particle interactions requires the use the
+atom_style line command.
+
+Related commands:
+
+pair_coeff
+
+Default: none
+
+
diff --git a/doc/pair_line.txt b/doc/pair_line.txt
new file mode 100644
index 0000000000..160800250b
--- /dev/null
+++ b/doc/pair_line.txt
@@ -0,0 +1,112 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style line command :h3
+
+[Syntax:]
+
+pair_style line cutoff :pre
+
+cutoff = global cutoff for interactions (distance units)
+
+[Examples:]
+
+pair_style line 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5 :pre
+
+[Description:]
+
+Style {line} treats particles which are line segments as a set of
+small spherical particles that tile the line segment length as
+explained below. Interactions between two line segments, each with N1
+and N2 spherical particles, are calculated as the pairwise sum of
+N1*N2 Lennard-Jones interactions. Interactions between a line segment
+with N spherical particles and a point particle are treated as the
+pairwise sum of N Lennard-Jones interactions. See the "pair_style
+lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones
+interactions.
+
+The cutoff distance for an interaction between 2 line segments, or
+between a line segment and a point particle, is calculated from the
+position of the line segment (its center), not between pairs of
+individual spheres comprising the line segment. Thus an interaction
+is either calculated in its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a line
+segment, for purposes of this pair style, are generated in the
+following manner. Their size is a function of the line segment length
+and the specified sigma for that particle type. If a line segment has
+a length L and is of type I, then the number of spheres N that
+represent the segment is calculated as N = L/sigma_II, rounded up to
+an integer value. Thus if L is not evenly divisibly by sigam_II, N is
+incremented to include one extra sphere. In this case, the spheres
+must be slightly smaller than sigma_II so as not to overlap, so a new
+sigma-prime is chosen as the sphere diameter, such that L/N =
+sigma-prime. Thus the line segment interacts with other segments or
+point particles as a collection of N spheres of diameter sigma-prime,
+evenly spaced along the line segment, so as to exactly cover its
+length.
+
+The LJ interaction between 2 spheres on different line segments of
+types I,J is computed with an arithmetic mixing of the sigma values of
+the 2 spheres and using the specified epsilon value for I,J atom
+types. Note that because the sigma values for line segment spheres is
+computed using only sigma_II values, specific to the line segment's
+type, this means that any specified sigma_IJ values (for I != J) are
+effectively ignored.
+
+For style {line}, the following coefficients must be defined for each
+pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
+the examples above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+epsilon (energy units)
+sigma (distance units)
+cutoff (distance units) :ul
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is {geometric}. See the "pair_modify" command for
+details.
+
+This pair style does not support the "pair_modify"_pair_modify.html
+shift, table, and tail options.
+
+This pair style does not write its information to "binary restart
+files"_restart.html.
+
+This pair style can only be used via the {pair} keyword of the
+"run_style respa"_run_style.html command. It does not support the
+{inner}, {middle}, {outer} keywords.
+
+:line
+
+[Restrictions:]
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the "Making
+LAMMPS"_Section_start.html#2_3 section for more info.
+
+Defining particles to be line segments so they participate in
+line/line or line/particle interactions requires the use the
+"atom_style line"_atom_style.html command.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html
+
+[Default:] none
diff --git a/doc/pair_tri.html b/doc/pair_tri.html
new file mode 100644
index 0000000000..931819e107
--- /dev/null
+++ b/doc/pair_tri.html
@@ -0,0 +1,120 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+pair_style tri command
+
+Syntax:
+
+pair_style tri cutoff
+
+cutoff = global cutoff for interactions (distance units)
+
+Examples:
+
+pair_style tri 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5
+
+Description:
+
+Style tri treats particles which are triangles as a set of small
+spherical particles that tile the triangle surface as explained below.
+Interactions between two triangles, each with N1 and N2 spherical
+particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
+interactions. Interactions between a triangle with N spherical
+particles and a point particle are treated as the pairwise sum of N
+Lennard-Jones interactions. See the pair_style lj/cut
+doc page for the definition of Lennard-Jones interactions.
+
+The cutoff distance for an interaction between 2 triangles, or between
+a triangle and a point particle, is calculated from the position of
+the triangle (its centroid), not between pairs of individual spheres
+comprising the triangle. Thus an interaction is either calculated in
+its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a
+triangle, for purposes of this pair style, are generated in the
+following manner. Assume the triangle is of type I, and sigma_II has
+been specified. We want a set of spheres with centers in the plane of
+the triangle, none of them larger in diameter than sigma_II, which
+completely cover the triangle's area, but with minimial overlap and a
+minimal total number of spheres. This is done in a recursive manner.
+Place a sphere at the centroid of the original triangle. Calculate
+what diameter it must have to just cover all 3 corner points of the
+triangle. If that diameter is equal to or smaller than sigma_II, then
+include a sphere of the calculated diameter in the set of covering
+spheres. It the diameter is larger than sigma_II, then split the
+triangle into 2 triangles by bisecting its longest side. Repeat the
+process on each sub-triangle, recursing as far as needed to generate a
+set of covering spheres. When finished, the original criteria are
+met, and the set of covering spheres shoule be near minimal in number
+and overlap, at least for input triangles with a reasonable
+aspect-ratio.
+
+The LJ interaction between 2 spheres on different triangles of types
+I,J is computed with an arithmetic mixing of the sigma values of the 2
+spheres and using the specified epsilon value for I,J atom types.
+Note that because the sigma values for triangles spheres is computed
+using only sigma_II values, specific to the triangles's type, this
+means that any specified sigma_IJ values (for I != J) are effectively
+ignored.
+
+For style tri, the following coefficients must be defined for each
+pair of atoms types via the pair_coeff command as in
+the examples above, or in the data file or restart files read by the
+read_data or read_restart
+commands:
+
+- epsilon (energy units)
+
- sigma (distance units)
+
- cutoff (distance units)
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+
+
+Mixing, shift, table, tail correction, restart, rRESPA info:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is geometric. See the "pair_modify" command for
+details.
+
+This pair style does not support the pair_modify
+shift, table, and tail options.
+
+This pair style does not write its information to binary restart
+files.
+
+This pair style can only be used via the pair keyword of the
+run_style respa command. It does not support the
+inner, middle, outer keywords.
+
+
+
+Restrictions:
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the Making
+LAMMPS section for more info.
+
+Defining particles to be triangles so they participate in tri/tri or
+tri/particle interactions requires the use the atom_style
+tri command.
+
+Related commands:
+
+pair_coeff
+
+Default: none
+
+
diff --git a/doc/pair_tri.txt b/doc/pair_tri.txt
new file mode 100644
index 0000000000..47aea453e5
--- /dev/null
+++ b/doc/pair_tri.txt
@@ -0,0 +1,115 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style tri command :h3
+
+[Syntax:]
+
+pair_style tri cutoff :pre
+
+cutoff = global cutoff for interactions (distance units)
+
+[Examples:]
+
+pair_style tri 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5 :pre
+
+[Description:]
+
+Style {tri} treats particles which are triangles as a set of small
+spherical particles that tile the triangle surface as explained below.
+Interactions between two triangles, each with N1 and N2 spherical
+particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
+interactions. Interactions between a triangle with N spherical
+particles and a point particle are treated as the pairwise sum of N
+Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html
+doc page for the definition of Lennard-Jones interactions.
+
+The cutoff distance for an interaction between 2 triangles, or between
+a triangle and a point particle, is calculated from the position of
+the triangle (its centroid), not between pairs of individual spheres
+comprising the triangle. Thus an interaction is either calculated in
+its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a
+triangle, for purposes of this pair style, are generated in the
+following manner. Assume the triangle is of type I, and sigma_II has
+been specified. We want a set of spheres with centers in the plane of
+the triangle, none of them larger in diameter than sigma_II, which
+completely cover the triangle's area, but with minimial overlap and a
+minimal total number of spheres. This is done in a recursive manner.
+Place a sphere at the centroid of the original triangle. Calculate
+what diameter it must have to just cover all 3 corner points of the
+triangle. If that diameter is equal to or smaller than sigma_II, then
+include a sphere of the calculated diameter in the set of covering
+spheres. It the diameter is larger than sigma_II, then split the
+triangle into 2 triangles by bisecting its longest side. Repeat the
+process on each sub-triangle, recursing as far as needed to generate a
+set of covering spheres. When finished, the original criteria are
+met, and the set of covering spheres shoule be near minimal in number
+and overlap, at least for input triangles with a reasonable
+aspect-ratio.
+
+The LJ interaction between 2 spheres on different triangles of types
+I,J is computed with an arithmetic mixing of the sigma values of the 2
+spheres and using the specified epsilon value for I,J atom types.
+Note that because the sigma values for triangles spheres is computed
+using only sigma_II values, specific to the triangles's type, this
+means that any specified sigma_IJ values (for I != J) are effectively
+ignored.
+
+For style {tri}, the following coefficients must be defined for each
+pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
+the examples above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+epsilon (energy units)
+sigma (distance units)
+cutoff (distance units) :ul
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is {geometric}. See the "pair_modify" command for
+details.
+
+This pair style does not support the "pair_modify"_pair_modify.html
+shift, table, and tail options.
+
+This pair style does not write its information to "binary restart
+files"_restart.html.
+
+This pair style can only be used via the {pair} keyword of the
+"run_style respa"_run_style.html command. It does not support the
+{inner}, {middle}, {outer} keywords.
+
+:line
+
+[Restrictions:]
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the "Making
+LAMMPS"_Section_start.html#2_3 section for more info.
+
+Defining particles to be triangles so they participate in tri/tri or
+tri/particle interactions requires the use the "atom_style
+tri"_atom_style.html command.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html
+
+[Default:] none
From 29ce252d9ab37e7fb2decea62b3871fef2f2bc1e Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:06:55 +0000
Subject: [PATCH 36/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7151
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/Section_commands.html | 30 +++++++++++++++---------------
doc/Section_commands.txt | 4 ++++
doc/fix.html | 1 -
doc/fix.txt | 1 -
doc/pair_coeff.html | 2 ++
doc/pair_coeff.txt | 2 ++
doc/pair_style.html | 2 ++
doc/pair_style.txt | 2 ++
8 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/doc/Section_commands.html b/doc/Section_commands.html
index 839ca37981..1781bf3b32 100644
--- a/doc/Section_commands.html
+++ b/doc/Section_commands.html
@@ -341,12 +341,12 @@ of each style or click on the style itself for a full description:
| efield | enforce2d | evaporate | external | freeze | gcmc | gravity | heat |
| indent | langevin | lineforce | momentum | move | msst | neb | nph |
| nphug | nph/asphere | nph/sphere | npt | npt/asphere | npt/sphere | nve | nve/asphere |
-| nve/limit | nve/noforce | nve/sphere | nvt | nvt/asphere | nvt/sllod | nvt/sphere | orient/fcc |
-| planeforce | poems | pour | press/berendsen | print | qeq/comb | reax/bonds | recenter |
-| restrain | rigid | rigid/nve | rigid/nvt | setforce | shake | spring | spring/rg |
-| spring/self | srd | store/force | store/state | temp/berendsen | temp/rescale | thermal/conductivity | tmd |
-| ttm | viscosity | viscous | wall/colloid | wall/gran | wall/harmonic | wall/lj126 | wall/lj93 |
-| wall/reflect | wall/region | wall/srd
+ |
| nve/limit | nve/line | nve/noforce | nve/sphere | nve/tri | nvt | nvt/asphere | nvt/sllod |
+| nvt/sphere | orient/fcc | planeforce | poems | pour | press/berendsen | print | qeq/comb |
+| reax/bonds | recenter | restrain | rigid | rigid/nve | rigid/nvt | setforce | shake |
+| spring | spring/rg | spring/self | srd | store/force | store/state | temp/berendsen | temp/rescale |
+| thermal/conductivity | tmd | ttm | viscosity | viscous | wall/colloid | wall/gran | wall/harmonic |
+| wall/lj126 | wall/lj93 | wall/reflect | wall/region | wall/srd
|
These are fix styles contributed by users, which can be used if
@@ -419,15 +419,15 @@ potentials. Click on the style itself for a full description:
| dpd | dpd/tstat | dsmc | eam |
| eam/alloy | eam/fs | eim | gauss |
| gayberne | gran/hertz/history | gran/hooke | gran/hooke/history |
-| hbond/dreiding/lj | hbond/dreiding/morse | lj/charmm/coul/charmm | lj/charmm/coul/charmm/implicit |
-| lj/charmm/coul/long | lj/class2 | lj/class2/coul/cut | lj/class2/coul/long |
-| lj/cut | lj/cut/coul/cut | lj/cut/coul/debye | lj/cut/coul/long |
-| lj/cut/coul/long/tip4p | lj/expand | lj/gromacs | lj/gromacs/coul/gromacs |
-| lj/smooth | lj96/cut | lubricate | meam |
-| morse | peri/lps | peri/pmb | reax |
-| rebo | resquared | soft | sw |
-| table | tersoff | tersoff/zbl | yukawa |
-| yukawa/colloid
+ |
| hbond/dreiding/lj | hbond/dreiding/morse | line/lj | lj/charmm/coul/charmm |
+| lj/charmm/coul/charmm/implicit | lj/charmm/coul/long | lj/class2 | lj/class2/coul/cut |
+| lj/class2/coul/long | lj/cut | lj/cut/coul/cut | lj/cut/coul/debye |
+| lj/cut/coul/long | lj/cut/coul/long/tip4p | lj/expand | lj/gromacs |
+| lj/gromacs/coul/gromacs | lj/smooth | lj96/cut | lubricate |
+| meam | morse | peri/lps | peri/pmb |
+| reax | rebo | resquared | soft |
+| sw | table | tersoff | tersoff/zbl |
+| tri/lj | yukawa | yukawa/colloid
|
These are pair styles contributed by users, which can be used if
diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt
index d6e2e5dd17..67700fd323 100644
--- a/doc/Section_commands.txt
+++ b/doc/Section_commands.txt
@@ -438,8 +438,10 @@ of each style or click on the style itself for a full description:
"nve"_fix_nve.html,
"nve/asphere"_fix_nve_asphere.html,
"nve/limit"_fix_nve_limit.html,
+"nve/line"_fix_nve_line.html,
"nve/noforce"_fix_nve_noforce.html,
"nve/sphere"_fix_nve_sphere.html,
+"nve/tri"_fix_nve_tri.html,
"nvt"_fix_nh.html,
"nvt/asphere"_fix_nvt_asphere.html,
"nvt/sllod"_fix_nvt_sllod.html,
@@ -638,6 +640,7 @@ potentials. Click on the style itself for a full description:
"gran/hooke/history"_pair_gran.html,
"hbond/dreiding/lj"_pair_hbond_dreiding.html,
"hbond/dreiding/morse"_pair_hbond_dreiding.html,
+"line/lj"_pair_line_lj.html,
"lj/charmm/coul/charmm"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit"_pair_charmm.html,
"lj/charmm/coul/long"_pair_charmm.html,
@@ -667,6 +670,7 @@ potentials. Click on the style itself for a full description:
"table"_pair_table.html,
"tersoff"_pair_tersoff.html,
"tersoff/zbl"_pair_tersoff_zbl.html,
+"tri/lj"_pair_tri_lj.html,
"yukawa"_pair_yukawa.html,
"yukawa/colloid"_pair_yukawa_colloid.html :tb(c=4,ea=c)
diff --git a/doc/fix.html b/doc/fix.html
index c005536590..6d84638722 100644
--- a/doc/fix.html
+++ b/doc/fix.html
@@ -184,7 +184,6 @@ list of fix styles available in LAMMPS:
- gcmc - grand canonical insertions/deletions
- heat - add/subtract momentum-conserving heat
- indent - impose force due to an indenter
-
- integrateU - Stokesian Dynamics evolution
- langevin - Langevin temperature control
- lineforce - constrain atoms to move in a line
- momentum - zero the linear and/or angular momentum of a group of atoms
diff --git a/doc/fix.txt b/doc/fix.txt
index 6f59881200..6b824cf10c 100644
--- a/doc/fix.txt
+++ b/doc/fix.txt
@@ -179,7 +179,6 @@ list of fix styles available in LAMMPS:
"gcmc"_fix_gcmc.html - grand canonical insertions/deletions
"heat"_fix_heat.html - add/subtract momentum-conserving heat
"indent"_fix_indent.html - impose force due to an indenter
-"integrateU"_fix_integrateU.html - Stokesian Dynamics evolution
"langevin"_fix_langevin.html - Langevin temperature control
"lineforce"_fix_lineforce.html - constrain atoms to move in a line
"momentum"_fix_momentum.html - zero the linear and/or angular momentum of a group of atoms
diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html
index fb5ffd893a..750a34767b 100644
--- a/doc/pair_coeff.html
+++ b/doc/pair_coeff.html
@@ -113,6 +113,7 @@ the pair_style command, and coefficients specified by the associated
- pair_style gran/hooke/history - granular potential without history effects
- pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
- pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential
+
- pair_style line/lj - LJ potential between line segments
- pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
- pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
- pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb
@@ -142,6 +143,7 @@ the pair_style command, and coefficients specified by the associated
- pair_style table - tabulated pair potential
- pair_style tersoff - Tersoff 3-body potential
- pair_style tersoff/zbl - Tersoff/ZBL 3-body potential
+
- pair_style tri/lj - LJ potential between triangles
- pair_style yukawa - Yukawa potential
- pair_style yukawa/colloid - screened Yukawa potential for finite-size particles
diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt
index 5a6c00a247..02aebc35f6 100644
--- a/doc/pair_coeff.txt
+++ b/doc/pair_coeff.txt
@@ -110,6 +110,7 @@ the pair_style command, and coefficients specified by the associated
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
+"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
@@ -139,6 +140,7 @@ the pair_style command, and coefficients specified by the associated
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
+"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
diff --git a/doc/pair_style.html b/doc/pair_style.html
index 0fd6871819..b00d2360e5 100644
--- a/doc/pair_style.html
+++ b/doc/pair_style.html
@@ -115,6 +115,7 @@ the pair_style command, and coefficients specified by the associated
- pair_style gran/hooke/history - granular potential without history effects
- pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
- pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential
+
- pair_style line/lj - LJ potential between line segments
- pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
- pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
- pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb
@@ -144,6 +145,7 @@ the pair_style command, and coefficients specified by the associated
- pair_style table - tabulated pair potential
- pair_style tersoff - Tersoff 3-body potential
- pair_style tersoff/zbl - Tersoff/ZBL 3-body potential
+
- pair_style tri/lj - LJ potential between triangles
- pair_style yukawa - Yukawa potential
- pair_style yukawa/colloid - screened Yukawa potential for finite-size particles
diff --git a/doc/pair_style.txt b/doc/pair_style.txt
index d7ae16d690..c450e3272a 100644
--- a/doc/pair_style.txt
+++ b/doc/pair_style.txt
@@ -112,6 +112,7 @@ the pair_style command, and coefficients specified by the associated
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
+"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
@@ -141,6 +142,7 @@ the pair_style command, and coefficients specified by the associated
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
+"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
From 522e626bc9596dfb12853206afd6f48ca5c08b0c Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:07:41 +0000
Subject: [PATCH 37/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7152
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/pair_line_lj.html | 117 ++++++++++++++++++++++++++++++++++++++++
doc/pair_line_lj.txt | 112 +++++++++++++++++++++++++++++++++++++++
doc/pair_tri_lj.html | 120 ++++++++++++++++++++++++++++++++++++++++++
doc/pair_tri_lj.txt | 115 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 464 insertions(+)
create mode 100644 doc/pair_line_lj.html
create mode 100644 doc/pair_line_lj.txt
create mode 100644 doc/pair_tri_lj.html
create mode 100644 doc/pair_tri_lj.txt
diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html
new file mode 100644
index 0000000000..205c5f3f91
--- /dev/null
+++ b/doc/pair_line_lj.html
@@ -0,0 +1,117 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+pair_style line command
+
+Syntax:
+
+pair_style line cutoff
+
+cutoff = global cutoff for interactions (distance units)
+
+Examples:
+
+pair_style line 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5
+
+Description:
+
+Style line treats particles which are line segments as a set of
+small spherical particles that tile the line segment length as
+explained below. Interactions between two line segments, each with N1
+and N2 spherical particles, are calculated as the pairwise sum of
+N1*N2 Lennard-Jones interactions. Interactions between a line segment
+with N spherical particles and a point particle are treated as the
+pairwise sum of N Lennard-Jones interactions. See the pair_style
+lj/cut doc page for the definition of Lennard-Jones
+interactions.
+
+The cutoff distance for an interaction between 2 line segments, or
+between a line segment and a point particle, is calculated from the
+position of the line segment (its center), not between pairs of
+individual spheres comprising the line segment. Thus an interaction
+is either calculated in its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a line
+segment, for purposes of this pair style, are generated in the
+following manner. Their size is a function of the line segment length
+and the specified sigma for that particle type. If a line segment has
+a length L and is of type I, then the number of spheres N that
+represent the segment is calculated as N = L/sigma_II, rounded up to
+an integer value. Thus if L is not evenly divisibly by sigam_II, N is
+incremented to include one extra sphere. In this case, the spheres
+must be slightly smaller than sigma_II so as not to overlap, so a new
+sigma-prime is chosen as the sphere diameter, such that L/N =
+sigma-prime. Thus the line segment interacts with other segments or
+point particles as a collection of N spheres of diameter sigma-prime,
+evenly spaced along the line segment, so as to exactly cover its
+length.
+
+The LJ interaction between 2 spheres on different line segments of
+types I,J is computed with an arithmetic mixing of the sigma values of
+the 2 spheres and using the specified epsilon value for I,J atom
+types. Note that because the sigma values for line segment spheres is
+computed using only sigma_II values, specific to the line segment's
+type, this means that any specified sigma_IJ values (for I != J) are
+effectively ignored.
+
+For style line, the following coefficients must be defined for each
+pair of atoms types via the pair_coeff command as in
+the examples above, or in the data file or restart files read by the
+read_data or read_restart
+commands:
+
+- epsilon (energy units)
+
- sigma (distance units)
+
- cutoff (distance units)
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+
+
+Mixing, shift, table, tail correction, restart, rRESPA info:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is geometric. See the "pair_modify" command for
+details.
+
+This pair style does not support the pair_modify
+shift, table, and tail options.
+
+This pair style does not write its information to binary restart
+files.
+
+This pair style can only be used via the pair keyword of the
+run_style respa command. It does not support the
+inner, middle, outer keywords.
+
+
+
+Restrictions:
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the Making
+LAMMPS section for more info.
+
+Defining particles to be line segments so they participate in
+line/line or line/particle interactions requires the use the
+atom_style line command.
+
+Related commands:
+
+pair_coeff
+
+Default: none
+
+
diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt
new file mode 100644
index 0000000000..160800250b
--- /dev/null
+++ b/doc/pair_line_lj.txt
@@ -0,0 +1,112 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style line command :h3
+
+[Syntax:]
+
+pair_style line cutoff :pre
+
+cutoff = global cutoff for interactions (distance units)
+
+[Examples:]
+
+pair_style line 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5 :pre
+
+[Description:]
+
+Style {line} treats particles which are line segments as a set of
+small spherical particles that tile the line segment length as
+explained below. Interactions between two line segments, each with N1
+and N2 spherical particles, are calculated as the pairwise sum of
+N1*N2 Lennard-Jones interactions. Interactions between a line segment
+with N spherical particles and a point particle are treated as the
+pairwise sum of N Lennard-Jones interactions. See the "pair_style
+lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones
+interactions.
+
+The cutoff distance for an interaction between 2 line segments, or
+between a line segment and a point particle, is calculated from the
+position of the line segment (its center), not between pairs of
+individual spheres comprising the line segment. Thus an interaction
+is either calculated in its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a line
+segment, for purposes of this pair style, are generated in the
+following manner. Their size is a function of the line segment length
+and the specified sigma for that particle type. If a line segment has
+a length L and is of type I, then the number of spheres N that
+represent the segment is calculated as N = L/sigma_II, rounded up to
+an integer value. Thus if L is not evenly divisibly by sigam_II, N is
+incremented to include one extra sphere. In this case, the spheres
+must be slightly smaller than sigma_II so as not to overlap, so a new
+sigma-prime is chosen as the sphere diameter, such that L/N =
+sigma-prime. Thus the line segment interacts with other segments or
+point particles as a collection of N spheres of diameter sigma-prime,
+evenly spaced along the line segment, so as to exactly cover its
+length.
+
+The LJ interaction between 2 spheres on different line segments of
+types I,J is computed with an arithmetic mixing of the sigma values of
+the 2 spheres and using the specified epsilon value for I,J atom
+types. Note that because the sigma values for line segment spheres is
+computed using only sigma_II values, specific to the line segment's
+type, this means that any specified sigma_IJ values (for I != J) are
+effectively ignored.
+
+For style {line}, the following coefficients must be defined for each
+pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
+the examples above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+epsilon (energy units)
+sigma (distance units)
+cutoff (distance units) :ul
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is {geometric}. See the "pair_modify" command for
+details.
+
+This pair style does not support the "pair_modify"_pair_modify.html
+shift, table, and tail options.
+
+This pair style does not write its information to "binary restart
+files"_restart.html.
+
+This pair style can only be used via the {pair} keyword of the
+"run_style respa"_run_style.html command. It does not support the
+{inner}, {middle}, {outer} keywords.
+
+:line
+
+[Restrictions:]
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the "Making
+LAMMPS"_Section_start.html#2_3 section for more info.
+
+Defining particles to be line segments so they participate in
+line/line or line/particle interactions requires the use the
+"atom_style line"_atom_style.html command.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html
+
+[Default:] none
diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html
new file mode 100644
index 0000000000..931819e107
--- /dev/null
+++ b/doc/pair_tri_lj.html
@@ -0,0 +1,120 @@
+
+LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
+
+
+
+
+
+
+
+
+
+pair_style tri command
+
+Syntax:
+
+pair_style tri cutoff
+
+cutoff = global cutoff for interactions (distance units)
+
+Examples:
+
+pair_style tri 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5
+
+Description:
+
+Style tri treats particles which are triangles as a set of small
+spherical particles that tile the triangle surface as explained below.
+Interactions between two triangles, each with N1 and N2 spherical
+particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
+interactions. Interactions between a triangle with N spherical
+particles and a point particle are treated as the pairwise sum of N
+Lennard-Jones interactions. See the pair_style lj/cut
+doc page for the definition of Lennard-Jones interactions.
+
+The cutoff distance for an interaction between 2 triangles, or between
+a triangle and a point particle, is calculated from the position of
+the triangle (its centroid), not between pairs of individual spheres
+comprising the triangle. Thus an interaction is either calculated in
+its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a
+triangle, for purposes of this pair style, are generated in the
+following manner. Assume the triangle is of type I, and sigma_II has
+been specified. We want a set of spheres with centers in the plane of
+the triangle, none of them larger in diameter than sigma_II, which
+completely cover the triangle's area, but with minimial overlap and a
+minimal total number of spheres. This is done in a recursive manner.
+Place a sphere at the centroid of the original triangle. Calculate
+what diameter it must have to just cover all 3 corner points of the
+triangle. If that diameter is equal to or smaller than sigma_II, then
+include a sphere of the calculated diameter in the set of covering
+spheres. It the diameter is larger than sigma_II, then split the
+triangle into 2 triangles by bisecting its longest side. Repeat the
+process on each sub-triangle, recursing as far as needed to generate a
+set of covering spheres. When finished, the original criteria are
+met, and the set of covering spheres shoule be near minimal in number
+and overlap, at least for input triangles with a reasonable
+aspect-ratio.
+
+The LJ interaction between 2 spheres on different triangles of types
+I,J is computed with an arithmetic mixing of the sigma values of the 2
+spheres and using the specified epsilon value for I,J atom types.
+Note that because the sigma values for triangles spheres is computed
+using only sigma_II values, specific to the triangles's type, this
+means that any specified sigma_IJ values (for I != J) are effectively
+ignored.
+
+For style tri, the following coefficients must be defined for each
+pair of atoms types via the pair_coeff command as in
+the examples above, or in the data file or restart files read by the
+read_data or read_restart
+commands:
+
+- epsilon (energy units)
+
- sigma (distance units)
+
- cutoff (distance units)
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+
+
+Mixing, shift, table, tail correction, restart, rRESPA info:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is geometric. See the "pair_modify" command for
+details.
+
+This pair style does not support the pair_modify
+shift, table, and tail options.
+
+This pair style does not write its information to binary restart
+files.
+
+This pair style can only be used via the pair keyword of the
+run_style respa command. It does not support the
+inner, middle, outer keywords.
+
+
+
+Restrictions:
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the Making
+LAMMPS section for more info.
+
+Defining particles to be triangles so they participate in tri/tri or
+tri/particle interactions requires the use the atom_style
+tri command.
+
+Related commands:
+
+pair_coeff
+
+Default: none
+
+
diff --git a/doc/pair_tri_lj.txt b/doc/pair_tri_lj.txt
new file mode 100644
index 0000000000..47aea453e5
--- /dev/null
+++ b/doc/pair_tri_lj.txt
@@ -0,0 +1,115 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style tri command :h3
+
+[Syntax:]
+
+pair_style tri cutoff :pre
+
+cutoff = global cutoff for interactions (distance units)
+
+[Examples:]
+
+pair_style tri 3.0
+pair_coeff * * 1.0 1.0
+pair_coeff 1 1 1.0 1.5 2.5 :pre
+
+[Description:]
+
+Style {tri} treats particles which are triangles as a set of small
+spherical particles that tile the triangle surface as explained below.
+Interactions between two triangles, each with N1 and N2 spherical
+particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
+interactions. Interactions between a triangle with N spherical
+particles and a point particle are treated as the pairwise sum of N
+Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html
+doc page for the definition of Lennard-Jones interactions.
+
+The cutoff distance for an interaction between 2 triangles, or between
+a triangle and a point particle, is calculated from the position of
+the triangle (its centroid), not between pairs of individual spheres
+comprising the triangle. Thus an interaction is either calculated in
+its entirety or not at all.
+
+The set of non-overlapping spherical particles that represent a
+triangle, for purposes of this pair style, are generated in the
+following manner. Assume the triangle is of type I, and sigma_II has
+been specified. We want a set of spheres with centers in the plane of
+the triangle, none of them larger in diameter than sigma_II, which
+completely cover the triangle's area, but with minimial overlap and a
+minimal total number of spheres. This is done in a recursive manner.
+Place a sphere at the centroid of the original triangle. Calculate
+what diameter it must have to just cover all 3 corner points of the
+triangle. If that diameter is equal to or smaller than sigma_II, then
+include a sphere of the calculated diameter in the set of covering
+spheres. It the diameter is larger than sigma_II, then split the
+triangle into 2 triangles by bisecting its longest side. Repeat the
+process on each sub-triangle, recursing as far as needed to generate a
+set of covering spheres. When finished, the original criteria are
+met, and the set of covering spheres shoule be near minimal in number
+and overlap, at least for input triangles with a reasonable
+aspect-ratio.
+
+The LJ interaction between 2 spheres on different triangles of types
+I,J is computed with an arithmetic mixing of the sigma values of the 2
+spheres and using the specified epsilon value for I,J atom types.
+Note that because the sigma values for triangles spheres is computed
+using only sigma_II values, specific to the triangles's type, this
+means that any specified sigma_IJ values (for I != J) are effectively
+ignored.
+
+For style {tri}, the following coefficients must be defined for each
+pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
+the examples above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+epsilon (energy units)
+sigma (distance units)
+cutoff (distance units) :ul
+
+The last coefficient is optional. If not specified, the global cutoff
+is used.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of this pair style can be mixed. The
+default mix value is {geometric}. See the "pair_modify" command for
+details.
+
+This pair style does not support the "pair_modify"_pair_modify.html
+shift, table, and tail options.
+
+This pair style does not write its information to "binary restart
+files"_restart.html.
+
+This pair style can only be used via the {pair} keyword of the
+"run_style respa"_run_style.html command. It does not support the
+{inner}, {middle}, {outer} keywords.
+
+:line
+
+[Restrictions:]
+
+This style is part of the ASPHERE package. It is only enabled if
+LAMMPS was built with that package. See the "Making
+LAMMPS"_Section_start.html#2_3 section for more info.
+
+Defining particles to be triangles so they participate in tri/tri or
+tri/particle interactions requires the use the "atom_style
+tri"_atom_style.html command.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html
+
+[Default:] none
From 8dfec21cf4494d2f01d49419e15ba75ec374309e Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:09:12 +0000
Subject: [PATCH 38/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7153
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/atom_style.html | 3 +-
doc/atom_style.txt | 3 +-
doc/pair_line.html | 117 ------------------------------------------
doc/pair_line.txt | 112 -----------------------------------------
doc/pair_tri.html | 120 --------------------------------------------
doc/pair_tri.txt | 115 ------------------------------------------
6 files changed, 2 insertions(+), 468 deletions(-)
delete mode 100644 doc/pair_line.html
delete mode 100644 doc/pair_line.txt
delete mode 100644 doc/pair_tri.html
delete mode 100644 doc/pair_tri.txt
diff --git a/doc/atom_style.html b/doc/atom_style.html
index 8b16f36569..77ca19b72f 100644
--- a/doc/atom_style.html
+++ b/doc/atom_style.html
@@ -140,8 +140,7 @@ section.
The angle, bond, full, and molecular styles are part of the
MOLECULAR package. The dipole style is part of the "dipole"
-package. The ellipsoid, line, and tri styles are part of the
-"asphere" package. The peri style is part of the PERI package for
+package. The peri style is part of the PERI package for
Peridynamics. The electron style is part of the USER-EFF package
for electronic force fields. The meso style is part
of the USER-SPH package for smoothed particle hydrodyanmics (SPH).
diff --git a/doc/atom_style.txt b/doc/atom_style.txt
index 5f85786a7a..ee0375927f 100644
--- a/doc/atom_style.txt
+++ b/doc/atom_style.txt
@@ -136,8 +136,7 @@ This command cannot be used after the simulation box is defined by a
The {angle}, {bond}, {full}, and {molecular} styles are part of the
MOLECULAR package. The {dipole} style is part of the "dipole"
-package. The {ellipsoid}, {line}, and {tri} styles are part of the
-"asphere" package. The {peri} style is part of the PERI package for
+package. The {peri} style is part of the PERI package for
Peridynamics. The {electron} style is part of the USER-EFF package
for "electronic force fields"_pair_eff.html. The {meso} style is part
of the USER-SPH package for smoothed particle hydrodyanmics (SPH).
diff --git a/doc/pair_line.html b/doc/pair_line.html
deleted file mode 100644
index 205c5f3f91..0000000000
--- a/doc/pair_line.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
-
-
-
-
-
-
-
-
-
-pair_style line command
-
-Syntax:
-
-pair_style line cutoff
-
-cutoff = global cutoff for interactions (distance units)
-
-Examples:
-
-pair_style line 3.0
-pair_coeff * * 1.0 1.0
-pair_coeff 1 1 1.0 1.5 2.5
-
-Description:
-
-Style line treats particles which are line segments as a set of
-small spherical particles that tile the line segment length as
-explained below. Interactions between two line segments, each with N1
-and N2 spherical particles, are calculated as the pairwise sum of
-N1*N2 Lennard-Jones interactions. Interactions between a line segment
-with N spherical particles and a point particle are treated as the
-pairwise sum of N Lennard-Jones interactions. See the pair_style
-lj/cut doc page for the definition of Lennard-Jones
-interactions.
-
-The cutoff distance for an interaction between 2 line segments, or
-between a line segment and a point particle, is calculated from the
-position of the line segment (its center), not between pairs of
-individual spheres comprising the line segment. Thus an interaction
-is either calculated in its entirety or not at all.
-
-The set of non-overlapping spherical particles that represent a line
-segment, for purposes of this pair style, are generated in the
-following manner. Their size is a function of the line segment length
-and the specified sigma for that particle type. If a line segment has
-a length L and is of type I, then the number of spheres N that
-represent the segment is calculated as N = L/sigma_II, rounded up to
-an integer value. Thus if L is not evenly divisibly by sigam_II, N is
-incremented to include one extra sphere. In this case, the spheres
-must be slightly smaller than sigma_II so as not to overlap, so a new
-sigma-prime is chosen as the sphere diameter, such that L/N =
-sigma-prime. Thus the line segment interacts with other segments or
-point particles as a collection of N spheres of diameter sigma-prime,
-evenly spaced along the line segment, so as to exactly cover its
-length.
-
-The LJ interaction between 2 spheres on different line segments of
-types I,J is computed with an arithmetic mixing of the sigma values of
-the 2 spheres and using the specified epsilon value for I,J atom
-types. Note that because the sigma values for line segment spheres is
-computed using only sigma_II values, specific to the line segment's
-type, this means that any specified sigma_IJ values (for I != J) are
-effectively ignored.
-
-For style line, the following coefficients must be defined for each
-pair of atoms types via the pair_coeff command as in
-the examples above, or in the data file or restart files read by the
-read_data or read_restart
-commands:
-
-- epsilon (energy units)
-
- sigma (distance units)
-
- cutoff (distance units)
-
-The last coefficient is optional. If not specified, the global cutoff
-is used.
-
-
-
-Mixing, shift, table, tail correction, restart, rRESPA info:
-
-For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of this pair style can be mixed. The
-default mix value is geometric. See the "pair_modify" command for
-details.
-
-This pair style does not support the pair_modify
-shift, table, and tail options.
-
-This pair style does not write its information to binary restart
-files.
-
-This pair style can only be used via the pair keyword of the
-run_style respa command. It does not support the
-inner, middle, outer keywords.
-
-
-
-Restrictions:
-
-This style is part of the ASPHERE package. It is only enabled if
-LAMMPS was built with that package. See the Making
-LAMMPS section for more info.
-
-Defining particles to be line segments so they participate in
-line/line or line/particle interactions requires the use the
-atom_style line command.
-
-Related commands:
-
-pair_coeff
-
-Default: none
-
-
diff --git a/doc/pair_line.txt b/doc/pair_line.txt
deleted file mode 100644
index 160800250b..0000000000
--- a/doc/pair_line.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
-
-:link(lws,http://lammps.sandia.gov)
-:link(ld,Manual.html)
-:link(lc,Section_commands.html#comm)
-
-:line
-
-pair_style line command :h3
-
-[Syntax:]
-
-pair_style line cutoff :pre
-
-cutoff = global cutoff for interactions (distance units)
-
-[Examples:]
-
-pair_style line 3.0
-pair_coeff * * 1.0 1.0
-pair_coeff 1 1 1.0 1.5 2.5 :pre
-
-[Description:]
-
-Style {line} treats particles which are line segments as a set of
-small spherical particles that tile the line segment length as
-explained below. Interactions between two line segments, each with N1
-and N2 spherical particles, are calculated as the pairwise sum of
-N1*N2 Lennard-Jones interactions. Interactions between a line segment
-with N spherical particles and a point particle are treated as the
-pairwise sum of N Lennard-Jones interactions. See the "pair_style
-lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones
-interactions.
-
-The cutoff distance for an interaction between 2 line segments, or
-between a line segment and a point particle, is calculated from the
-position of the line segment (its center), not between pairs of
-individual spheres comprising the line segment. Thus an interaction
-is either calculated in its entirety or not at all.
-
-The set of non-overlapping spherical particles that represent a line
-segment, for purposes of this pair style, are generated in the
-following manner. Their size is a function of the line segment length
-and the specified sigma for that particle type. If a line segment has
-a length L and is of type I, then the number of spheres N that
-represent the segment is calculated as N = L/sigma_II, rounded up to
-an integer value. Thus if L is not evenly divisibly by sigam_II, N is
-incremented to include one extra sphere. In this case, the spheres
-must be slightly smaller than sigma_II so as not to overlap, so a new
-sigma-prime is chosen as the sphere diameter, such that L/N =
-sigma-prime. Thus the line segment interacts with other segments or
-point particles as a collection of N spheres of diameter sigma-prime,
-evenly spaced along the line segment, so as to exactly cover its
-length.
-
-The LJ interaction between 2 spheres on different line segments of
-types I,J is computed with an arithmetic mixing of the sigma values of
-the 2 spheres and using the specified epsilon value for I,J atom
-types. Note that because the sigma values for line segment spheres is
-computed using only sigma_II values, specific to the line segment's
-type, this means that any specified sigma_IJ values (for I != J) are
-effectively ignored.
-
-For style {line}, the following coefficients must be defined for each
-pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
-the examples above, or in the data file or restart files read by the
-"read_data"_read_data.html or "read_restart"_read_restart.html
-commands:
-
-epsilon (energy units)
-sigma (distance units)
-cutoff (distance units) :ul
-
-The last coefficient is optional. If not specified, the global cutoff
-is used.
-
-:line
-
-[Mixing, shift, table, tail correction, restart, rRESPA info]:
-
-For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of this pair style can be mixed. The
-default mix value is {geometric}. See the "pair_modify" command for
-details.
-
-This pair style does not support the "pair_modify"_pair_modify.html
-shift, table, and tail options.
-
-This pair style does not write its information to "binary restart
-files"_restart.html.
-
-This pair style can only be used via the {pair} keyword of the
-"run_style respa"_run_style.html command. It does not support the
-{inner}, {middle}, {outer} keywords.
-
-:line
-
-[Restrictions:]
-
-This style is part of the ASPHERE package. It is only enabled if
-LAMMPS was built with that package. See the "Making
-LAMMPS"_Section_start.html#2_3 section for more info.
-
-Defining particles to be line segments so they participate in
-line/line or line/particle interactions requires the use the
-"atom_style line"_atom_style.html command.
-
-[Related commands:]
-
-"pair_coeff"_pair_coeff.html
-
-[Default:] none
diff --git a/doc/pair_tri.html b/doc/pair_tri.html
deleted file mode 100644
index 931819e107..0000000000
--- a/doc/pair_tri.html
+++ /dev/null
@@ -1,120 +0,0 @@
-
-LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands
-
-
-
-
-
-
-
-
-
-pair_style tri command
-
-Syntax:
-
-pair_style tri cutoff
-
-cutoff = global cutoff for interactions (distance units)
-
-Examples:
-
-pair_style tri 3.0
-pair_coeff * * 1.0 1.0
-pair_coeff 1 1 1.0 1.5 2.5
-
-Description:
-
-Style tri treats particles which are triangles as a set of small
-spherical particles that tile the triangle surface as explained below.
-Interactions between two triangles, each with N1 and N2 spherical
-particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
-interactions. Interactions between a triangle with N spherical
-particles and a point particle are treated as the pairwise sum of N
-Lennard-Jones interactions. See the pair_style lj/cut
-doc page for the definition of Lennard-Jones interactions.
-
-The cutoff distance for an interaction between 2 triangles, or between
-a triangle and a point particle, is calculated from the position of
-the triangle (its centroid), not between pairs of individual spheres
-comprising the triangle. Thus an interaction is either calculated in
-its entirety or not at all.
-
-The set of non-overlapping spherical particles that represent a
-triangle, for purposes of this pair style, are generated in the
-following manner. Assume the triangle is of type I, and sigma_II has
-been specified. We want a set of spheres with centers in the plane of
-the triangle, none of them larger in diameter than sigma_II, which
-completely cover the triangle's area, but with minimial overlap and a
-minimal total number of spheres. This is done in a recursive manner.
-Place a sphere at the centroid of the original triangle. Calculate
-what diameter it must have to just cover all 3 corner points of the
-triangle. If that diameter is equal to or smaller than sigma_II, then
-include a sphere of the calculated diameter in the set of covering
-spheres. It the diameter is larger than sigma_II, then split the
-triangle into 2 triangles by bisecting its longest side. Repeat the
-process on each sub-triangle, recursing as far as needed to generate a
-set of covering spheres. When finished, the original criteria are
-met, and the set of covering spheres shoule be near minimal in number
-and overlap, at least for input triangles with a reasonable
-aspect-ratio.
-
-The LJ interaction between 2 spheres on different triangles of types
-I,J is computed with an arithmetic mixing of the sigma values of the 2
-spheres and using the specified epsilon value for I,J atom types.
-Note that because the sigma values for triangles spheres is computed
-using only sigma_II values, specific to the triangles's type, this
-means that any specified sigma_IJ values (for I != J) are effectively
-ignored.
-
-For style tri, the following coefficients must be defined for each
-pair of atoms types via the pair_coeff command as in
-the examples above, or in the data file or restart files read by the
-read_data or read_restart
-commands:
-
-- epsilon (energy units)
-
- sigma (distance units)
-
- cutoff (distance units)
-
-The last coefficient is optional. If not specified, the global cutoff
-is used.
-
-
-
-Mixing, shift, table, tail correction, restart, rRESPA info:
-
-For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of this pair style can be mixed. The
-default mix value is geometric. See the "pair_modify" command for
-details.
-
-This pair style does not support the pair_modify
-shift, table, and tail options.
-
-This pair style does not write its information to binary restart
-files.
-
-This pair style can only be used via the pair keyword of the
-run_style respa command. It does not support the
-inner, middle, outer keywords.
-
-
-
-Restrictions:
-
-This style is part of the ASPHERE package. It is only enabled if
-LAMMPS was built with that package. See the Making
-LAMMPS section for more info.
-
-Defining particles to be triangles so they participate in tri/tri or
-tri/particle interactions requires the use the atom_style
-tri command.
-
-Related commands:
-
-pair_coeff
-
-Default: none
-
-
diff --git a/doc/pair_tri.txt b/doc/pair_tri.txt
deleted file mode 100644
index 47aea453e5..0000000000
--- a/doc/pair_tri.txt
+++ /dev/null
@@ -1,115 +0,0 @@
-"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
-
-:link(lws,http://lammps.sandia.gov)
-:link(ld,Manual.html)
-:link(lc,Section_commands.html#comm)
-
-:line
-
-pair_style tri command :h3
-
-[Syntax:]
-
-pair_style tri cutoff :pre
-
-cutoff = global cutoff for interactions (distance units)
-
-[Examples:]
-
-pair_style tri 3.0
-pair_coeff * * 1.0 1.0
-pair_coeff 1 1 1.0 1.5 2.5 :pre
-
-[Description:]
-
-Style {tri} treats particles which are triangles as a set of small
-spherical particles that tile the triangle surface as explained below.
-Interactions between two triangles, each with N1 and N2 spherical
-particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
-interactions. Interactions between a triangle with N spherical
-particles and a point particle are treated as the pairwise sum of N
-Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html
-doc page for the definition of Lennard-Jones interactions.
-
-The cutoff distance for an interaction between 2 triangles, or between
-a triangle and a point particle, is calculated from the position of
-the triangle (its centroid), not between pairs of individual spheres
-comprising the triangle. Thus an interaction is either calculated in
-its entirety or not at all.
-
-The set of non-overlapping spherical particles that represent a
-triangle, for purposes of this pair style, are generated in the
-following manner. Assume the triangle is of type I, and sigma_II has
-been specified. We want a set of spheres with centers in the plane of
-the triangle, none of them larger in diameter than sigma_II, which
-completely cover the triangle's area, but with minimial overlap and a
-minimal total number of spheres. This is done in a recursive manner.
-Place a sphere at the centroid of the original triangle. Calculate
-what diameter it must have to just cover all 3 corner points of the
-triangle. If that diameter is equal to or smaller than sigma_II, then
-include a sphere of the calculated diameter in the set of covering
-spheres. It the diameter is larger than sigma_II, then split the
-triangle into 2 triangles by bisecting its longest side. Repeat the
-process on each sub-triangle, recursing as far as needed to generate a
-set of covering spheres. When finished, the original criteria are
-met, and the set of covering spheres shoule be near minimal in number
-and overlap, at least for input triangles with a reasonable
-aspect-ratio.
-
-The LJ interaction between 2 spheres on different triangles of types
-I,J is computed with an arithmetic mixing of the sigma values of the 2
-spheres and using the specified epsilon value for I,J atom types.
-Note that because the sigma values for triangles spheres is computed
-using only sigma_II values, specific to the triangles's type, this
-means that any specified sigma_IJ values (for I != J) are effectively
-ignored.
-
-For style {tri}, the following coefficients must be defined for each
-pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
-the examples above, or in the data file or restart files read by the
-"read_data"_read_data.html or "read_restart"_read_restart.html
-commands:
-
-epsilon (energy units)
-sigma (distance units)
-cutoff (distance units) :ul
-
-The last coefficient is optional. If not specified, the global cutoff
-is used.
-
-:line
-
-[Mixing, shift, table, tail correction, restart, rRESPA info]:
-
-For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of this pair style can be mixed. The
-default mix value is {geometric}. See the "pair_modify" command for
-details.
-
-This pair style does not support the "pair_modify"_pair_modify.html
-shift, table, and tail options.
-
-This pair style does not write its information to "binary restart
-files"_restart.html.
-
-This pair style can only be used via the {pair} keyword of the
-"run_style respa"_run_style.html command. It does not support the
-{inner}, {middle}, {outer} keywords.
-
-:line
-
-[Restrictions:]
-
-This style is part of the ASPHERE package. It is only enabled if
-LAMMPS was built with that package. See the "Making
-LAMMPS"_Section_start.html#2_3 section for more info.
-
-Defining particles to be triangles so they participate in tri/tri or
-tri/particle interactions requires the use the "atom_style
-tri"_atom_style.html command.
-
-[Related commands:]
-
-"pair_coeff"_pair_coeff.html
-
-[Default:] none
From fd155252ea24a3d24dd35f6e674b43981e718b5b Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:09:45 +0000
Subject: [PATCH 39/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7154
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/pair_line_lj.cpp | 444 ++++++++++++++++++++++++
src/ASPHERE/pair_line_lj.h | 61 ++++
src/ASPHERE/pair_tri_lj.cpp | 637 +++++++++++++++++++++++++++++++++++
src/ASPHERE/pair_tri_lj.h | 61 ++++
4 files changed, 1203 insertions(+)
create mode 100644 src/ASPHERE/pair_line_lj.cpp
create mode 100644 src/ASPHERE/pair_line_lj.h
create mode 100644 src/ASPHERE/pair_tri_lj.cpp
create mode 100644 src/ASPHERE/pair_tri_lj.h
diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp
new file mode 100644
index 0000000000..4a3902c888
--- /dev/null
+++ b/src/ASPHERE/pair_line_lj.cpp
@@ -0,0 +1,444 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_line.h"
+#include "atom.h"
+#include "atom_vec_line.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 10000
+
+/* ---------------------------------------------------------------------- */
+
+PairLine::PairLine(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecLine *) atom->style_match("line");
+ if (!avec) error->all(FLERR,"Pair line requires atom style line");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLine::~PairLine()
+{
+ memory->sfree(discrete);
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLine::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ double **torque = atom->torque;
+ int *line = atom->line;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ for (i = 0; i < nall; i++) dnum[i] = 0;
+ ndiscrete = 0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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]) continue;
+
+ // line/line interactions = NxN particles
+
+ evdwl = 0.0;
+ if (line[i] >= 0 && line[j] >= 0) {
+ if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
+ npi = dnum[i];
+ ifirst = dfirst[i];
+ if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ torque[i][2] += dxi*fi[1] - dyi*fi[0];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ torque[j][2] += dxj*fj[1] - dyj*fj[0];
+ }
+ }
+ }
+
+ // line/particle interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[i] >= 0) {
+ if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ torque[i][2] += dxi*fi[1] - dyi*fi[0];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ }
+ }
+
+ // particle/line interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[j] >= 0) {
+ if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+
+ if (newton_pair || j < nlocal) {
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ torque[j][2] += dxj*fj[1] - dyj*fj[0];
+ }
+ }
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (eflag)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairLine::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairLine::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // 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[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairLine::coeff(int narg, char **arg)
+{
+ if (narg < 4 || narg > 5)
+ error->all(FLERR,"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 = force->numeric(arg[2]);
+ double sigma_one = force->numeric(arg[3]);
+
+ double cut_one = cut_global;
+ if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairLine::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[i][j] = mix_distance(cut[i][i],cut[j][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);
+
+ epsilon[j][i] = epsilon[i][j];
+ sigma[j][i] = sigma[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];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ discretize line segment I into N sub-segments no more than sigma in length
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+void PairLine::discretize(int i, double sigma)
+{
+ AtomVecLine::Bonus *bonus = avec->bonus;
+ double length = bonus[atom->line[i]].length;
+ double theta = bonus[atom->line[i]].theta;
+ int n = static_cast (length/sigma) + 1;
+ dnum[i] = n;
+ dfirst[i] = ndiscrete;
+
+ if (ndiscrete + n > dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+
+ double *x = atom->x[i];
+ sigma = length/n;
+ double delta;
+
+ for (int m = 0; m < n; m++) {
+ delta = -0.5 + (2*m+1)/(2.0*n);
+ discrete[ndiscrete].dx = delta*length*cos(theta);
+ discrete[ndiscrete].dy = delta*length*sin(theta);
+ discrete[ndiscrete].sigma = sigma;
+ ndiscrete++;
+ }
+}
diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h
new file mode 100644
index 0000000000..6598bfe6c1
--- /dev/null
+++ b/src/ASPHERE/pair_line_lj.h
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(line,PairLine)
+
+#else
+
+#ifndef LMP_PAIR_LINE_H
+#define LMP_PAIR_LINE_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairLine : public Pair {
+ public:
+ PairLine(class LAMMPS *);
+ ~PairLine();
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+
+ protected:
+ double cut_global;
+ double **cut;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4;
+ class AtomVecLine *avec;
+
+ struct Discrete {
+ double dx,dy;
+ double sigma;
+ };
+ Discrete *discrete; // list of all discretes for all lines
+ int ndiscrete; // number of discretes in list
+ int dmax; // allocated size of discrete list
+ int *dnum; // number of discretes per line, 0 if uninit
+ int *dfirst; // index of first discrete per each line
+ int nmax; // allocated size of dnum,dfirst vectors
+
+ void allocate();
+ void discretize(int, double);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp
new file mode 100644
index 0000000000..0a40b8fb06
--- /dev/null
+++ b/src/ASPHERE/pair_tri_lj.cpp
@@ -0,0 +1,637 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_tri.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "atom_vec_tri.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 20
+
+/* ---------------------------------------------------------------------- */
+
+PairTri::PairTri(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecTri *) atom->style_match("tri");
+ if (!avec) error->all(FLERR,"Pair tri requires atom style tri");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairTri::~PairTri()
+{
+ memory->sfree(discrete);
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTri::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double dxi,dxj,dyi,dyj,dzi,dzj;
+ double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3];
+ double dc1[3],dc2[3],dc3[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ AtomVecTri::Bonus *bonus = avec->bonus;
+ double **x = atom->x;
+ double **f = atom->f;
+ double **torque = atom->torque;
+ int *tri = atom->tri;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ for (i = 0; i < nall; i++) dnum[i] = 0;
+ ndiscrete = 0;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ 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]) continue;
+
+ // tri/tri interactions = NxN particles
+ // c1,c2,c3 = corner pts of triangle I or J
+
+ evdwl = 0.0;
+ if (tri[i] >= 0 && tri[j] >= 0) {
+ if (dnum[i] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
+ dfirst[i] = ndiscrete;
+ discretize(i,sigma[itype][itype],dc1,dc2,dc3);
+ dnum[i] = ndiscrete - dfirst[i];
+ }
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ if (dnum[j] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
+ MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
+ dfirst[j] = ndiscrete;
+ discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
+ dnum[j] = ndiscrete - dfirst[j];
+ }
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ ti[0] = dyi*fi[2] - dzi*fi[1];
+ ti[1] = dzi*fi[0] - dxi*fi[2];
+ ti[2] = dxi*fi[1] - dyi*fi[0];
+ torque[i][0] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ tj[0] = dyj*fj[2] - dzj*fj[1];
+ tj[1] = dzj*fj[0] - dxj*fj[2];
+ tj[2] = dxj*fj[1] - dyj*fj[0];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+ }
+ }
+ }
+
+ // tri/particle interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle I
+
+ } else if (tri[i] >= 0) {
+
+ if (dnum[i] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
+ dfirst[i] = ndiscrete;
+ discretize(i,sigma[itype][itype],dc1,dc2,dc3);
+ dnum[i] = ndiscrete - dfirst[i];
+ }
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+ xj[2] = x[j][2];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ ti[0] = dyi*fi[2] - dzi*fi[1];
+ ti[1] = dzi*fi[0] - dxi*fi[2];
+ ti[2] = dxi*fi[1] - dyi*fi[0];
+ torque[i][2] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ }
+ }
+
+ // particle/tri interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle J
+
+ } else if (tri[j] >= 0) {
+ if (dnum[j] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
+ MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
+ dfirst[j] = ndiscrete;
+ discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
+ dnum[j] = ndiscrete - dfirst[j];
+ }
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xi[2] = x[i][2];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] = delx*fpair;
+ fi[1] = dely*fpair;
+ fi[2] = delz*fpair;
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+
+ if (newton_pair || j < nlocal) {
+ fj[0] = -delx*fpair;
+ fj[1] = -dely*fpair;
+ fj[2] = -delz*fpair;
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ tj[0] = dyj*fj[2] - dzj*fj[1];
+ tj[1] = dzj*fj[0] - dxj*fj[2];
+ tj[2] = dxj*fj[1] - dyj*fj[0];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+ }
+ }
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (eflag)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairTri::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairTri::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // 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[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairTri::coeff(int narg, char **arg)
+{
+ if (narg < 4 || narg > 5)
+ error->all(FLERR,"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 = force->numeric(arg[2]);
+ double sigma_one = force->numeric(arg[3]);
+
+ double cut_one = cut_global;
+ if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairTri::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[i][j] = mix_distance(cut[i][i],cut[j][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);
+
+ epsilon[j][i] = epsilon[i][j];
+ sigma[j][i] = sigma[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];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ recursively discretize triangle I with displaced corners c1,c2,c3
+ into N sub-tris no more than sigma in size
+ recurse by making 2 tris via bisecting longest side
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+void PairTri::discretize(int i, double sigma,
+ double *c1, double *c2, double *c3)
+{
+ double c1c2[3],c2c3[3],c1c3[3];
+
+ double centroid[3],dc1[3],dc2[3],dc3[3];
+
+ centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
+ centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
+ centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
+
+ MathExtra::sub3(c1,centroid,dc1);
+ MathExtra::sub3(c2,centroid,dc2);
+ MathExtra::sub3(c3,centroid,dc3);
+
+ double sigmasq = 0.25 * sigma*sigma;
+ double len1sq = MathExtra::lensq3(dc1);
+ double len2sq = MathExtra::lensq3(dc2);
+ double len3sq = MathExtra::lensq3(dc3);
+
+ // if sigma sphere overlaps all corner points, add particle at centroid
+
+ if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
+ if (ndiscrete == dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+ discrete[ndiscrete].dx = centroid[0];
+ discrete[ndiscrete].dy = centroid[1];
+ discrete[ndiscrete].dz = centroid[2];
+ sigmasq = MAX(len1sq,len2sq);
+ sigmasq = MAX(sigmasq,len3sq);
+ discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
+ ndiscrete++;
+ return;
+ }
+
+ // else break triangle into 2 sub-triangles and recurse
+
+ double c12[3],c23[3],c13[3],mid[3];
+
+ MathExtra::sub3(c2,c3,c23);
+ len1sq = MathExtra::lensq3(c23);
+ MathExtra::sub3(c1,c3,c13);
+ len2sq = MathExtra::lensq3(c13);
+ MathExtra::sub3(c1,c2,c12);
+ len3sq = MathExtra::lensq3(c12);
+
+ double maxsq = MAX(len1sq,len2sq);
+ maxsq = MAX(maxsq,len3sq);
+
+ if (len1sq == maxsq) {
+ MathExtra::add3(c2,c3,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c1,c2,mid);
+ discretize(i,sigma,c1,c3,mid);
+ } else if (len2sq == maxsq) {
+ MathExtra::add3(c1,c3,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c2,c1,mid);
+ discretize(i,sigma,c2,c3,mid);
+ } else {
+ MathExtra::add3(c1,c2,mid);
+ MathExtra::scale3(0.5,mid);
+ discretize(i,sigma,c3,c1,mid);
+ discretize(i,sigma,c3,c2,mid);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ recursively discretize triangle I with displaced corners c1,c2,c3
+ into N sub-tris no more than sigma in size
+ recurse by making 6 tris via centroid
+ store new discrete particles in Discrete list
+------------------------------------------------------------------------- */
+
+/*
+void PairTri::discretize(int i, double sigma,
+ double *c1, double *c2, double *c3)
+{
+ double centroid[3],dc1[3],dc2[3],dc3[3];
+
+ centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
+ centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
+ centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
+
+ MathExtra::sub3(c1,centroid,dc1);
+ MathExtra::sub3(c2,centroid,dc2);
+ MathExtra::sub3(c3,centroid,dc3);
+
+ double sigmasq = 0.25 * sigma*sigma;
+ double len1sq = MathExtra::lensq3(dc1);
+ double len2sq = MathExtra::lensq3(dc2);
+ double len3sq = MathExtra::lensq3(dc3);
+
+ // if sigma sphere overlaps all corner points, add particle at centroid
+
+ if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
+ if (ndiscrete == dmax) {
+ dmax += DELTA;
+ discrete = (Discrete *)
+ memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
+ }
+ discrete[ndiscrete].dx = centroid[0];
+ discrete[ndiscrete].dy = centroid[1];
+ discrete[ndiscrete].dz = centroid[2];
+ sigmasq = MAX(len1sq,len2sq);
+ sigmasq = MAX(sigmasq,len3sq);
+ discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
+ ndiscrete++;
+ return;
+ }
+
+ // else break triangle into 6 sub-triangles and recurse
+
+ double c1c2mid[3],c2c3mid[3],c1c3mid[3];
+
+ MathExtra::add3(c1,c2,c1c2mid);
+ MathExtra::scale3(0.5,c1c2mid);
+ MathExtra::add3(c2,c3,c2c3mid);
+ MathExtra::scale3(0.5,c2c3mid);
+ MathExtra::add3(c1,c3,c1c3mid);
+ MathExtra::scale3(0.5,c1c3mid);
+
+ discretize(i,sigma,c1,c1c2mid,centroid);
+ discretize(i,sigma,c1,c1c3mid,centroid);
+ discretize(i,sigma,c2,c2c3mid,centroid);
+ discretize(i,sigma,c2,c1c2mid,centroid);
+ discretize(i,sigma,c3,c1c3mid,centroid);
+ discretize(i,sigma,c3,c2c3mid,centroid);
+}
+
+*/
diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h
new file mode 100644
index 0000000000..fd1fe08bac
--- /dev/null
+++ b/src/ASPHERE/pair_tri_lj.h
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tri,PairTri)
+
+#else
+
+#ifndef LMP_PAIR_TRI_H
+#define LMP_PAIR_TRI_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairTri : public Pair {
+ public:
+ PairTri(class LAMMPS *);
+ ~PairTri();
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+
+ protected:
+ double cut_global;
+ double **cut;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4;
+ class AtomVecTri *avec;
+
+ struct Discrete {
+ double dx,dy,dz;
+ double sigma;
+ };
+ Discrete *discrete; // list of all discretes for all lines
+ int ndiscrete; // number of discretes in list
+ int dmax; // allocated size of discrete list
+ int *dnum; // number of discretes per line, 0 if uninit
+ int *dfirst; // index of first discrete per each line
+ int nmax; // allocated size of dnum,dfirst vectors
+
+ void allocate();
+ void discretize(int, double, double *, double *, double *);
+};
+
+}
+
+#endif
+#endif
From 8287969efa327bc5096118df84ffe8d0fdfa6c4e Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:10:28 +0000
Subject: [PATCH 40/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7155
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/Install.sh | 16 +-
src/ASPHERE/pair_line.cpp | 444 --------------------------
src/ASPHERE/pair_line.h | 61 ----
src/ASPHERE/pair_tri.cpp | 637 --------------------------------------
src/ASPHERE/pair_tri.h | 61 ----
5 files changed, 8 insertions(+), 1211 deletions(-)
delete mode 100644 src/ASPHERE/pair_line.cpp
delete mode 100644 src/ASPHERE/pair_line.h
delete mode 100644 src/ASPHERE/pair_tri.cpp
delete mode 100644 src/ASPHERE/pair_tri.h
diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh
index 2f6f974332..1cc7a4b61d 100644
--- a/src/ASPHERE/Install.sh
+++ b/src/ASPHERE/Install.sh
@@ -12,9 +12,9 @@ if (test $1 = 1) then
cp fix_nve_tri.cpp ..
cp fix_nvt_asphere.cpp ..
cp pair_gayberne.cpp ..
- cp pair_line.cpp ..
+ cp pair_line_lj.cpp ..
cp pair_resquared.cpp ..
- cp pair_tri.cpp ..
+ cp pair_tri_Lj.cpp ..
cp compute_erotate_asphere.h ..
cp compute_temp_asphere.h ..
@@ -26,9 +26,9 @@ if (test $1 = 1) then
cp fix_nve_tri.h ..
cp fix_nvt_asphere.h ..
cp pair_gayberne.h ..
- cp pair_line.h ..
+ cp pair_line_lj.h ..
cp pair_resquared.h ..
- cp pair_tri.h ..
+ cp pair_tri_lj.h ..
elif (test $1 = 0) then
@@ -42,9 +42,9 @@ elif (test $1 = 0) then
rm -f ../fix_nve_tri.cpp
rm -f ../fix_nvt_asphere.cpp
rm -f ../pair_gayberne.cpp
- rm -f ../pair_line.cpp
+ rm -f ../pair_line_lj.cpp
rm -f ../pair_resquared.cpp
- rm -f ../pair_tri.cpp
+ rm -f ../pair_tri_lj.cpp
rm -f ../compute_erotate_asphere.h
rm -f ../compute_temp_asphere.h
@@ -56,8 +56,8 @@ elif (test $1 = 0) then
rm -f ../fix_nve_tri.h
rm -f ../fix_nvt_asphere.h
rm -f ../pair_gayberne.h
- rm -f ../pair_line.h
+ rm -f ../pair_line_lj.h
rm -f ../pair_resquared.h
- rm -f ../pair_tri.h
+ rm -f ../pair_tri_lj.h
fi
diff --git a/src/ASPHERE/pair_line.cpp b/src/ASPHERE/pair_line.cpp
deleted file mode 100644
index 4a3902c888..0000000000
--- a/src/ASPHERE/pair_line.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#include "math.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "pair_line.h"
-#include "atom.h"
-#include "atom_vec_line.h"
-#include "force.h"
-#include "neighbor.h"
-#include "neigh_list.h"
-#include "memory.h"
-#include "error.h"
-
-using namespace LAMMPS_NS;
-
-#define DELTA 10000
-
-/* ---------------------------------------------------------------------- */
-
-PairLine::PairLine(LAMMPS *lmp) : Pair(lmp)
-{
- avec = (AtomVecLine *) atom->style_match("line");
- if (!avec) error->all(FLERR,"Pair line requires atom style line");
-
- dmax = nmax = 0;
- discrete = NULL;
- dnum = dfirst = NULL;
-
- single_enable = 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-PairLine::~PairLine()
-{
- memory->sfree(discrete);
- memory->destroy(dnum);
- memory->destroy(dfirst);
-
- if (allocated) {
- memory->destroy(setflag);
- memory->destroy(cutsq);
-
- memory->destroy(cut);
- memory->destroy(epsilon);
- memory->destroy(sigma);
- memory->destroy(lj1);
- memory->destroy(lj2);
- memory->destroy(lj3);
- memory->destroy(lj4);
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairLine::compute(int eflag, int vflag)
-{
- int i,j,ii,jj,inum,jnum,itype,jtype;
- int ni,nj,npi,npj,ifirst,jfirst;
- double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
- double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
- double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj;
- int *ilist,*jlist,*numneigh,**firstneigh;
-
- evdwl = 0.0;
- if (eflag || vflag) ev_setup(eflag,vflag);
- else evflag = vflag_fdotr = 0;
-
- double **x = atom->x;
- double **f = atom->f;
- double **torque = atom->torque;
- int *line = atom->line;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- int newton_pair = force->newton_pair;
-
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
-
- // grow discrete list if necessary and initialize
-
- if (nall > nmax) {
- memory->destroy(dnum);
- memory->destroy(dfirst);
- memory->create(dnum,nall,"pair:dnum");
- memory->create(dfirst,nall,"pair:dfirst");
- }
- for (i = 0; i < nall; i++) dnum[i] = 0;
- ndiscrete = 0;
-
- // loop over neighbors of my atoms
-
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
-
- 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]) continue;
-
- // line/line interactions = NxN particles
-
- evdwl = 0.0;
- if (line[i] >= 0 && line[j] >= 0) {
- if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
- npi = dnum[i];
- ifirst = dfirst[i];
- if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
- npj = dnum[j];
- jfirst = dfirst[j];
-
- for (ni = 0; ni < npi; ni++) {
- dxi = discrete[ifirst+ni].dx;
- dyi = discrete[ifirst+ni].dy;
-
- for (nj = 0; nj < npj; nj++) {
- dxj = discrete[jfirst+nj].dx;
- dyj = discrete[jfirst+nj].dy;
-
- xi[0] = x[i][0] + dxi;
- xi[1] = x[i][1] + dyi;
- xj[0] = x[j][0] + dxj;
- xj[1] = x[j][1] + dyj;
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- rsq = delx*delx + dely*dely;
-
- sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
- torque[i][2] += dxi*fi[1] - dyi*fi[0];
-
- if (newton_pair || j < nlocal) {
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- torque[j][2] += dxj*fj[1] - dyj*fj[0];
- }
- }
- }
-
- // line/particle interaction = Nx1 particles
- // convert line into Np particles based on sigma and line length
-
- } else if (line[i] >= 0) {
- if (dnum[i] == 0) discretize(i,sigma[itype][itype]);
- npi = dnum[i];
- ifirst = dfirst[i];
-
- for (ni = 0; ni < npi; ni++) {
- dxi = discrete[ifirst+ni].dx;
- dyi = discrete[ifirst+ni].dy;
-
- xi[0] = x[i][0] + dxi;
- xi[1] = x[i][1] + dyi;
- xj[0] = x[j][0];
- xj[1] = x[j][1];
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- rsq = delx*delx + dely*dely;
-
- sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
- torque[i][2] += dxi*fi[1] - dyi*fi[0];
-
- if (newton_pair || j < nlocal) {
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- }
- }
-
- // particle/line interaction = Nx1 particles
- // convert line into Np particles based on sigma and line length
-
- } else if (line[j] >= 0) {
- if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]);
- npj = dnum[j];
- jfirst = dfirst[j];
-
- for (nj = 0; nj < npj; nj++) {
- dxj = discrete[jfirst+nj].dx;
- dyj = discrete[jfirst+nj].dy;
-
- xi[0] = x[i][0];
- xi[1] = x[i][1];
- xj[0] = x[j][0] + dxj;
- xj[1] = x[j][1] + dyj;
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- rsq = delx*delx + dely*dely;
-
- sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
-
- if (newton_pair || j < nlocal) {
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- torque[j][2] += dxj*fj[1] - dyj*fj[0];
- }
- }
-
- // particle/particle interaction = 1x1 particles
-
- } else {
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
- fpair = forcelj*r2inv;
-
- if (eflag)
- evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
- if (newton_pair || j < nlocal) {
- f[j][0] -= delx*fpair;
- f[j][1] -= dely*fpair;
- f[j][2] -= delz*fpair;
- }
- }
-
- if (evflag) ev_tally(i,j,nlocal,newton_pair,
- evdwl,0.0,fpair,delx,dely,delz);
- }
- }
-
- if (vflag_fdotr) virial_fdotr_compute();
-}
-
-/* ----------------------------------------------------------------------
- allocate all arrays
-------------------------------------------------------------------------- */
-
-void PairLine::allocate()
-{
- allocated = 1;
- int n = atom->ntypes;
-
- memory->create(setflag,n+1,n+1,"pair:setflag");
- for (int i = 1; i <= n; i++)
- for (int j = i; j <= n; j++)
- setflag[i][j] = 0;
-
- memory->create(cutsq,n+1,n+1,"pair:cutsq");
-
- memory->create(cut,n+1,n+1,"pair:cut");
- memory->create(epsilon,n+1,n+1,"pair:epsilon");
- memory->create(sigma,n+1,n+1,"pair:sigma");
- memory->create(lj1,n+1,n+1,"pair:lj1");
- memory->create(lj2,n+1,n+1,"pair:lj2");
- memory->create(lj3,n+1,n+1,"pair:lj3");
- memory->create(lj4,n+1,n+1,"pair:lj4");
-}
-
-/* ----------------------------------------------------------------------
- global settings
-------------------------------------------------------------------------- */
-
-void PairLine::settings(int narg, char **arg)
-{
- if (narg != 1) error->all(FLERR,"Illegal pair_style command");
-
- cut_global = force->numeric(arg[0]);
-
- // 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[i][j] = cut_global;
- }
-}
-
-/* ----------------------------------------------------------------------
- set coeffs for one or more type pairs
-------------------------------------------------------------------------- */
-
-void PairLine::coeff(int narg, char **arg)
-{
- if (narg < 4 || narg > 5)
- error->all(FLERR,"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 = force->numeric(arg[2]);
- double sigma_one = force->numeric(arg[3]);
-
- double cut_one = cut_global;
- if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
- setflag[i][j] = 1;
- count++;
- }
- }
-
- if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
-}
-
-/* ----------------------------------------------------------------------
- init for one type pair i,j and corresponding j,i
-------------------------------------------------------------------------- */
-
-double PairLine::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[i][j] = mix_distance(cut[i][i],cut[j][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);
-
- epsilon[j][i] = epsilon[i][j];
- sigma[j][i] = sigma[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];
-
- return cut[i][j];
-}
-
-/* ----------------------------------------------------------------------
- discretize line segment I into N sub-segments no more than sigma in length
- store new discrete particles in Discrete list
-------------------------------------------------------------------------- */
-
-void PairLine::discretize(int i, double sigma)
-{
- AtomVecLine::Bonus *bonus = avec->bonus;
- double length = bonus[atom->line[i]].length;
- double theta = bonus[atom->line[i]].theta;
- int n = static_cast (length/sigma) + 1;
- dnum[i] = n;
- dfirst[i] = ndiscrete;
-
- if (ndiscrete + n > dmax) {
- dmax += DELTA;
- discrete = (Discrete *)
- memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
- }
-
- double *x = atom->x[i];
- sigma = length/n;
- double delta;
-
- for (int m = 0; m < n; m++) {
- delta = -0.5 + (2*m+1)/(2.0*n);
- discrete[ndiscrete].dx = delta*length*cos(theta);
- discrete[ndiscrete].dy = delta*length*sin(theta);
- discrete[ndiscrete].sigma = sigma;
- ndiscrete++;
- }
-}
diff --git a/src/ASPHERE/pair_line.h b/src/ASPHERE/pair_line.h
deleted file mode 100644
index 6598bfe6c1..0000000000
--- a/src/ASPHERE/pair_line.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(line,PairLine)
-
-#else
-
-#ifndef LMP_PAIR_LINE_H
-#define LMP_PAIR_LINE_H
-
-#include "pair.h"
-
-namespace LAMMPS_NS {
-
-class PairLine : public Pair {
- public:
- PairLine(class LAMMPS *);
- ~PairLine();
- void compute(int, int);
- void settings(int, char **);
- void coeff(int, char **);
- double init_one(int, int);
-
- protected:
- double cut_global;
- double **cut;
- double **epsilon,**sigma;
- double **lj1,**lj2,**lj3,**lj4;
- class AtomVecLine *avec;
-
- struct Discrete {
- double dx,dy;
- double sigma;
- };
- Discrete *discrete; // list of all discretes for all lines
- int ndiscrete; // number of discretes in list
- int dmax; // allocated size of discrete list
- int *dnum; // number of discretes per line, 0 if uninit
- int *dfirst; // index of first discrete per each line
- int nmax; // allocated size of dnum,dfirst vectors
-
- void allocate();
- void discretize(int, double);
-};
-
-}
-
-#endif
-#endif
diff --git a/src/ASPHERE/pair_tri.cpp b/src/ASPHERE/pair_tri.cpp
deleted file mode 100644
index 0a40b8fb06..0000000000
--- a/src/ASPHERE/pair_tri.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#include "math.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "pair_tri.h"
-#include "math_extra.h"
-#include "atom.h"
-#include "atom_vec_tri.h"
-#include "force.h"
-#include "neighbor.h"
-#include "neigh_list.h"
-#include "memory.h"
-#include "error.h"
-
-using namespace LAMMPS_NS;
-
-#define DELTA 20
-
-/* ---------------------------------------------------------------------- */
-
-PairTri::PairTri(LAMMPS *lmp) : Pair(lmp)
-{
- avec = (AtomVecTri *) atom->style_match("tri");
- if (!avec) error->all(FLERR,"Pair tri requires atom style tri");
-
- dmax = nmax = 0;
- discrete = NULL;
- dnum = dfirst = NULL;
-
- single_enable = 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-PairTri::~PairTri()
-{
- memory->sfree(discrete);
- memory->destroy(dnum);
- memory->destroy(dfirst);
-
- if (allocated) {
- memory->destroy(setflag);
- memory->destroy(cutsq);
-
- memory->destroy(cut);
- memory->destroy(epsilon);
- memory->destroy(sigma);
- memory->destroy(lj1);
- memory->destroy(lj2);
- memory->destroy(lj3);
- memory->destroy(lj4);
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairTri::compute(int eflag, int vflag)
-{
- int i,j,ii,jj,inum,jnum,itype,jtype;
- int ni,nj,npi,npj,ifirst,jfirst;
- double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
- double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
- double dxi,dxj,dyi,dyj,dzi,dzj;
- double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3];
- double dc1[3],dc2[3],dc3[3];
- int *ilist,*jlist,*numneigh,**firstneigh;
-
- evdwl = 0.0;
- if (eflag || vflag) ev_setup(eflag,vflag);
- else evflag = vflag_fdotr = 0;
-
- AtomVecTri::Bonus *bonus = avec->bonus;
- double **x = atom->x;
- double **f = atom->f;
- double **torque = atom->torque;
- int *tri = atom->tri;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- int newton_pair = force->newton_pair;
-
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
-
- // grow discrete list if necessary and initialize
-
- if (nall > nmax) {
- memory->destroy(dnum);
- memory->destroy(dfirst);
- memory->create(dnum,nall,"pair:dnum");
- memory->create(dfirst,nall,"pair:dfirst");
- }
- for (i = 0; i < nall; i++) dnum[i] = 0;
- ndiscrete = 0;
-
- // loop over neighbors of my atoms
-
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
-
- 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]) continue;
-
- // tri/tri interactions = NxN particles
- // c1,c2,c3 = corner pts of triangle I or J
-
- evdwl = 0.0;
- if (tri[i] >= 0 && tri[j] >= 0) {
- if (dnum[i] == 0) {
- MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
- MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
- MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
- MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
- dfirst[i] = ndiscrete;
- discretize(i,sigma[itype][itype],dc1,dc2,dc3);
- dnum[i] = ndiscrete - dfirst[i];
- }
- npi = dnum[i];
- ifirst = dfirst[i];
-
- if (dnum[j] == 0) {
- MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
- MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
- MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
- MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
- dfirst[j] = ndiscrete;
- discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
- dnum[j] = ndiscrete - dfirst[j];
- }
- npj = dnum[j];
- jfirst = dfirst[j];
-
- for (ni = 0; ni < npi; ni++) {
- dxi = discrete[ifirst+ni].dx;
- dyi = discrete[ifirst+ni].dy;
- dzi = discrete[ifirst+ni].dz;
-
- for (nj = 0; nj < npj; nj++) {
- dxj = discrete[jfirst+nj].dx;
- dyj = discrete[jfirst+nj].dy;
- dzj = discrete[jfirst+nj].dz;
-
- xi[0] = x[i][0] + dxi;
- xi[1] = x[i][1] + dyi;
- xi[2] = x[i][2] + dzi;
- xj[0] = x[j][0] + dxj;
- xj[1] = x[j][1] + dyj;
- xj[2] = x[j][2] + dzj;
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- delz = xi[2] - xj[2];
- rsq = delx*delx + dely*dely + delz*delz;
-
- sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- fi[2] = delz*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
- f[i][2] += fi[2];
- ti[0] = dyi*fi[2] - dzi*fi[1];
- ti[1] = dzi*fi[0] - dxi*fi[2];
- ti[2] = dxi*fi[1] - dyi*fi[0];
- torque[i][0] += ti[0];
- torque[i][1] += ti[1];
- torque[i][2] += ti[2];
-
- if (newton_pair || j < nlocal) {
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- fj[2] = -delz*fpair;
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- f[j][2] += fj[2];
- tj[0] = dyj*fj[2] - dzj*fj[1];
- tj[1] = dzj*fj[0] - dxj*fj[2];
- tj[2] = dxj*fj[1] - dyj*fj[0];
- torque[j][0] += tj[0];
- torque[j][1] += tj[1];
- torque[j][2] += tj[2];
- }
- }
- }
-
- // tri/particle interaction = Nx1 particles
- // c1,c2,c3 = corner pts of triangle I
-
- } else if (tri[i] >= 0) {
-
- if (dnum[i] == 0) {
- MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
- MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
- MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
- MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
- dfirst[i] = ndiscrete;
- discretize(i,sigma[itype][itype],dc1,dc2,dc3);
- dnum[i] = ndiscrete - dfirst[i];
- }
- npi = dnum[i];
- ifirst = dfirst[i];
-
- for (ni = 0; ni < npi; ni++) {
- dxi = discrete[ifirst+ni].dx;
- dyi = discrete[ifirst+ni].dy;
- dzi = discrete[ifirst+ni].dz;
-
- xi[0] = x[i][0] + dxi;
- xi[1] = x[i][1] + dyi;
- xi[2] = x[i][2] + dzi;
- xj[0] = x[j][0];
- xj[1] = x[j][1];
- xj[2] = x[j][2];
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- delz = xi[2] - xj[2];
- rsq = delx*delx + dely*dely + delz*delz;
-
- sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- fi[2] = delz*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
- f[i][2] += fi[2];
- ti[0] = dyi*fi[2] - dzi*fi[1];
- ti[1] = dzi*fi[0] - dxi*fi[2];
- ti[2] = dxi*fi[1] - dyi*fi[0];
- torque[i][2] += ti[0];
- torque[i][1] += ti[1];
- torque[i][2] += ti[2];
-
- if (newton_pair || j < nlocal) {
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- fj[2] = -delz*fpair;
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- f[j][2] += fj[2];
- }
- }
-
- // particle/tri interaction = Nx1 particles
- // c1,c2,c3 = corner pts of triangle J
-
- } else if (tri[j] >= 0) {
- if (dnum[j] == 0) {
- MathExtra::quat_to_mat(bonus[tri[j]].quat,p);
- MathExtra::matvec(p,bonus[tri[j]].c1,dc1);
- MathExtra::matvec(p,bonus[tri[j]].c2,dc2);
- MathExtra::matvec(p,bonus[tri[j]].c3,dc3);
- dfirst[j] = ndiscrete;
- discretize(j,sigma[jtype][jtype],dc1,dc2,dc3);
- dnum[j] = ndiscrete - dfirst[j];
- }
- npj = dnum[j];
- jfirst = dfirst[j];
-
- for (nj = 0; nj < npj; nj++) {
- dxj = discrete[jfirst+nj].dx;
- dyj = discrete[jfirst+nj].dy;
- dzj = discrete[jfirst+nj].dz;
-
- xi[0] = x[i][0];
- xi[1] = x[i][1];
- xi[2] = x[i][2];
- xj[0] = x[j][0] + dxj;
- xj[1] = x[j][1] + dyj;
- xj[2] = x[j][2] + dzj;
-
- delx = xi[0] - xj[0];
- dely = xi[1] - xj[1];
- delz = xi[2] - xj[2];
- rsq = delx*delx + dely*dely + delz*delz;
-
- sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
- sig3 = sig*sig*sig;
- term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
- term1 = 2.0 * term2 * sig3*sig3;
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (term1*r6inv - term2);
- fpair = forcelj*r2inv;
-
- if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
-
- fi[0] = delx*fpair;
- fi[1] = dely*fpair;
- fi[2] = delz*fpair;
- f[i][0] += fi[0];
- f[i][1] += fi[1];
- f[i][2] += fi[2];
-
- if (newton_pair || j < nlocal) {
- fj[0] = -delx*fpair;
- fj[1] = -dely*fpair;
- fj[2] = -delz*fpair;
- f[j][0] += fj[0];
- f[j][1] += fj[1];
- f[j][2] += fj[2];
- tj[0] = dyj*fj[2] - dzj*fj[1];
- tj[1] = dzj*fj[0] - dxj*fj[2];
- tj[2] = dxj*fj[1] - dyj*fj[0];
- torque[j][0] += tj[0];
- torque[j][1] += tj[1];
- torque[j][2] += tj[2];
- }
- }
-
- // particle/particle interaction = 1x1 particles
-
- } else {
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
- fpair = forcelj*r2inv;
-
- if (eflag)
- evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
- if (newton_pair || j < nlocal) {
- f[j][0] -= delx*fpair;
- f[j][1] -= dely*fpair;
- f[j][2] -= delz*fpair;
- }
- }
-
- if (evflag) ev_tally(i,j,nlocal,newton_pair,
- evdwl,0.0,fpair,delx,dely,delz);
- }
- }
-
- if (vflag_fdotr) virial_fdotr_compute();
-}
-
-/* ----------------------------------------------------------------------
- allocate all arrays
-------------------------------------------------------------------------- */
-
-void PairTri::allocate()
-{
- allocated = 1;
- int n = atom->ntypes;
-
- memory->create(setflag,n+1,n+1,"pair:setflag");
- for (int i = 1; i <= n; i++)
- for (int j = i; j <= n; j++)
- setflag[i][j] = 0;
-
- memory->create(cutsq,n+1,n+1,"pair:cutsq");
-
- memory->create(cut,n+1,n+1,"pair:cut");
- memory->create(epsilon,n+1,n+1,"pair:epsilon");
- memory->create(sigma,n+1,n+1,"pair:sigma");
- memory->create(lj1,n+1,n+1,"pair:lj1");
- memory->create(lj2,n+1,n+1,"pair:lj2");
- memory->create(lj3,n+1,n+1,"pair:lj3");
- memory->create(lj4,n+1,n+1,"pair:lj4");
-}
-
-/* ----------------------------------------------------------------------
- global settings
-------------------------------------------------------------------------- */
-
-void PairTri::settings(int narg, char **arg)
-{
- if (narg != 1) error->all(FLERR,"Illegal pair_style command");
-
- cut_global = force->numeric(arg[0]);
-
- // 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[i][j] = cut_global;
- }
-}
-
-/* ----------------------------------------------------------------------
- set coeffs for one or more type pairs
-------------------------------------------------------------------------- */
-
-void PairTri::coeff(int narg, char **arg)
-{
- if (narg < 4 || narg > 5)
- error->all(FLERR,"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 = force->numeric(arg[2]);
- double sigma_one = force->numeric(arg[3]);
-
- double cut_one = cut_global;
- if (narg == 5) cut_one = force->numeric(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[i][j] = cut_one;
- setflag[i][j] = 1;
- count++;
- }
- }
-
- if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
-}
-
-/* ----------------------------------------------------------------------
- init for one type pair i,j and corresponding j,i
-------------------------------------------------------------------------- */
-
-double PairTri::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[i][j] = mix_distance(cut[i][i],cut[j][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);
-
- epsilon[j][i] = epsilon[i][j];
- sigma[j][i] = sigma[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];
-
- return cut[i][j];
-}
-
-/* ----------------------------------------------------------------------
- recursively discretize triangle I with displaced corners c1,c2,c3
- into N sub-tris no more than sigma in size
- recurse by making 2 tris via bisecting longest side
- store new discrete particles in Discrete list
-------------------------------------------------------------------------- */
-
-void PairTri::discretize(int i, double sigma,
- double *c1, double *c2, double *c3)
-{
- double c1c2[3],c2c3[3],c1c3[3];
-
- double centroid[3],dc1[3],dc2[3],dc3[3];
-
- centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
- centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
- centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
-
- MathExtra::sub3(c1,centroid,dc1);
- MathExtra::sub3(c2,centroid,dc2);
- MathExtra::sub3(c3,centroid,dc3);
-
- double sigmasq = 0.25 * sigma*sigma;
- double len1sq = MathExtra::lensq3(dc1);
- double len2sq = MathExtra::lensq3(dc2);
- double len3sq = MathExtra::lensq3(dc3);
-
- // if sigma sphere overlaps all corner points, add particle at centroid
-
- if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
- if (ndiscrete == dmax) {
- dmax += DELTA;
- discrete = (Discrete *)
- memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
- }
- discrete[ndiscrete].dx = centroid[0];
- discrete[ndiscrete].dy = centroid[1];
- discrete[ndiscrete].dz = centroid[2];
- sigmasq = MAX(len1sq,len2sq);
- sigmasq = MAX(sigmasq,len3sq);
- discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
- ndiscrete++;
- return;
- }
-
- // else break triangle into 2 sub-triangles and recurse
-
- double c12[3],c23[3],c13[3],mid[3];
-
- MathExtra::sub3(c2,c3,c23);
- len1sq = MathExtra::lensq3(c23);
- MathExtra::sub3(c1,c3,c13);
- len2sq = MathExtra::lensq3(c13);
- MathExtra::sub3(c1,c2,c12);
- len3sq = MathExtra::lensq3(c12);
-
- double maxsq = MAX(len1sq,len2sq);
- maxsq = MAX(maxsq,len3sq);
-
- if (len1sq == maxsq) {
- MathExtra::add3(c2,c3,mid);
- MathExtra::scale3(0.5,mid);
- discretize(i,sigma,c1,c2,mid);
- discretize(i,sigma,c1,c3,mid);
- } else if (len2sq == maxsq) {
- MathExtra::add3(c1,c3,mid);
- MathExtra::scale3(0.5,mid);
- discretize(i,sigma,c2,c1,mid);
- discretize(i,sigma,c2,c3,mid);
- } else {
- MathExtra::add3(c1,c2,mid);
- MathExtra::scale3(0.5,mid);
- discretize(i,sigma,c3,c1,mid);
- discretize(i,sigma,c3,c2,mid);
- }
-}
-
-/* ----------------------------------------------------------------------
- recursively discretize triangle I with displaced corners c1,c2,c3
- into N sub-tris no more than sigma in size
- recurse by making 6 tris via centroid
- store new discrete particles in Discrete list
-------------------------------------------------------------------------- */
-
-/*
-void PairTri::discretize(int i, double sigma,
- double *c1, double *c2, double *c3)
-{
- double centroid[3],dc1[3],dc2[3],dc3[3];
-
- centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0;
- centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0;
- centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0;
-
- MathExtra::sub3(c1,centroid,dc1);
- MathExtra::sub3(c2,centroid,dc2);
- MathExtra::sub3(c3,centroid,dc3);
-
- double sigmasq = 0.25 * sigma*sigma;
- double len1sq = MathExtra::lensq3(dc1);
- double len2sq = MathExtra::lensq3(dc2);
- double len3sq = MathExtra::lensq3(dc3);
-
- // if sigma sphere overlaps all corner points, add particle at centroid
-
- if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) {
- if (ndiscrete == dmax) {
- dmax += DELTA;
- discrete = (Discrete *)
- memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete");
- }
- discrete[ndiscrete].dx = centroid[0];
- discrete[ndiscrete].dy = centroid[1];
- discrete[ndiscrete].dz = centroid[2];
- sigmasq = MAX(len1sq,len2sq);
- sigmasq = MAX(sigmasq,len3sq);
- discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq);
- ndiscrete++;
- return;
- }
-
- // else break triangle into 6 sub-triangles and recurse
-
- double c1c2mid[3],c2c3mid[3],c1c3mid[3];
-
- MathExtra::add3(c1,c2,c1c2mid);
- MathExtra::scale3(0.5,c1c2mid);
- MathExtra::add3(c2,c3,c2c3mid);
- MathExtra::scale3(0.5,c2c3mid);
- MathExtra::add3(c1,c3,c1c3mid);
- MathExtra::scale3(0.5,c1c3mid);
-
- discretize(i,sigma,c1,c1c2mid,centroid);
- discretize(i,sigma,c1,c1c3mid,centroid);
- discretize(i,sigma,c2,c2c3mid,centroid);
- discretize(i,sigma,c2,c1c2mid,centroid);
- discretize(i,sigma,c3,c1c3mid,centroid);
- discretize(i,sigma,c3,c2c3mid,centroid);
-}
-
-*/
diff --git a/src/ASPHERE/pair_tri.h b/src/ASPHERE/pair_tri.h
deleted file mode 100644
index fd1fe08bac..0000000000
--- a/src/ASPHERE/pair_tri.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(tri,PairTri)
-
-#else
-
-#ifndef LMP_PAIR_TRI_H
-#define LMP_PAIR_TRI_H
-
-#include "pair.h"
-
-namespace LAMMPS_NS {
-
-class PairTri : public Pair {
- public:
- PairTri(class LAMMPS *);
- ~PairTri();
- void compute(int, int);
- void settings(int, char **);
- void coeff(int, char **);
- double init_one(int, int);
-
- protected:
- double cut_global;
- double **cut;
- double **epsilon,**sigma;
- double **lj1,**lj2,**lj3,**lj4;
- class AtomVecTri *avec;
-
- struct Discrete {
- double dx,dy,dz;
- double sigma;
- };
- Discrete *discrete; // list of all discretes for all lines
- int ndiscrete; // number of discretes in list
- int dmax; // allocated size of discrete list
- int *dnum; // number of discretes per line, 0 if uninit
- int *dfirst; // index of first discrete per each line
- int nmax; // allocated size of dnum,dfirst vectors
-
- void allocate();
- void discretize(int, double, double *, double *, double *);
-};
-
-}
-
-#endif
-#endif
From 4322b98c8e6dc64cd801cf0b31eb5435f26471c8 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:11:00 +0000
Subject: [PATCH 41/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7156
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/Install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh
index 1cc7a4b61d..77a640197c 100644
--- a/src/ASPHERE/Install.sh
+++ b/src/ASPHERE/Install.sh
@@ -14,7 +14,7 @@ if (test $1 = 1) then
cp pair_gayberne.cpp ..
cp pair_line_lj.cpp ..
cp pair_resquared.cpp ..
- cp pair_tri_Lj.cpp ..
+ cp pair_tri_lj.cpp ..
cp compute_erotate_asphere.h ..
cp compute_temp_asphere.h ..
From ac909b6e18149919803f5c12c78291e49382102e Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:13:28 +0000
Subject: [PATCH 42/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7157
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/ASPHERE/pair_line_lj.cpp | 20 ++++++++++----------
src/ASPHERE/pair_line_lj.h | 12 ++++++------
src/ASPHERE/pair_tri_lj.cpp | 22 +++++++++++-----------
src/ASPHERE/pair_tri_lj.h | 12 ++++++------
4 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp
index 4a3902c888..ca50168be5 100644
--- a/src/ASPHERE/pair_line_lj.cpp
+++ b/src/ASPHERE/pair_line_lj.cpp
@@ -15,7 +15,7 @@
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
-#include "pair_line.h"
+#include "pair_line_lj.h"
#include "atom.h"
#include "atom_vec_line.h"
#include "force.h"
@@ -30,10 +30,10 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
-PairLine::PairLine(LAMMPS *lmp) : Pair(lmp)
+PairLineLJ::PairLineLJ(LAMMPS *lmp) : Pair(lmp)
{
avec = (AtomVecLine *) atom->style_match("line");
- if (!avec) error->all(FLERR,"Pair line requires atom style line");
+ if (!avec) error->all(FLERR,"Pair line/lj requires atom style line");
dmax = nmax = 0;
discrete = NULL;
@@ -44,7 +44,7 @@ PairLine::PairLine(LAMMPS *lmp) : Pair(lmp)
/* ---------------------------------------------------------------------- */
-PairLine::~PairLine()
+PairLineLJ::~PairLineLJ()
{
memory->sfree(discrete);
memory->destroy(dnum);
@@ -66,7 +66,7 @@ PairLine::~PairLine()
/* ---------------------------------------------------------------------- */
-void PairLine::compute(int eflag, int vflag)
+void PairLineLJ::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
int ni,nj,npi,npj,ifirst,jfirst;
@@ -307,7 +307,7 @@ void PairLine::compute(int eflag, int vflag)
allocate all arrays
------------------------------------------------------------------------- */
-void PairLine::allocate()
+void PairLineLJ::allocate()
{
allocated = 1;
int n = atom->ntypes;
@@ -332,7 +332,7 @@ void PairLine::allocate()
global settings
------------------------------------------------------------------------- */
-void PairLine::settings(int narg, char **arg)
+void PairLineLJ::settings(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal pair_style command");
@@ -352,7 +352,7 @@ void PairLine::settings(int narg, char **arg)
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
-void PairLine::coeff(int narg, char **arg)
+void PairLineLJ::coeff(int narg, char **arg)
{
if (narg < 4 || narg > 5)
error->all(FLERR,"Incorrect args for pair coefficients");
@@ -386,7 +386,7 @@ void PairLine::coeff(int narg, char **arg)
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
-double PairLine::init_one(int i, int j)
+double PairLineLJ::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j],
@@ -415,7 +415,7 @@ double PairLine::init_one(int i, int j)
store new discrete particles in Discrete list
------------------------------------------------------------------------- */
-void PairLine::discretize(int i, double sigma)
+void PairLineLJ::discretize(int i, double sigma)
{
AtomVecLine::Bonus *bonus = avec->bonus;
double length = bonus[atom->line[i]].length;
diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h
index 6598bfe6c1..b30140acea 100644
--- a/src/ASPHERE/pair_line_lj.h
+++ b/src/ASPHERE/pair_line_lj.h
@@ -13,21 +13,21 @@
#ifdef PAIR_CLASS
-PairStyle(line,PairLine)
+PairStyle(line/lj,PairLineLJ)
#else
-#ifndef LMP_PAIR_LINE_H
-#define LMP_PAIR_LINE_H
+#ifndef LMP_PAIR_LINE_LJ_H
+#define LMP_PAIR_LINE_LJ_H
#include "pair.h"
namespace LAMMPS_NS {
-class PairLine : public Pair {
+class PairLineLJ : public Pair {
public:
- PairLine(class LAMMPS *);
- ~PairLine();
+ PairLineLJ(class LAMMPS *);
+ ~PairLineLJ();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp
index 0a40b8fb06..0ecf19aee5 100644
--- a/src/ASPHERE/pair_tri_lj.cpp
+++ b/src/ASPHERE/pair_tri_lj.cpp
@@ -15,7 +15,7 @@
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
-#include "pair_tri.h"
+#include "pair_tri_lj.h"
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_tri.h"
@@ -31,10 +31,10 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
-PairTri::PairTri(LAMMPS *lmp) : Pair(lmp)
+PairTriLJ::PairTriLJ(LAMMPS *lmp) : Pair(lmp)
{
avec = (AtomVecTri *) atom->style_match("tri");
- if (!avec) error->all(FLERR,"Pair tri requires atom style tri");
+ if (!avec) error->all(FLERR,"Pair tri/lj requires atom style tri");
dmax = nmax = 0;
discrete = NULL;
@@ -45,7 +45,7 @@ PairTri::PairTri(LAMMPS *lmp) : Pair(lmp)
/* ---------------------------------------------------------------------- */
-PairTri::~PairTri()
+PairTriLJ::~PairTriLJ()
{
memory->sfree(discrete);
memory->destroy(dnum);
@@ -67,7 +67,7 @@ PairTri::~PairTri()
/* ---------------------------------------------------------------------- */
-void PairTri::compute(int eflag, int vflag)
+void PairTriLJ::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
int ni,nj,npi,npj,ifirst,jfirst;
@@ -391,7 +391,7 @@ void PairTri::compute(int eflag, int vflag)
allocate all arrays
------------------------------------------------------------------------- */
-void PairTri::allocate()
+void PairTriLJ::allocate()
{
allocated = 1;
int n = atom->ntypes;
@@ -416,7 +416,7 @@ void PairTri::allocate()
global settings
------------------------------------------------------------------------- */
-void PairTri::settings(int narg, char **arg)
+void PairTriLJ::settings(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal pair_style command");
@@ -436,7 +436,7 @@ void PairTri::settings(int narg, char **arg)
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
-void PairTri::coeff(int narg, char **arg)
+void PairTriLJ::coeff(int narg, char **arg)
{
if (narg < 4 || narg > 5)
error->all(FLERR,"Incorrect args for pair coefficients");
@@ -470,7 +470,7 @@ void PairTri::coeff(int narg, char **arg)
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
-double PairTri::init_one(int i, int j)
+double PairTriLJ::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j],
@@ -501,7 +501,7 @@ double PairTri::init_one(int i, int j)
store new discrete particles in Discrete list
------------------------------------------------------------------------- */
-void PairTri::discretize(int i, double sigma,
+void PairTriLJ::discretize(int i, double sigma,
double *c1, double *c2, double *c3)
{
double c1c2[3],c2c3[3],c1c3[3];
@@ -579,7 +579,7 @@ void PairTri::discretize(int i, double sigma,
------------------------------------------------------------------------- */
/*
-void PairTri::discretize(int i, double sigma,
+void PairTriLJ::discretize(int i, double sigma,
double *c1, double *c2, double *c3)
{
double centroid[3],dc1[3],dc2[3],dc3[3];
diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h
index fd1fe08bac..a8cf2bf721 100644
--- a/src/ASPHERE/pair_tri_lj.h
+++ b/src/ASPHERE/pair_tri_lj.h
@@ -13,21 +13,21 @@
#ifdef PAIR_CLASS
-PairStyle(tri,PairTri)
+PairStyle(tri/lj,PairTriLJ)
#else
-#ifndef LMP_PAIR_TRI_H
-#define LMP_PAIR_TRI_H
+#ifndef LMP_PAIR_TRI_LJ_H
+#define LMP_PAIR_TRI_LJ_H
#include "pair.h"
namespace LAMMPS_NS {
-class PairTri : public Pair {
+class PairTriLJ : public Pair {
public:
- PairTri(class LAMMPS *);
- ~PairTri();
+ PairTriLJ(class LAMMPS *);
+ ~PairTriLJ();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
From 5667c71730bc33ecc051d2bd713faf49c013aeed Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:18:16 +0000
Subject: [PATCH 43/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7158
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
src/SHOCK/fix_append_atoms.cpp | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp
index 42fd494f96..9d59470f0d 100644
--- a/src/SHOCK/fix_append_atoms.cpp
+++ b/src/SHOCK/fix_append_atoms.cpp
@@ -64,38 +64,52 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Only zhi currently implemented for append_atoms");
xloflag = 1;
iarg++;
- if (domain->boundary[0][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum the append boundary");
+ if (domain->boundary[0][0] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"xhi") == 0) {
error->all(FLERR,"Only zhi currently implemented for append_atom");
xhiflag = 1;
iarg++;
- if (domain->boundary[0][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary");
+ if (domain->boundary[0][1] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"ylo") == 0) {
error->all(FLERR,"Only zhi currently implemented for append_atom");
yloflag = 1;
iarg++;
- if (domain->boundary[1][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary");
+ if (domain->boundary[1][0] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"yhi") == 0) {
error->all(FLERR,"Only zhi currently implemented for append_atom");
yhiflag = 1;
iarg++;
- if (domain->boundary[1][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary");
+ if (domain->boundary[1][1] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"zlo") == 0) {
error->all(FLERR,"Only zhi currently implemented for append_atom");
zloflag = 1;
iarg++;
- if (domain->boundary[2][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary");
+ if (domain->boundary[2][0] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"zhi") == 0) {
zhiflag = 1;
iarg++;
- if (domain->boundary[2][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary");
+ if (domain->boundary[2][1] != 3)
+ error->all(FLERR,
+ "Must shrink-wrap with minimum the append boundary");
} else if (strcmp(arg[iarg],"freq") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command");
freq = atoi(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"spatial") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix append_atoms command");
- if (strcmp(arg[iarg+1],"f_") == 0) error->all(FLERR,"Bad fix ID in fix append_atoms command");
+ if (strcmp(arg[iarg+1],"f_") == 0)
+ error->all(FLERR,
+ "Bad fix ID in fix append_atoms command");
spatflag = 1;
int n = strlen(arg[iarg+1]);
spatlead = atof(arg[iarg+2]);
@@ -106,7 +120,7 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) :
strcpy(spatialid,suffix);
delete [] suffix;
iarg += 3;
- // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL
+ // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL
} else if (strcmp(arg[iarg],"size") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command");
size = atof(arg[iarg+1]);
@@ -152,7 +166,8 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) :
if ((zloflag || zhiflag) && domain->zperiodic)
error->all(FLERR,"Cannot use append_atoms in periodic dimension");
- if (domain->triclinic == 1) error->all(FLERR,"Cannot append atoms to a triclinic box");
+ if (domain->triclinic == 1)
+ error->all(FLERR,"Cannot append atoms to a triclinic box");
// setup scaling
From 5cd9c6fe00012d8580000483f975a514eb7d3e00 Mon Sep 17 00:00:00 2001
From: sjplimp
Date: Thu, 20 Oct 2011 15:37:44 +0000
Subject: [PATCH 44/47] git-svn-id:
svn://svn.icms.temple.edu/lammps-ro/trunk@7160
f3b2605a-c512-4ea7-a41b-209d697bcdaa
---
doc/Section_intro.html | 3 ++-
doc/Section_intro.txt | 3 ++-
doc/pair_line_lj.html | 18 +++++++++---------
doc/pair_line_lj.txt | 18 +++++++++---------
doc/pair_tri_lj.html | 18 +++++++++---------
doc/pair_tri_lj.txt | 18 +++++++++---------
6 files changed, 40 insertions(+), 38 deletions(-)
diff --git a/doc/Section_intro.html b/doc/Section_intro.html
index bced87e8c1..3b659cf8e7 100644
--- a/doc/Section_intro.html
+++ b/doc/Section_intro.html
@@ -125,7 +125,8 @@ LAMMPS.
- metals
- granular materials
- coarse-grained mesoscale models
-
- extended spherical and ellipsoidal particles
+
- finite-size spherical and ellipsoidal particles
+
- finite-size line segment (2d) and triangle (3d) particles
- point dipolar particles
- rigid collections of particles
- hybrid combinations of these
diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt
index 95a934830a..2ceb4f78d4 100644
--- a/doc/Section_intro.txt
+++ b/doc/Section_intro.txt
@@ -121,7 +121,8 @@ Particle and model types :h4
metals
granular materials
coarse-grained mesoscale models
- extended spherical and ellipsoidal particles
+ finite-size spherical and ellipsoidal particles
+ finite-size line segment (2d) and triangle (3d) particles
point dipolar particles
rigid collections of particles
hybrid combinations of these :ul
diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html
index 205c5f3f91..125bd41c5d 100644
--- a/doc/pair_line_lj.html
+++ b/doc/pair_line_lj.html
@@ -9,23 +9,23 @@
-pair_style line command
+pair_style line/lj command
Syntax:
-pair_style line cutoff
+pair_style line/lj cutoff
cutoff = global cutoff for interactions (distance units)
Examples:
-pair_style line 3.0
+pair_style line/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
Description:
-Style line treats particles which are line segments as a set of
+
Style line/lj treats particles which are line segments as a set of
small spherical particles that tile the line segment length as
explained below. Interactions between two line segments, each with N1
and N2 spherical particles, are calculated as the pairwise sum of
@@ -64,10 +64,10 @@ computed using only sigma_II values, specific to the line segment's
type, this means that any specified sigma_IJ values (for I != J) are
effectively ignored.
-For style line, the following coefficients must be defined for each
-pair of atoms types via the pair_coeff command as in
-the examples above, or in the data file or restart files read by the
-read_data or read_restart
+
For style line/lj, the following coefficients must be defined for
+each pair of atoms types via the pair_coeff command
+as in the examples above, or in the data file or restart files read by
+the read_data or read_restart
commands:
- epsilon (energy units)
@@ -110,7 +110,7 @@ line/line or line/particle interactions requires the use the
Related commands:
-pair_coeff
+
pair_coeff, pair_style tri/lj
Default: none
diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt
index 160800250b..7f0bad0830 100644
--- a/doc/pair_line_lj.txt
+++ b/doc/pair_line_lj.txt
@@ -6,23 +6,23 @@
:line
-pair_style line command :h3
+pair_style line/lj command :h3
[Syntax:]
-pair_style line cutoff :pre
+pair_style line/lj cutoff :pre
cutoff = global cutoff for interactions (distance units)
[Examples:]
-pair_style line 3.0
+pair_style line/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5 :pre
[Description:]
-Style {line} treats particles which are line segments as a set of
+Style {line/lj} treats particles which are line segments as a set of
small spherical particles that tile the line segment length as
explained below. Interactions between two line segments, each with N1
and N2 spherical particles, are calculated as the pairwise sum of
@@ -61,10 +61,10 @@ computed using only sigma_II values, specific to the line segment's
type, this means that any specified sigma_IJ values (for I != J) are
effectively ignored.
-For style {line}, the following coefficients must be defined for each
-pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
-the examples above, or in the data file or restart files read by the
-"read_data"_read_data.html or "read_restart"_read_restart.html
+For style {line/lj}, the following coefficients must be defined for
+each pair of atoms types via the "pair_coeff"_pair_coeff.html command
+as in the examples above, or in the data file or restart files read by
+the "read_data"_read_data.html or "read_restart"_read_restart.html
commands:
epsilon (energy units)
@@ -107,6 +107,6 @@ line/line or line/particle interactions requires the use the
[Related commands:]
-"pair_coeff"_pair_coeff.html
+"pair_coeff"_pair_coeff.html, "pair_style tri/lj"_pair_tri_lj.html
[Default:] none
diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html
index 931819e107..76b4455fe7 100644
--- a/doc/pair_tri_lj.html
+++ b/doc/pair_tri_lj.html
@@ -9,23 +9,23 @@
-pair_style tri command
+pair_style tri/lj command
Syntax:
-pair_style tri cutoff
+pair_style tri/lj cutoff
cutoff = global cutoff for interactions (distance units)
Examples:
-pair_style tri 3.0
+pair_style tri/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
Description:
-Style tri treats particles which are triangles as a set of small
+
Style tri/lj treats particles which are triangles as a set of small
spherical particles that tile the triangle surface as explained below.
Interactions between two triangles, each with N1 and N2 spherical
particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
@@ -67,10 +67,10 @@ using only sigma_II values, specific to the triangles's type, this
means that any specified sigma_IJ values (for I != J) are effectively
ignored.
-For style tri, the following coefficients must be defined for each
-pair of atoms types via the pair_coeff command as in
-the examples above, or in the data file or restart files read by the
-read_data or read_restart
+
For style tri/lj, the following coefficients must be defined for
+each pair of atoms types via the pair_coeff command
+as in the examples above, or in the data file or restart files read by
+the read_data or read_restart
commands: