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
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
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/src/USER-CUDA/cuda_common.h b/lib/cuda/cuda_common.h
similarity index 100%
rename from src/USER-CUDA/cuda_common.h
rename to lib/cuda/cuda_common.h
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)
{
diff --git a/lib/cuda/pair_manybody_const.h b/lib/cuda/pair_manybody_const.h
new file mode 100644
index 0000000000..69bf32aead
--- /dev/null
+++ b/lib/cuda/pair_manybody_const.h
@@ -0,0 +1,16 @@
+/*
+ * pair_manybody_const.h
+ *
+ * Created on: Oct 11, 2011
+ * Author: chmu-tph
+ */
+
+#define MANYBODY_NPAIR 3
+
+__device__ __constant__ int elem2param[(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)];
+__device__ __constant__ int nelements;
+__device__ __constant__ int map[MANYBODY_NPAIR+2];
+__device__ __constant__ int* _glob_numneigh_red; //number of neighbors within force cutoff (as opposed to neighbor cutoff)
+__device__ __constant__ int* _glob_neighbors_red; //indices of neighbors within force cutoff
+__device__ __constant__ int* _glob_neightype_red; //type of neighbors within force cutoff
+
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
+}
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
diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh
index a494ae63d7..77a640197c 100644
--- a/src/ASPHERE/Install.sh
+++ b/src/ASPHERE/Install.sh
@@ -8,9 +8,13 @@ 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_line_lj.cpp ..
cp pair_resquared.cpp ..
+ cp pair_tri_lj.cpp ..
cp compute_erotate_asphere.h ..
cp compute_temp_asphere.h ..
@@ -18,9 +22,13 @@ 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_line_lj.h ..
cp pair_resquared.h ..
+ cp pair_tri_lj.h ..
elif (test $1 = 0) then
@@ -30,9 +38,13 @@ 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_line_lj.cpp
rm -f ../pair_resquared.cpp
+ rm -f ../pair_tri_lj.cpp
rm -f ../compute_erotate_asphere.h
rm -f ../compute_temp_asphere.h
@@ -40,8 +52,12 @@ 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_line_lj.h
rm -f ../pair_resquared.h
+ rm -f ../pair_tri_lj.h
fi
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
diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp
new file mode 100644
index 0000000000..ca50168be5
--- /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_lj.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
+
+/* ---------------------------------------------------------------------- */
+
+PairLineLJ::PairLineLJ(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecLine *) atom->style_match("line");
+ if (!avec) error->all(FLERR,"Pair line/lj requires atom style line");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLineLJ::~PairLineLJ()
+{
+ 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 PairLineLJ::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 PairLineLJ::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 PairLineLJ::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 PairLineLJ::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 PairLineLJ::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 PairLineLJ::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..b30140acea
--- /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/lj,PairLineLJ)
+
+#else
+
+#ifndef LMP_PAIR_LINE_LJ_H
+#define LMP_PAIR_LINE_LJ_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairLineLJ : public Pair {
+ public:
+ PairLineLJ(class LAMMPS *);
+ ~PairLineLJ();
+ 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..0ecf19aee5
--- /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_lj.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
+
+/* ---------------------------------------------------------------------- */
+
+PairTriLJ::PairTriLJ(LAMMPS *lmp) : Pair(lmp)
+{
+ avec = (AtomVecTri *) atom->style_match("tri");
+ if (!avec) error->all(FLERR,"Pair tri/lj requires atom style tri");
+
+ dmax = nmax = 0;
+ discrete = NULL;
+ dnum = dfirst = NULL;
+
+ single_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairTriLJ::~PairTriLJ()
+{
+ 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 PairTriLJ::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 PairTriLJ::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 PairTriLJ::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 PairTriLJ::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 PairTriLJ::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 PairTriLJ::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 PairTriLJ::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..a8cf2bf721
--- /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/lj,PairTriLJ)
+
+#else
+
+#ifndef LMP_PAIR_TRI_LJ_H
+#define LMP_PAIR_TRI_LJ_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairTriLJ : public Pair {
+ public:
+ PairTriLJ(class LAMMPS *);
+ ~PairTriLJ();
+ 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
diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp
index 921f2fac84..3d1847314a 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 ed14c2ed86..cbee3ac810 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 58c65b365e..0fa91a2518 100644
--- a/src/GPU/pppm_gpu.cpp
+++ b/src/GPU/pppm_gpu.cpp
@@ -32,10 +32,10 @@
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
-#include "memory.h"
-#include "error.h"
#include "gpu_extra.h"
#include "math_const.h"
+#include "memory.h"
+#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
@@ -191,7 +191,7 @@ void PPPMGPU::compute(int eflag, int vflag)
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*MY_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 5e7a417462..fe0ce40f31 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;
@@ -216,11 +216,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);
@@ -476,7 +476,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 382dd26ee3..cd22f987f7 100644
--- a/src/KSPACE/ewald.h
+++ b/src/KSPACE/ewald.h
@@ -34,7 +34,6 @@ class Ewald : public KSpace {
double memory_usage();
protected:
- 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/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
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp
index eac19b515d..ec52038907 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
diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp
index 197e0bcd4d..c90898335c 100644
--- a/src/MANYBODY/pair_comb.cpp
+++ b/src/MANYBODY/pair_comb.cpp
@@ -29,12 +29,11 @@
#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;
diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h
index 7093ea8ef1..b236ab7d08 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/MANYBODY/pair_tersoff.h b/src/MANYBODY/pair_tersoff.h
index 411ddf8871..0d2cf1f32b 100644
--- a/src/MANYBODY/pair_tersoff.h
+++ b/src/MANYBODY/pair_tersoff.h
@@ -63,7 +63,8 @@ class PairTersoff : public Pair {
void setup();
virtual void repulsive(Param *, double, double &, int, double &);
double zeta(Param *, double, double, double *, double *);
- virtual 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,7 +75,15 @@ class PairTersoff : public Pair {
double ters_bij(double, Param *);
double ters_bij_d(double, Param *);
- inline double ters_gijk(const double costheta, const Param * const param) const {
+ void ters_zetaterm_d(double, double *, double, double *, double,
+ double *, double *, double *, Param *);
+ void costheta_d(double *, double, double *, double,
+ double *, double *, double *);
+
+ // inlined functions for efficiency
+
+ 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;
@@ -82,7 +91,8 @@ class PairTersoff : public Pair {
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 {
+ 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;
@@ -91,13 +101,6 @@ class PairTersoff : public Pair {
return param->gamma*numerator*denominator*denominator;
}
- 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
-
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];
}
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 fb523628be..596903c18e 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 0898c355c8..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;
@@ -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,evdwl_total,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_total = evdwl = 0.0;
+ evdwl = ehbond = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
@@ -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;
@@ -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;
@@ -223,13 +224,9 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
// KIJ instead of IJK b/c delr1/delr2 are both with respect to k
- if (evflag) {
- ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2);
- if (eflag_global) {
- hbcount++;
- evdwl_total += evdwl;
- }
- }
+ if (evflag) ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2);
+
+ hbcount++;
}
}
}
@@ -238,7 +235,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
if (eflag_global) {
pvector[0] = hbcount;
- pvector[1] = evdwl_total;
+ pvector[1] = ehbond;
}
}
@@ -282,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;
}
/* ----------------------------------------------------------------------
@@ -319,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) {
@@ -503,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 416595cbff..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
@@ -46,14 +48,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,evdwl_total;
+ 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_total = evdwl = 0.0;
+ evdwl = ehbond = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
@@ -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;
@@ -154,6 +156,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;
@@ -190,13 +193,10 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
f[k][2] -= vz1 + vz2;
// KIJ instead of IJK b/c delr1/delr2 are both with respect to k
- if (evflag) {
- ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2);
- if (eflag_global) {
- hbcount++;
- evdwl_total += evdwl;
- }
- }
+
+ if (evflag) ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2);
+
+ hbcount++;
}
}
}
@@ -205,7 +205,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
if (eflag_global) {
pvector[0] = hbcount;
- pvector[1] = evdwl_total;
+ pvector[1] = ehbond;
}
}
@@ -244,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
@@ -406,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/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
diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp
index ec0d07d20d..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"
@@ -34,13 +36,15 @@
#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};
+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};
@@ -48,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
@@ -93,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) {
@@ -154,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");
@@ -166,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");
@@ -174,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");
@@ -234,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
@@ -287,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)
@@ -317,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 "
@@ -337,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;
@@ -389,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
@@ -405,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
@@ -414,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
@@ -559,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);
@@ -581,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);
@@ -603,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);
@@ -643,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
@@ -763,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;
@@ -829,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;
@@ -872,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;
@@ -898,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
@@ -1030,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;
}
}
@@ -1048,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++];
}
}
@@ -1063,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;
@@ -1095,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;
@@ -1159,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;
@@ -1220,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];
@@ -1249,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)
@@ -1273,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);
@@ -1316,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];
@@ -1329,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;
@@ -1418,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
------------------------------------------------------------------------- */
@@ -1449,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];
@@ -1468,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];
@@ -1539,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;
@@ -1549,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]);
@@ -1584,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];
@@ -1600,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;
}
@@ -1638,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,
@@ -1646,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;
@@ -1679,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;
}
/* ----------------------------------------------------------------------
@@ -1705,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
------------------------------------------------------------------------- */
@@ -1735,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
------------------------------------------------------------------------- */
@@ -1758,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];
@@ -1825,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]);
@@ -1885,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
@@ -1895,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];
@@ -1930,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];
}
/* ----------------------------------------------------------------------
@@ -2025,6 +2300,7 @@ void FixSRD::force_torque(double *vsold, double *vsnew,
------------------------------------------------------------------------- */
void FixSRD::force_wall(double *vsold, double *vsnew, int iwall)
+
{
double dpdt[3];
@@ -2087,8 +2363,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;
@@ -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*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*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 += 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 += 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/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/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_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/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/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/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;i1)
precisionmodify=arg[1][0];
else precisionmodify='=';
-
+
nfactors = 3;
factors = new int[nfactors];
factors[0] = 2;
@@ -966,7 +968,7 @@ else
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
- 0.5*MY_PI*qsum*qsum / (g_ewald*g_ewald*volume);
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qqrd2e;
}
diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp
index 599c9e8b97..f03ca0a07f 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;
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/Install.sh b/src/USER-OMP/Install.sh
index 40379fcc8f..c010cefdf8 100644
--- a/src/USER-OMP/Install.sh
+++ b/src/USER-OMP/Install.sh
@@ -6,7 +6,6 @@ for file in *_omp.cpp *_omp.h; do
ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
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
@@ -16,12 +15,10 @@ for file in *_omp.cpp *_omp.h; do
cp $file ..
elif (test $1 = 0) then
-
rm -f ../$file
fi
done
-
if (test $1 = 1) then
cp thr_data.h ..
@@ -43,4 +40,4 @@ elif (test $1 = 0) then
rm -f ../pair_lj_charmm_coul_pppm_omp.h
rm -f ../pair_lj_charmm_coul_pppm_omp.cpp
-fi
+fi
\ No newline at end of file
diff --git a/src/USER-OMP/Package.sh b/src/USER-OMP/Package.sh
index 5777ce381b..89c13bf570 100644
--- a/src/USER-OMP/Package.sh
+++ b/src/USER-OMP/Package.sh
@@ -1,4 +1,3 @@
-#/bin/sh
# Update package files in LAMMPS
# copy package file to src if it doesn't exists or is different
# do not copy OpenMP style files, if a non-OpenMP version does
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.
diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp
index e45cfe9d5d..0aa6429c24 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
@@ -209,10 +211,10 @@ void DihedralHelixOMP::eval(int nfrom, int nto, ThrData * const thr)
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;
c = c * a;
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
index 760bd4912d..c387bee7bd 100644
--- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
@@ -174,7 +174,6 @@ void DihedralMultiHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
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",
diff --git a/src/angle.cpp b/src/angle.cpp
index 334f26610b..54a3a5d051 100644
--- a/src/angle.cpp
+++ b/src/angle.cpp
@@ -16,10 +16,12 @@
#include "atom.h"
#include "comm.h"
#include "force.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
@@ -28,8 +30,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 07a3064b4e..46ee5e1dc6 100644
--- a/src/angle.h
+++ b/src/angle.h
@@ -41,8 +41,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.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/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp
index 47c9ef97f6..4baff5b602 100644
--- 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_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_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/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
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_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/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 d55c140e2d..f1a62cba16 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_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)
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_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/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 0fd566a0a6..9a1f47e5ce 100644
--- a/src/improper.cpp
+++ b/src/improper.cpp
@@ -28,7 +28,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 1b2413fe61..d766015e34 100644
--- a/src/improper.h
+++ b/src/improper.h
@@ -39,8 +39,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/input.cpp b/src/input.cpp
index 6960bb2834..a7827f46ce 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
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_hybrid.cpp b/src/pair_hybrid.cpp
index e7d2027da6..3a5583ce63 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]) || strcmp(arg[i],"NULL") == 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]) || strcmp(arg[i],"NULL") == 0)) i++;
styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]);
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/read_data.cpp b/src/read_data.cpp
index 3b5d0bc89e..9f9c54f99e 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");
}
/* ---------------------------------------------------------------------- */
@@ -150,8 +159,18 @@ void ReadData::command(int narg, char **arg)
} else if (strcmp(keyword,"Ellipsoids") == 0) {
if (!avec_ellipsoid)
error->one(FLERR,"Invalid data file section: Ellipsoids");
- if (atomflag == 0) error->one(FLERR,"Must read Atoms before Ellipsoids");
- ellipsoids();
+ if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
+ bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
+ } else if (strcmp(keyword,"Lines") == 0) {
+ if (!avec_line)
+ error->one(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->one(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->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs");
+ error->one(FLERR,
+ "Must define dihedral_style before "
+ "MiddleBondTorsion Coeffs");
dihedralcoeffs(1);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs");
+ error->one(FLERR,
+ "Must define dihedral_style before EndBondTorsion Coeffs");
dihedralcoeffs(2);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before AngleTorsion Coeffs");
+ error->one(FLERR,
+ "Must define dihedral_style before AngleTorsion Coeffs");
dihedralcoeffs(3);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs");
+ error->one(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->one(FLERR,"No atoms in data file");
+ if (atom->natoms > 0 && atomflag == 0)
+ error->one(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->one(FLERR,"No ellipsoids allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nellipsoids);
+ } else if (strstr(line,"lines")) {
+ if (!avec_line)
+ error->one(FLERR,"No lines allowed with this atom style");
+ sscanf(line,BIGINT_FORMAT,&nlines);
+ } else if (strstr(line,"triangles")) {
+ if (!avec_tri)
+ error->one(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->one(FLERR,"Invalid data file section: Ellipsoids");
ellipsoid_flag = 1;
skip_lines(nellipsoids);
+ } else if (strcmp(keyword,"Lines") == 0) {
+ if (!avec_line) error->one(FLERR,"Invalid data file section: Lines");
+ line_flag = 1;
+ skip_lines(nlines);
+ } else if (strcmp(keyword,"Triangles") == 0) {
+ if (!avec_tri) error->one(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->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs");
+ error->one(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->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs");
+ error->one(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->one(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before AngleTorsion Coeffs");
+ error->one(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->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
- error->one(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs");
+ error->one(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 507fa812f5..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"
@@ -28,16 +30,15 @@
#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;
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};
@@ -95,7 +96,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) {
@@ -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]);
@@ -165,8 +183,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) {
@@ -175,18 +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");
+ 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]);
@@ -225,11 +263,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) {
@@ -379,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);
@@ -399,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
@@ -440,12 +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);
@@ -453,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++;
}
}
@@ -468,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;
@@ -528,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;
@@ -542,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);
@@ -563,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);
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 a522ea9f7e..495f54c400 100644
--- a/src/thermo.cpp
+++ b/src/thermo.cpp
@@ -36,6 +36,7 @@
#include "kspace.h"
#include "output.h"
#include "timer.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
diff --git a/src/version.h b/src/version.h
index 4d760c21f6..522b480dc6 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "6 Oct 2011"
+#define LAMMPS_VERSION "20 Oct 2011"
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()