Merge branch 'develop' into rheo

This commit is contained in:
jtclemm
2024-01-18 14:52:15 -07:00
100 changed files with 2988 additions and 2277 deletions

View File

@ -663,14 +663,9 @@ foreach(PKG_WITH_INCL CORESHELL DPD-SMOOTH MC MISC PHONON QEQ OPENMP KOKKOS OPT
endif()
endforeach()
######################################################################
# packages with defines to disable package specific code
######################################################################
foreach(PKG_WITH_DEF BPM PLUGIN)
if(PKG_${PKG_WITH_DEF})
target_compile_definitions(lammps PRIVATE -DLMP_${PKG_WITH_DEF})
endif()
endforeach()
if(PKG_PLUGIN)
target_compile_definitions(lammps PRIVATE -DLMP_PLUGIN)
endif()
# link with -ldl or equivalent for plugin loading; except on Windows
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")

View File

@ -20,6 +20,7 @@ Available topics in mostly chronological order are:
- `Use ev_init() to initialize variables derived from eflag and vflag`_
- `Use utils::numeric() functions instead of force->numeric()`_
- `Use utils::open_potential() function to open potential files`_
- `Use symbolic Atom and AtomVec constants instead of numerical values`_
- `Simplify customized error messages`_
- `Use of "override" instead of "virtual"`_
- `Simplified and more compact neighbor list requests`_
@ -196,6 +197,71 @@ New:
fp = utils::open_potential(filename, lmp);
Use symbolic Atom and AtomVec constants instead of numerical values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. versionchanged:: 18Sep2020
Properties in LAMMPS that were represented by integer values (0, 1,
2, 3) to indicate settings in the ``Atom`` and ``AtomVec`` classes (or
classes derived from it) (and its derived classes) have been converted
to use scoped enumerators instead.
.. list-table::
:header-rows: 1
:widths: auto
* - Symbolic Constant
- Value
- Symbolic Constant
- Value
* - Atom::GROW
- 0
- Atom::MAP_NONE
- 0
* - Atom::RESTART
- 1
- Atom::MAP_ARRAY
- 1
* - Atom::BORDER
- 2
- Atom::MAP_HASH
- 2
* - Atom::ATOMIC
- 0
- Atom::MAP_YES
- 3
* - Atom::MOLECULAR
- 1
- AtomVec::PER_ATOM
- 0
* - Atom::TEMPLATE
- 2
- AtomVec::PER_TYPE
- 1
Old:
.. code-block:: c++
molecular = 0;
mass_type = 1;
if (atom->molecular == 2)
if (atom->map_style == 2)
atom->add_callback(0);
atom->delete_callback(id,1);
New:
.. code-block:: c++
molecular = Atom::ATOMIC;
mass_type = AtomVec::PER_TYPE;
if (atom->molecular == Atom::TEMPLATE)
if (atom->map_style == Atom::MAP_HASH)
atom->add_callback(Atom::GROW);
atom->delete_callback(id,Atom::RESTART);
Simplify customized error messages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -11,7 +11,16 @@ Syntax
.. code-block:: LAMMPS
angle_style lepton
angle_style style args
* style = *lepton*
* args = optional arguments
.. parsed-literal::
args = *auto_offset* or *no_offset*
*auto_offset* = offset the potential energy so that the value at theta0 is 0.0 (default)
*no_offset* = do not offset the potential energy
Examples
""""""""
@ -19,6 +28,7 @@ Examples
.. code-block:: LAMMPS
angle_style lepton
angle_style lepton no_offset
angle_coeff 1 120.0 "k*theta^2; k=250.0"
angle_coeff 2 90.0 "k2*theta^2 + k3*theta^3 + k4*theta^4; k2=300.0; k3=-100.0; k4=50.0"
@ -41,6 +51,13 @@ angle coefficient. For example `"200.0*theta^2"` represents a
U_{angle,i} = K (\theta_i - \theta_0)^2 = K \theta^2 \qquad \theta = \theta_i - \theta_0
.. versionchanged:: TBD
By default the potential energy U is shifted so that the value U is 0.0
for $theta = theta_0$. This is equivalent to using the optional keyword
*auto_offset*. When using the keyword *no_offset* instead, the
potential energy is not shifted.
The `Lepton library <https://simtk.org/projects/lepton>`_, that the
*lepton* angle style interfaces with, evaluates this expression string
at run time to compute the pairwise energy. It also creates an

View File

@ -11,7 +11,16 @@ Syntax
.. code-block:: LAMMPS
bond_style lepton
bond_style style args
* style = *lepton*
* args = optional arguments
.. parsed-literal::
args = *auto_offset* or *no_offset*
*auto_offset* = offset the potential energy so that the value at r0 is 0.0 (default)
*no_offset* = do not offset the potential energy
Examples
""""""""
@ -19,6 +28,7 @@ Examples
.. code-block:: LAMMPS
bond_style lepton
bond_style lepton no_offset
bond_coeff 1 1.5 "k*r^2; k=250.0"
bond_coeff 2 1.1 "k2*r^2 + k3*r^3 + k4*r^4; k2=300.0; k3=-100.0; k4=50.0"
@ -40,6 +50,13 @@ constant *K* of 200.0 energy units:
U_{bond,i} = K (r_i - r_0)^2 = K r^2 \qquad r = r_i - r_0
.. versionchanged:: TBD
By default the potential energy U is shifted so that he value U is 0.0
for $r = r_0$. This is equivalent to using the optional keyword
*auto_offset*. When using the keyword *no_offset* instead, the
potential energy is not shifted.
The `Lepton library <https://simtk.org/projects/lepton>`_, that the
*lepton* bond style interfaces with, evaluates this expression string at
run time to compute the pairwise energy. It also creates an analytical

View File

@ -232,8 +232,6 @@ These fixes are part of the QEQ package. They are only enabled if
LAMMPS was built with that package. See the :doc:`Build package
<Build_package>` page for more info.
These qeq fixes are not compatible with the GPU and USER-INTEL packages.
These qeq fixes will ignore electric field contributions from
:doc:`fix efield <fix_efield>`.

View File

@ -126,14 +126,50 @@ molecule (header keyword = inertia).
Format of a molecule file
"""""""""""""""""""""""""
The format of an individual molecule file is similar but
(not identical) to the data file read by the :doc:`read_data <read_data>`
commands, and is as follows.
The format of an individual molecule file looks similar but is
different than that of a data file read by the :doc:`read_data <read_data>`
commands. Here is a simple example for a TIP3P water molecule:
.. code-block::
# Water molecule. TIP3P geometry
# header section:
3 atoms
2 bonds
1 angles
# body section:
Coords
1 0.00000 -0.06556 0.00000
2 0.75695 0.52032 0.00000
3 -0.75695 0.52032 0.00000
Types
1 1 # O
2 2 # H
3 2 # H
Charges
1 -0.834
2 0.417
3 0.417
Bonds
1 1 1 2
2 1 1 3
Angles
1 1 2 1 3
A molecule file has a header and a body. The header appears first. The
first line of the header and thus of the molecule file is *always* skipped;
it typically contains a description of the file or a comment from the software
that created the file.
first line of the header and thus of the molecule file is *always*
skipped; it typically contains a description of the file or a comment
from the software that created the file.
Then lines are read one line at a time. Lines can have a trailing
comment starting with '#' that is ignored. There *must* be at least one
@ -158,25 +194,62 @@ appear if the value(s) are different than the default, except when
defining a *body* particle, which requires setting the number of
*atoms* to 1, and setting the *inertia* in a specific section (see below).
* N *atoms* = # of atoms N in molecule, default = 0
* Nb *bonds* = # of bonds Nb in molecule, default = 0
* Na *angles* = # of angles Na in molecule, default = 0
* Nd *dihedrals* = # of dihedrals Nd in molecule, default = 0
* Ni *impropers* = # of impropers Ni in molecule, default = 0
* Nf *fragments* = # of fragments Nf in molecule, default = 0
* Ninteger Ndouble *body* = # of integer and floating-point values
in body particle, default = 0
* Mtotal *mass* = total mass of molecule
* Xc Yc Zc *com* = coordinates of center-of-mass of molecule
* Ixx Iyy Izz Ixy Ixz Iyz *inertia* = 6 components of inertia tensor of molecule
.. list-table::
:header-rows: 1
:widths: auto
For *mass*, *com*, and *inertia*, the default is for LAMMPS to
calculate this quantity itself if needed, assuming the molecules
consist of a set of point particles or finite-size particles (with a
non-zero diameter) that do not overlap. If finite-size particles in
the molecule do overlap, LAMMPS will not account for the overlap
effects when calculating any of these 3 quantities, so you should
pre-compute them yourself and list the values in the file.
* - Number(s)
- Keyword
- Meaning
- Default Value
* - N
- atoms
- # of atoms N in molecule
- 0
* - Nb
- bonds
- # of bonds Nb in molecule
- 0
* - Na
- angles
- # of angles Na in molecule
- 0
* - Nd
- dihedrals
- # of dihedrals Nd in molecule
- 0
* - Ni
- impropers
- # of impropers Ni in molecule
- 0
* - Nf
- fragments
- # of fragments Nf in molecule
- 0
* - Ninteger Ndouble
- body
- # of integer and floating-point values in body particle
- 0
* - Mtotal
- mass
- total mass of molecule
- computed
* - Xc Yc Zc
- com
- coordinates of center-of-mass of molecule
- computed
* - Ixx Iyy Izz Ixy Ixz Iyz
- inertia
- 6 components of inertia tensor of molecule
- computed
For *mass*, *com*, and *inertia*, the default is for LAMMPS to calculate
this quantity itself if needed, assuming the molecules consist of a set
of point particles or finite-size particles (with a non-zero diameter)
that do **not** overlap. If finite-size particles in the molecule
**do** overlap, LAMMPS will not account for the overlap effects when
calculating any of these 3 quantities, so you should pre-compute them
yourself and list the values in the file.
The mass and center-of-mass coordinates (Xc,Yc,Zc) are
self-explanatory. The 6 moments of inertia (ixx,iyy,izz,ixy,ixz,iyz)
@ -188,7 +261,7 @@ internally.
These are the allowed section keywords for the body of the file.
* *Coords, Types, Molecules, Fragments, Charges, Diameters, Masses* = atom-property sections
* *Coords, Types, Molecules, Fragments, Charges, Diameters, Dipoles, Masses* = atom-property sections
* *Bonds, Angles, Dihedrals, Impropers* = molecular topology sections
* *Special Bond Counts, Special Bonds* = special neighbor info
* *Shake Flags, Shake Atoms, Shake Bond Types* = SHAKE info
@ -303,6 +376,21 @@ not listed, the default diameter of each atom in the molecule is 1.0.
----------
..versionadded:: TBD
*Dipoles* section:
* one line per atom
* line syntax: ID mux muy muz
* mux,muy,muz = x-, y-, and z-component of point dipole vector of atom
This section is only allowed for :doc:`atom styles <atom_style>` that
support particles with point dipoles, e.g. atom_style dipole. If not
listed, the default dipole component of each atom in the molecule is set
to 0.0.
----------
*Masses* section:
* one line per atom

View File

@ -72,7 +72,7 @@ interactions between particles which depend on the distance and have a
cutoff. The potential function must be provided as an expression string
using "r" as the distance variable. With pair style *lepton/coul* one
may additionally reference the charges of the two atoms of the pair with
"qi" and "qj", respectively. With pair style *lepton/coul* one may
"qi" and "qj", respectively. With pair style *lepton/sphere* one may
instead reference the radii of the two atoms of the pair with "radi" and
"radj", respectively; this is half of the diameter that can be set in
:doc:`data files <read_data>` or the :doc:`set command <set>`.
@ -166,8 +166,8 @@ mixing. Thus, expressions for *all* I,J pairs must be specified
explicitly.
Only pair style *lepton* supports the :doc:`pair_modify shift <pair_modify>`
option for shifting the energy of the pair interaction so that it is
0 at the cutoff, pair styles *lepton/coul* and *lepton/sphere* do *not*.
option for shifting the potential energy of the pair interaction so that
it is 0 at the cutoff, pair styles *lepton/coul* and *lepton/sphere* do *not*.
The :doc:`pair_modify table <pair_modify>` options are not relevant for
the these pair styles.

View File

@ -151,6 +151,7 @@ asphericity
Asq
assignee
assively
associativity
Asta
Astart
Astop

View File

@ -22,22 +22,26 @@
"""
Import basic modules
"""
# for python2/3 compatibility
from __future__ import print_function
import sys, os, timeit
from timeit import default_timer as timer
start_time = timer()
"""
Try to import numpy; if failed, import a local version mynumpy
Try to import numpy; if failed, import a local version mynumpy
which needs to be provided
"""
try:
import numpy as np
except:
print >> sys.stderr, "numpy not found. Exiting."
print("numpy not found. Exiting.", file=sys.stderr)
sys.exit(1)
"""
Check that the required arguments (box offset and size in simulation units
Check that the required arguments (box offset and size in simulation units
and the sequence file were provided
"""
try:
@ -45,8 +49,8 @@ try:
box_length = float(sys.argv[2])
infile = sys.argv[3]
except:
print >> sys.stderr, "Usage: %s <%s> <%s> <%s>" % (sys.argv[0], \
"box offset", "box length", "file with sequences")
print( "Usage: %s <%s> <%s> <%s>" % (sys.argv[0], \
"box offset", "box length", "file with sequences"), file=sys.stderr)
sys.exit(1)
box = np.array ([box_length, box_length, box_length])
@ -57,8 +61,7 @@ try:
inp = open (infile, 'r')
inp.close()
except:
print >> sys.stderr, "Could not open file '%s' for reading. \
Aborting." % infile
print( "Could not open file '%s' for reading. Aborting." % infile, file=sys.stderr)
sys.exit(2)
# return parts of a string
@ -86,7 +89,7 @@ Define auxiliary variables for the construction of a helix
# center of the double strand
CM_CENTER_DS = POS_BASE + 0.2
# ideal distance between base sites of two nucleotides
# ideal distance between base sites of two nucleotides
# which are to be base paired in a duplex
BASE_BASE = 0.3897628551303122
@ -118,7 +121,7 @@ strandnum = []
bonds = []
"""
"""
Convert local body frame to quaternion DOF
"""
def exyz_to_quat (mya1, mya3):
@ -135,25 +138,25 @@ def exyz_to_quat (mya1, mya3):
# compute other components from it
if q0sq >= 0.25:
myquat[0] = np.sqrt(q0sq)
myquat[1] = (mya2[2] - mya3[1]) / (4.0*myquat[0])
myquat[2] = (mya3[0] - mya1[2]) / (4.0*myquat[0])
myquat[3] = (mya1[1] - mya2[0]) / (4.0*myquat[0])
myquat[0] = np.sqrt(q0sq)
myquat[1] = (mya2[2] - mya3[1]) / (4.0*myquat[0])
myquat[2] = (mya3[0] - mya1[2]) / (4.0*myquat[0])
myquat[3] = (mya1[1] - mya2[0]) / (4.0*myquat[0])
elif q1sq >= 0.25:
myquat[1] = np.sqrt(q1sq)
myquat[0] = (mya2[2] - mya3[1]) / (4.0*myquat[1])
myquat[2] = (mya2[0] + mya1[1]) / (4.0*myquat[1])
myquat[3] = (mya1[2] + mya3[0]) / (4.0*myquat[1])
myquat[1] = np.sqrt(q1sq)
myquat[0] = (mya2[2] - mya3[1]) / (4.0*myquat[1])
myquat[2] = (mya2[0] + mya1[1]) / (4.0*myquat[1])
myquat[3] = (mya1[2] + mya3[0]) / (4.0*myquat[1])
elif q2sq >= 0.25:
myquat[2] = np.sqrt(q2sq)
myquat[0] = (mya3[0] - mya1[2]) / (4.0*myquat[2])
myquat[1] = (mya2[0] + mya1[1]) / (4.0*myquat[2])
myquat[3] = (mya3[1] + mya2[2]) / (4.0*myquat[2])
myquat[2] = np.sqrt(q2sq)
myquat[0] = (mya3[0] - mya1[2]) / (4.0*myquat[2])
myquat[1] = (mya2[0] + mya1[1]) / (4.0*myquat[2])
myquat[3] = (mya3[1] + mya2[2]) / (4.0*myquat[2])
elif q3sq >= 0.25:
myquat[3] = np.sqrt(q3sq)
myquat[0] = (mya1[1] - mya2[0]) / (4.0*myquat[3])
myquat[1] = (mya3[0] + mya1[2]) / (4.0*myquat[3])
myquat[2] = (mya3[1] + mya2[2]) / (4.0*myquat[3])
myquat[3] = np.sqrt(q3sq)
myquat[0] = (mya1[1] - mya2[0]) / (4.0*myquat[3])
myquat[1] = (mya3[0] + mya1[2]) / (4.0*myquat[3])
myquat[2] = (mya3[1] + mya2[2]) / (4.0*myquat[3])
norm = 1.0/np.sqrt(myquat[0]*myquat[0] + myquat[1]*myquat[1] + \
myquat[2]*myquat[2] + myquat[3]*myquat[3])
@ -169,62 +172,62 @@ Adds a strand to the system by appending it to the array of previous strands
"""
def add_strands (mynewpositions, mynewa1s, mynewa3s):
overlap = False
# This is a simple check for each of the particles where for previously
# placed particles i we check whether it overlaps with any of the
# This is a simple check for each of the particles where for previously
# placed particles i we check whether it overlaps with any of the
# newly created particles j
print >> sys.stdout, "## Checking for overlaps"
print( "## Checking for overlaps", file=sys.stdout)
for i in xrange(len(positions)):
for i in range(len(positions)):
p = positions[i]
pa1 = a1s[i]
p = positions[i]
pa1 = a1s[i]
for j in xrange (len(mynewpositions)):
for j in range (len(mynewpositions)):
q = mynewpositions[j]
qa1 = mynewa1s[j]
q = mynewpositions[j]
qa1 = mynewa1s[j]
# skip particles that are anyway too far away
dr = p - q
dr -= box * np.rint (dr / box)
if np.dot(dr, dr) > RC2:
continue
# skip particles that are anyway too far away
dr = p - q
dr -= box * np.rint(dr / box)
if np.dot(dr, dr) > RC2:
continue
# base site and backbone site of the two particles
# base site and backbone site of the two particles
p_pos_back = p + pa1 * POS_BACK
p_pos_base = p + pa1 * POS_BASE
q_pos_back = q + qa1 * POS_BACK
q_pos_base = q + qa1 * POS_BASE
# check for no overlap between the two backbone sites
# check for no overlap between the two backbone sites
dr = p_pos_back - q_pos_back
dr -= box * np.rint (dr / box)
dr -= box * np.rint(dr / box)
if np.dot(dr, dr) < RC2_BACK:
overlap = True
# check for no overlap between the two base sites
# check for no overlap between the two base sites
dr = p_pos_base - q_pos_base
dr -= box * np.rint (dr / box)
dr -= box * np.rint(dr / box)
if np.dot(dr, dr) < RC2_BASE:
overlap = True
# check for no overlap between backbone site of particle p
# with base site of particle q
# check for no overlap between backbone site of particle p
# with base site of particle q
dr = p_pos_back - q_pos_base
dr -= box * np.rint (dr / box)
if np.dot(dr, dr) < RC2_BACK_BASE:
overlap = True
# check for no overlap between base site of particle p and
# backbone site of particle q
# check for no overlap between base site of particle p and
# backbone site of particle q
dr = p_pos_base - q_pos_back
dr -= box * np.rint (dr / box)
if np.dot(dr, dr) < RC2_BACK_BASE:
overlap = True
# exit if there is an overlap
# exit if there is an overlap
if overlap:
return False
@ -237,10 +240,10 @@ def add_strands (mynewpositions, mynewa1s, mynewa3s):
a1s.append (p)
for p in mynewa3s:
a3s.append (p)
# calculate quaternion from local body frame and append
for ia in xrange(len(mynewpositions)):
mynewquaternions = exyz_to_quat(mynewa1s[ia],mynewa3s[ia])
quaternions.append(mynewquaternions)
# calculate quaternion from local body frame and append
for ia in range(len(mynewpositions)):
mynewquaternions = exyz_to_quat(mynewa1s[ia],mynewa3s[ia])
quaternions.append(mynewquaternions)
return True
@ -281,7 +284,7 @@ def get_rotation_matrix(axis, anglest):
[olc*x*z-st*y, olc*y*z+st*x, olc*z*z+ct]])
"""
Generates the position and orientation vectors of a
Generates the position and orientation vectors of a
(single or double) strand from a sequence string
"""
def generate_strand(bp, sequence=None, start_pos=np.array([0, 0, 0]), \
@ -295,76 +298,75 @@ def generate_strand(bp, sequence=None, start_pos=np.array([0, 0, 0]), \
# overall direction of the helix
dir = np.array(dir, dtype=float)
if sequence == None:
sequence = np.random.randint(1, 5, bp)
sequence = np.random.randint(1, 5, bp)
# the elseif here is most likely redundant
# the elseif here is most likely redundant
elif len(sequence) != bp:
n = bp - len(sequence)
sequence += np.random.randint(1, 5, n)
print >> sys.stderr, "sequence is too short, adding %d random bases" % n
n = bp - len(sequence)
sequence += np.random.randint(1, 5, n)
print( "sequence is too short, adding %d random bases" % n, file=sys.stderr)
# normalize direction
dir_norm = np.sqrt(np.dot(dir,dir))
if dir_norm < 1e-10:
print >> sys.stderr, "direction must be a valid vector, \
defaulting to (0, 0, 1)"
dir = np.array([0, 0, 1])
print( "direction must be a valid vector, defaulting to (0, 0, 1)", file=sys.stderr)
dir = np.array([0, 0, 1])
else: dir /= dir_norm
# find a vector orthogonal to dir to act as helix direction,
# if not provided switch off random orientation
if perp is None or perp is False:
v1 = np.random.random_sample(3)
v1 -= dir * (np.dot(dir, v1))
v1 /= np.sqrt(sum(v1*v1))
v1 = np.random.random_sample(3)
v1 -= dir * (np.dot(dir, v1))
v1 /= np.sqrt(sum(v1*v1))
else:
v1 = perp;
v1 = perp;
# generate rotational matrix representing the overall rotation of the helix
R0 = get_rotation_matrix(dir, rot)
# rotation matrix corresponding to one step along the helix
R = get_rotation_matrix(dir, [1, "bp"])
# set the vector a1 (backbone to base) to v1
# set the vector a1 (backbone to base) to v1
a1 = v1
# apply the global rotation to a1
# apply the global rotation to a1
a1 = np.dot(R0, a1)
# set the position of the fist backbone site to start_pos
rb = np.array(start_pos)
# set a3 to the direction of the helix
a3 = dir
for i in range(bp):
# work out the position of the centre of mass of the nucleotide
rcdm = rb - CM_CENTER_DS * a1
# append to newpositions
mynewpositions.append(rcdm)
mynewa1s.append(a1)
mynewa3s.append(a3)
# if we are not at the end of the helix, we work out a1 and rb for the
# next nucleotide along the helix
if i != bp - 1:
a1 = np.dot(R, a1)
rb += a3 * BASE_BASE
rcdm = rb - CM_CENTER_DS * a1
# if we are working on a double strand, we do a cycle similar
# append to newpositions
mynewpositions.append(rcdm)
mynewa1s.append(a1)
mynewa3s.append(a3)
# if we are not at the end of the helix, we work out a1 and rb for the
# next nucleotide along the helix
if i != bp - 1:
a1 = np.dot(R, a1)
rb += a3 * BASE_BASE
# if we are working on a double strand, we do a cycle similar
# to the previous one but backwards
if double == True:
a1 = -a1
a3 = -dir
R = R.transpose()
for i in range(bp):
rcdm = rb - CM_CENTER_DS * a1
mynewpositions.append (rcdm)
mynewa1s.append (a1)
mynewa3s.append (a3)
a1 = np.dot(R, a1)
rb += a3 * BASE_BASE
a1 = -a1
a3 = -dir
R = R.transpose()
for i in range(bp):
rcdm = rb - CM_CENTER_DS * a1
mynewpositions.append (rcdm)
mynewa1s.append (a1)
mynewa3s.append (a3)
a1 = np.dot(R, a1)
rb += a3 * BASE_BASE
assert (len (mynewpositions) > 0)
@ -391,10 +393,10 @@ def read_strands(filename):
try:
infile = open (filename)
except:
print >> sys.stderr, "Could not open file '%s'. Aborting." % filename
print( "Could not open file '%s'. Aborting." % filename, file=sys.stderr )
sys.exit(2)
# This block works out the number of nucleotides and strands by reading
# This block works out the number of nucleotides and strands by reading
# the number of non-empty lines in the input file and the number of letters,
# taking the possible DOUBLE keyword into account.
nstrands, nnucl, nbonds = 0, 0, 0
@ -406,30 +408,29 @@ def read_strands(filename):
if line[:6] == 'DOUBLE':
line = line.split()[1]
length = len(line)
print >> sys.stdout, "## Found duplex of %i base pairs" % length
print( "## Found duplex of %i base pairs" % length, file=sys.stdout)
nnucl += 2*length
nstrands += 2
nbonds += (2*length-2)
nbonds += (2*length-2)
else:
line = line.split()[0]
length = len(line)
print >> sys.stdout, \
"## Found single strand of %i bases" % length
print( "## Found single strand of %i bases" % length, file=sys.stdout)
nnucl += length
nstrands += 1
nbonds += length-1
nbonds += length-1
# rewind the sequence input file
infile.seek(0)
print >> sys.stdout, "## nstrands, nnucl = ", nstrands, nnucl
print( "## nstrands, nnucl = ", nstrands, nnucl, file=sys.stdout)
# generate the data file in LAMMPS format
try:
out = open ("data.oxdna", "w")
except:
print >> sys.stderr, "Could not open data file for writing. Aborting."
print( "Could not open data file for writing. Aborting.", file=sys.stderr)
sys.exit(2)
lines = infile.readlines()
nlines = len(lines)
i = 1
@ -440,115 +441,114 @@ def read_strands(filename):
line = line.upper().strip()
# skip empty lines
if len(line) == 0:
i += 1
continue
if len(line) == 0:
i += 1
continue
# block for duplexes: last argument of the generate function
# is set to 'True'
# block for duplexes: last argument of the generate function
# is set to 'True'
if line[:6] == 'DOUBLE':
line = line.split()[1]
length = len(line)
seq = [(base_to_number[x]) for x in line]
myns += 1
for b in xrange(length):
basetype.append(seq[b])
strandnum.append(myns)
myns += 1
for b in range(length):
basetype.append(seq[b])
strandnum.append(myns)
for b in xrange(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
for b in range(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
# create the sequence of the second strand as made of
# complementary bases
seq2 = [5-s for s in seq]
seq2.reverse()
# create the sequence of the second strand as made of
# complementary bases
seq2 = [5-s for s in seq]
seq2.reverse()
myns += 1
for b in xrange(length):
basetype.append(seq2[b])
strandnum.append(myns)
myns += 1
for b in range(length):
basetype.append(seq2[b])
strandnum.append(myns)
for b in xrange(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
print >> sys.stdout, "## Created duplex of %i bases" % (2*length)
for b in range(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
# generate random position of the first nucleotide
print( "## Created duplex of %i bases" % (2*length), file=sys.stdout)
# generate random position of the first nucleotide
cdm = box_offset + np.random.random_sample(3) * box
# generate the random direction of the helix
# generate the random direction of the helix
axis = np.random.random_sample(3)
axis /= np.sqrt(np.dot(axis, axis))
# use the generate function defined above to create
# the position and orientation vector of the strand
# use the generate function defined above to create
# the position and orientation vector of the strand
newpositions, newa1s, newa3s = generate_strand(len(line), \
sequence=seq, dir=axis, start_pos=cdm, double=True)
sequence=seq, dir=axis, start_pos=cdm, double=True)
# generate a new position for the strand until it does not overlap
# with anything already present
start = timer()
# with anything already present
start = timer()
while not add_strands(newpositions, newa1s, newa3s):
cdm = box_offset + np.random.random_sample(3) * box
axis = np.random.random_sample(3)
axis /= np.sqrt(np.dot(axis, axis))
newpositions, newa1s, newa3s = generate_strand(len(line), \
sequence=seq, dir=axis, start_pos=cdm, double=True)
print >> sys.stdout, "## Trying %i" % i
end = timer()
print >> sys.stdout, "## Added duplex of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \
(2*length, i, nlines, end-start, len(positions), nnucl)
sequence=seq, dir=axis, start_pos=cdm, double=True)
print( "## Trying %i" % i, file=sys.stdout)
end = timer()
print( "## Added duplex of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \
(2*length, i, nlines, end-start, len(positions), nnucl), file=sys.stdout)
# block for single strands: last argument of the generate function
# is set to 'False'
# block for single strands: last argument of the generate function
# is set to 'False'
else:
length = len(line)
seq = [(base_to_number[x]) for x in line]
myns += 1
for b in xrange(length):
basetype.append(seq[b])
strandnum.append(myns)
myns += 1
for b in range(length):
basetype.append(seq[b])
strandnum.append(myns)
for b in xrange(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
for b in range(length-1):
bondpair = [noffset + b, noffset + b + 1]
bonds.append(bondpair)
noffset += length
# generate random position of the first nucleotide
# generate random position of the first nucleotide
cdm = box_offset + np.random.random_sample(3) * box
# generate the random direction of the helix
# generate the random direction of the helix
axis = np.random.random_sample(3)
axis /= np.sqrt(np.dot(axis, axis))
print >> sys.stdout, \
"## Created single strand of %i bases" % length
print("## Created single strand of %i bases" % length, file=sys.stdout)
newpositions, newa1s, newa3s = generate_strand(length, \
sequence=seq, dir=axis, start_pos=cdm, double=False)
start = timer()
start = timer()
while not add_strands(newpositions, newa1s, newa3s):
cdm = box_offset + np.random.random_sample(3) * box
axis = np.random.random_sample(3)
axis /= np.sqrt(np.dot(axis, axis))
axis /= np.sqrt(np.dot(axis, axis))
newpositions, newa1s, newa3s = generate_strand(length, \
sequence=seq, dir=axis, start_pos=cdm, double=False)
sequence=seq, dir=axis, start_pos=cdm, double=False)
print >> sys.stdout, "## Trying %i" % (i)
end = timer()
print >> sys.stdout, "## Added single strand of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \
(length, i, nlines, end-start,len(positions), nnucl)
end = timer()
print( "## Added single strand of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \
(length, i, nlines, end-start,len(positions), nnucl), file=sys.stdout)
i += 1
# sanity check
if not len(positions) == nnucl:
print len(positions), nnucl
print( len(positions), nnucl )
raise AssertionError
out.write('# LAMMPS data file\n')
@ -580,44 +580,41 @@ def read_strands(filename):
out.write('Atoms\n')
out.write('\n')
for i in xrange(nnucl):
out.write('%d %d %22.15le %22.15le %22.15le %d 1 1\n' \
% (i+1, basetype[i], \
positions[i][0], positions[i][1], positions[i][2], \
strandnum[i]))
for i in range(nnucl):
out.write('%d %d %22.15le %22.15le %22.15le %d 1 1\n' \
% (i+1, basetype[i], positions[i][0], positions[i][1], positions[i][2], strandnum[i]))
out.write('\n')
out.write('# Atom-ID, translational, rotational velocity\n')
out.write('Velocities\n')
out.write('\n')
for i in xrange(nnucl):
out.write("%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \
% (i+1,0.0,0.0,0.0,0.0,0.0,0.0))
for i in range(nnucl):
out.write("%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \
% (i+1,0.0,0.0,0.0,0.0,0.0,0.0))
out.write('\n')
out.write('# Atom-ID, shape, quaternion\n')
out.write('Ellipsoids\n')
out.write('\n')
for i in xrange(nnucl):
out.write(\
"%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \
% (i+1,1.1739845031423408,1.1739845031423408,1.1739845031423408, \
quaternions[i][0],quaternions[i][1], quaternions[i][2],quaternions[i][3]))
for i in range(nnucl):
out.write("%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \
% (i+1,1.1739845031423408,1.1739845031423408,1.1739845031423408, \
quaternions[i][0],quaternions[i][1], quaternions[i][2],quaternions[i][3]))
out.write('\n')
out.write('# Bond topology\n')
out.write('Bonds\n')
out.write('\n')
for i in xrange(nbonds):
out.write("%d %d %d %d\n" % (i+1,1,bonds[i][0],bonds[i][1]))
for i in range(nbonds):
out.write("%d %d %d %d\n" % (i+1,1,bonds[i][0],bonds[i][1]))
out.close()
print >> sys.stdout, "## Wrote data to 'data.oxdna'"
print >> sys.stdout, "## DONE"
print("## Wrote data to 'data.oxdna'", file=sys.stdout)
print("## DONE", file=sys.stdout)
# call the above main() function, which executes the program
read_strands (infile)
@ -627,4 +624,6 @@ runtime = end_time-start_time
hours = runtime/3600
minutes = (runtime-np.rint(hours)*3600)/60
seconds = (runtime-np.rint(hours)*3600-np.rint(minutes)*60)%60
print >> sys.stdout, "## Total runtime %ih:%im:%.2fs" % (hours,minutes,seconds)
print( "## Total runtime %ih:%im:%.2fs" % (hours,minutes,seconds), file=sys.stdout)

View File

@ -1,5 +1,8 @@
# Setup tool for oxDNA input in LAMMPS format.
# for python2/3 compatibility
from __future__ import print_function
import math,numpy as np,sys,os
# system size
@ -250,59 +253,59 @@ def duplex_array():
qrot3=math.sin(0.5*twist)
for letter in strand[2]:
temp1=[]
temp2=[]
temp1=[]
temp2=[]
temp1.append(nt2num[letter])
temp2.append(compnt2num[letter])
temp1.append(nt2num[letter])
temp2.append(compnt2num[letter])
temp1.append([posx1,posy1,posz1])
temp2.append([posx2,posy2,posz2])
temp1.append([posx1,posy1,posz1])
temp2.append([posx2,posy2,posz2])
vel=[0,0,0,0,0,0]
temp1.append(vel)
temp2.append(vel)
vel=[0,0,0,0,0,0]
temp1.append(vel)
temp2.append(vel)
temp1.append(shape)
temp2.append(shape)
temp1.append(shape)
temp2.append(shape)
temp1.append(quat1)
temp2.append(quat2)
temp1.append(quat1)
temp2.append(quat2)
quat1_0 = quat1[0]*qrot0 - quat1[1]*qrot1 - quat1[2]*qrot2 - quat1[3]*qrot3
quat1_1 = quat1[0]*qrot1 + quat1[1]*qrot0 + quat1[2]*qrot3 - quat1[3]*qrot2
quat1_2 = quat1[0]*qrot2 + quat1[2]*qrot0 + quat1[3]*qrot1 - quat1[1]*qrot3
quat1_3 = quat1[0]*qrot3 + quat1[3]*qrot0 + quat1[1]*qrot2 + quat1[2]*qrot1
quat1_0 = quat1[0]*qrot0 - quat1[1]*qrot1 - quat1[2]*qrot2 - quat1[3]*qrot3
quat1_1 = quat1[0]*qrot1 + quat1[1]*qrot0 + quat1[2]*qrot3 - quat1[3]*qrot2
quat1_2 = quat1[0]*qrot2 + quat1[2]*qrot0 + quat1[3]*qrot1 - quat1[1]*qrot3
quat1_3 = quat1[0]*qrot3 + quat1[3]*qrot0 + quat1[1]*qrot2 + quat1[2]*qrot1
quat1 = [quat1_0,quat1_1,quat1_2,quat1_3]
quat1 = [quat1_0,quat1_1,quat1_2,quat1_3]
posx1=axisx - dcomh*(quat1[0]**2+quat1[1]**2-quat1[2]**2-quat1[3]**2)
posy1=axisy - dcomh*(2*(quat1[1]*quat1[2]+quat1[0]*quat1[3]))
posz1=posz1+risez
posx1=axisx - dcomh*(quat1[0]**2+quat1[1]**2-quat1[2]**2-quat1[3]**2)
posy1=axisy - dcomh*(2*(quat1[1]*quat1[2]+quat1[0]*quat1[3]))
posz1=posz1+risez
quat2_0 = quat2[0]*qrot0 - quat2[1]*qrot1 - quat2[2]*qrot2 + quat2[3]*qrot3
quat2_1 = quat2[0]*qrot1 + quat2[1]*qrot0 - quat2[2]*qrot3 - quat2[3]*qrot2
quat2_2 = quat2[0]*qrot2 + quat2[2]*qrot0 + quat2[3]*qrot1 + quat2[1]*qrot3
quat2_3 =-quat2[0]*qrot3 + quat2[3]*qrot0 + quat2[1]*qrot2 + quat2[2]*qrot1
quat2_0 = quat2[0]*qrot0 - quat2[1]*qrot1 - quat2[2]*qrot2 + quat2[3]*qrot3
quat2_1 = quat2[0]*qrot1 + quat2[1]*qrot0 - quat2[2]*qrot3 - quat2[3]*qrot2
quat2_2 = quat2[0]*qrot2 + quat2[2]*qrot0 + quat2[3]*qrot1 + quat2[1]*qrot3
quat2_3 =-quat2[0]*qrot3 + quat2[3]*qrot0 + quat2[1]*qrot2 + quat2[2]*qrot1
quat2 = [quat2_0,quat2_1,quat2_2,quat2_3]
quat2 = [quat2_0,quat2_1,quat2_2,quat2_3]
posx2=axisx + dcomh*(quat1[0]**2+quat1[1]**2-quat1[2]**2-quat1[3]**2)
posy2=axisy + dcomh*(2*(quat1[1]*quat1[2]+quat1[0]*quat1[3]))
posz2=posz1
posx2=axisx + dcomh*(quat1[0]**2+quat1[1]**2-quat1[2]**2-quat1[3]**2)
posy2=axisy + dcomh*(2*(quat1[1]*quat1[2]+quat1[0]*quat1[3]))
posz2=posz1
if (len(nucleotide)+1 > strandstart):
topology.append([1,len(nucleotide),len(nucleotide)+1])
comptopo.append([1,len(nucleotide)+len(strand[2]),len(nucleotide)+len(strand[2])+1])
if (len(nucleotide)+1 > strandstart):
topology.append([1,len(nucleotide),len(nucleotide)+1])
comptopo.append([1,len(nucleotide)+len(strand[2]),len(nucleotide)+len(strand[2])+1])
nucleotide.append(temp1)
compstrand.append(temp2)
nucleotide.append(temp1)
compstrand.append(temp2)
for ib in range(len(compstrand)):
nucleotide.append(compstrand[len(compstrand)-1-ib])
nucleotide.append(compstrand[len(compstrand)-1-ib])
for ib in range(len(comptopo)):
topology.append(comptopo[ib])
topology.append(comptopo[ib])
return

View File

@ -40,7 +40,7 @@ fix 1 statted_grp_REACT nvt temp $T $T 100
fix 4 bond_react_MASTER_group temp/rescale 1 $T $T 1 1
thermo_style custom step temp press density f_myrxns[1]
thermo_style custom step temp press density f_myrxns[*]
thermo 100

View File

@ -26,7 +26,7 @@ read_data large_nylon_melt.data.gz &
extra/angle/per/atom 15 &
extra/dihedral/per/atom 15 &
extra/improper/per/atom 25 &
extra/special/per/atom 25
extra/special/per/atom 25
velocity all create 800.0 4928459 dist gaussian
@ -50,7 +50,7 @@ fix 1 statted_grp_REACT nvt temp 800 800 100
# you can use the internally created 'bond_react_MASTER_group', like so:
# fix 2 bond_react_MASTER_group temp/rescale 1 800 800 10 1
thermo_style custom step temp press density f_myrxns[1] f_myrxns[2] # cumulative reaction counts
thermo_style custom step temp press density f_myrxns[*] # cumulative reaction counts
# restart 100 restart1 restart2

View File

@ -20,7 +20,8 @@ improper_style class2
special_bonds lj/coul 0 0 1
pair_modify tail yes mix sixthpower
read_data tiny_epoxy.data
read_data tiny_epoxy.data &
extra/special/per/atom 25
velocity all create 300.0 4928459 dist gaussian
@ -44,7 +45,7 @@ fix rxns all bond/react stabilization yes statted_grp .03 &
fix 1 statted_grp_REACT nvt temp 300 300 100
thermo_style custom step temp f_rxns[1] f_rxns[2] f_rxns[3] f_rxns[4]
thermo_style custom step temp f_rxns[*]
run 2000

View File

@ -50,7 +50,7 @@ fix 1 statted_grp_REACT nvt temp 300 300 100
# by using the internally-created 'bond_react_MASTER_group', like so:
fix 4 bond_react_MASTER_group temp/rescale 1 300 300 10 1
thermo_style custom step temp press density f_myrxns[1] f_myrxns[2]
thermo_style custom step temp press density f_myrxns[*]
# restart 100 restart1 restart2

View File

@ -54,7 +54,7 @@ fix 1 statted_grp_REACT nvt temp 300 300 100
# by using the internally-created 'bond_react_MASTER_group', like so:
fix 4 bond_react_MASTER_group temp/rescale 1 300 300 10 1
thermo_style custom step temp press density v_prob1 v_prob2 f_myrxns[1] f_myrxns[2]
thermo_style custom step temp press density v_prob1 v_prob2 f_myrxns[*]
# restart 100 restart1 restart2

View File

@ -47,7 +47,7 @@ fix myrxns all bond/react stabilization no &
fix 1 all nve/limit .03
thermo_style custom step temp press density f_myrxns[1] f_myrxns[2]
thermo_style custom step temp press density f_myrxns[*]
# restart 100 restart1 restart2

View File

@ -51,7 +51,7 @@ fix 1 statted_grp_REACT nvt temp $T $T 100
fix 4 bond_react_MASTER_group temp/rescale 1 $T $T 1 1
thermo_style custom step temp press density f_rxn1[1] f_rxn1[2] f_rxn1[3]
thermo_style custom step temp press density f_rxn1[*]
run 10000

View File

@ -15,7 +15,7 @@
***************************************************************************/
#ifndef LAL_BASE_SPH_H
#define LAL_BASE_DPD_H
#define LAL_BASE_SPH_H
#include "lal_device.h"
#include "lal_balance.h"

View File

@ -102,6 +102,7 @@ __kernel void k_coul_slater_long(const __global numtyp4 *restrict x_,
numtyp t = ucl_recip((numtyp)1.0 + EWALD_P*grij);
_erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
fetch(prefactor,j,q_tex);
prefactor *= qqrd2e * scale[mtype] * qtmp/r;
numtyp rlamdainv = r * lamdainv;
numtyp exprlmdainv = ucl_exp((numtyp)-2.0*rlamdainv);
numtyp slater_term = exprlmdainv*((numtyp)1.0 + ((numtyp)2.0*rlamdainv*((numtyp)1.0+rlamdainv)));

View File

@ -13,8 +13,8 @@
email : ndactrung@gmail.com
***************************************************************************/
#ifndef LAL_Coul_Slater_Long_H
#define LAL_Coul_Slater_Long_H
#ifndef LAL_COUL_SLATER_LONG_H
#define LAL_COUL_SLATER_LONG_H
#include "lal_base_charge.h"

View File

@ -303,7 +303,7 @@ double EAMT::host_memory_usage() const {
}
// ---------------------------------------------------------------------------
// Copy nbor list from host if necessary and then compute atom energies/forces
// Copy nbor list from host if necessary and then compute per-atom fp
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void EAMT::compute(const int f_ago, const int inum_full, const int nlocal,
@ -379,7 +379,7 @@ void EAMT::compute(const int f_ago, const int inum_full, const int nlocal,
}
// ---------------------------------------------------------------------------
// Reneighbor on GPU and then compute per-atom densities
// Reneighbor on GPU and then compute per-atom fp
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
int** EAMT::compute(const int ago, const int inum_full, const int nall,
@ -461,7 +461,7 @@ int** EAMT::compute(const int ago, const int inum_full, const int nall,
}
// ---------------------------------------------------------------------------
// Copy nbor list from host if necessary and then calculate forces, virials,..
// Update per-atom fp, and then calculate forces, virials,..
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void EAMT::compute2(int *ilist, const bool eflag, const bool vflag,

View File

@ -13,8 +13,8 @@
email : ndactrung@gmail.com
***************************************************************************/
#ifndef LAL_SPH_LJ_H
#define LAL_SPH_LJ_H
#ifndef LAL_SPH_HEATCONDUCTION_H
#define LAL_SPH_HEATCONDUCTION_H
#include "lal_base_sph.h"

2
src/.gitignore vendored
View File

@ -348,8 +348,6 @@
/bond_bpm_spring.h
/compute_nbond_atom.cpp
/compute_nbond_atom.h
/fix_bond_history.cpp
/fix_bond_history.h
/fix_nve_bpm_sphere.cpp
/fix_nve_bpm_sphere.h
/fix_update_special_bonds.cpp

View File

@ -1,49 +0,0 @@
# Install/unInstall package files in LAMMPS
# mode = 0/1/2 for uninstall/install/update
mode=$1
# enforce using portable C locale
LC_ALL=C
export LC_ALL
# arg1 = file, arg2 = file it depends on
action () {
if (test $mode = 0) then
rm -f ../$1
elif (! cmp -s $1 ../$1) then
if (test -z "$2" || test -e ../$2) then
cp $1 ..
if (test $mode = 2) then
echo " updating src/$1"
fi
fi
elif (test -n "$2") then
if (test ! -e ../$2) then
rm -f ../$1
fi
fi
}
# all package files with no dependencies
for file in *.cpp *.h; do
test -f ${file} && action $file
done
# edit 2 Makefile.package files to include/exclude package info
if (test $1 = 1) then
if (test -e ../Makefile.package) then
sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_BPM |' ../Makefile.package
fi
elif (test $1 = 0) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*LMP_BPM[^ \t]* //' ../Makefile.package
fi
fi

View File

@ -19,8 +19,8 @@
#include "error.h"
#include "force.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neighbor.h"
#include "pair.h"
#include <utility>
@ -62,7 +62,8 @@ void FixUpdateSpecialBonds::setup(int /*vflag*/)
// Require atoms know about all of their bonds and if they break
if (force->newton_bond) error->all(FLERR, "Fix update/special/bonds requires Newton bond off");
if (!atom->avec->bonds_allow) error->all(FLERR, "Fix update/special/bonds requires atom bonds");
if (!atom->avec->bonds_allow)
error->all(FLERR, "Fix update/special/bonds requires an atom style supporting bonds");
// special lj must be 0 1 1 to censor pair forces between bonded particles
// special coulomb must be 1 1 1 to ensure all pairs are included in the
@ -153,7 +154,7 @@ void FixUpdateSpecialBonds::pre_exchange()
void FixUpdateSpecialBonds::pre_force(int /*vflag*/)
{
int ilist, nlist, i1, i2, j, jj, jnum;
int i1, i2, j, jj, jnum;
int *jlist, *numneigh, **firstneigh;
tagint tag1, tag2;
NeighList *list;
@ -164,7 +165,7 @@ void FixUpdateSpecialBonds::pre_force(int /*vflag*/)
// In theory could communicate a list of broken bonds to neighboring processors here
// to remove restriction that users use Newton bond off
for (int ilist = 0; ilist < neighbor->nlist; ilist ++) {
for (int ilist = 0; ilist < neighbor->nlist; ilist++) {
list = neighbor->lists[ilist];
// Skip copied lists, will update original
@ -202,30 +203,40 @@ void FixUpdateSpecialBonds::pre_force(int /*vflag*/)
}
}
for (auto const &it : new_created_pairs) {
tag1 = it.first;
tag2 = it.second;
i1 = atom->map(tag1);
i2 = atom->map(tag2);
for (int ilist = 0; ilist < neighbor->nlist; ilist++) {
list = neighbor->lists[ilist];
// Loop through atoms of owned atoms i j and update SB bits
if (i1 < nlocal) {
jlist = firstneigh[i1];
jnum = numneigh[i1];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
if (((j >> SBBITS) & 3) != 0) continue; // Skip bonded pairs
if (tag[j] == tag2) jlist[jj] = j ^ (1 << SBBITS); // Add 1-2 special bond bits
// Skip copied lists, will update original
if (list->copy) continue;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
for (auto const &it : new_created_pairs) {
tag1 = it.first;
tag2 = it.second;
i1 = atom->map(tag1);
i2 = atom->map(tag2);
// Loop through atoms of owned atoms i j and update SB bits
if (i1 < nlocal) {
jlist = firstneigh[i1];
jnum = numneigh[i1];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
if (((j >> SBBITS) & 3) != 0) continue; // Skip bonded pairs
if (tag[j] == tag2) jlist[jj] = j ^ (1 << SBBITS); // Add 1-2 special bond bits
}
}
}
if (i2 < nlocal) {
jlist = firstneigh[i2];
jnum = numneigh[i2];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
if (((j >> SBBITS) & 3) != 0) continue; // Skip bonded pairs
if (tag[j] == tag1) jlist[jj] = j ^ (1 << SBBITS); // Add 1-2 special bond bits
if (i2 < nlocal) {
jlist = firstneigh[i2];
jnum = numneigh[i2];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
if (((j >> SBBITS) & 3) != 0) continue; // Skip bonded pairs
if (tag[j] == tag1) jlist[jj] = j ^ (1 << SBBITS); // Add 1-2 special bond bits
}
}
}
}

View File

@ -38,8 +38,7 @@ class ComputeRattlersAtom : public Compute {
void unpack_reverse_comm(int, int *, double *) override;
private:
int pstyle, cutstyle;
int ncontacts_rattler, max_tries, nmax, invoked_peratom;
int cutstyle, ncontacts_rattler, max_tries, nmax, invoked_peratom;
int *ncontacts;
double *rattler;
class NeighList *list;

View File

@ -33,21 +33,20 @@
#include <cmath>
#include <cstring>
#include <iostream>
using namespace LAMMPS_NS;
static const char cite_compute_slcsa_atom_c[] =
"compute slcsa/atom command: doi:10.1088/0965-0393/21/5/055020\n\n"
"compute slcsa/atom command: doi:10.1016/j.commatsci.2023.112534\n\n"
"@Article{Lafourcade2023,\n"
" author = {P. Lafourcade and J.-B. Maillet and C. Denoual and E. Duval and A. Allera and A. "
"M. Goryaeva and M.-C. Marinica},\n"
" title = {Robust crystal structure identification at extreme conditions using a "
"density-independent spectral descriptor and supervised learning},\n"
" journal = {Computational Materials Science},\n"
" year = 2023,\n"
" volume = XX,\n"
" pages = {XXXXXX}\n"
" year = 2023,\n"
" volume = 230,\n"
" pages = 112534\n"
"}\n\n";
/* ---------------------------------------------------------------------- */
@ -79,6 +78,8 @@ ComputeSLCSAAtom::ComputeSLCSAAtom(LAMMPS *lmp, int narg, char **arg) :
// # LR bias vector
// vector with 1 row x nclasses cols
if (lmp->citeme) lmp->citeme->add(cite_compute_slcsa_atom_c);
if (narg != 11) utils::missing_cmd_args(FLERR, "compute slcsa/atom", error);
int twojmax = utils::inumeric(FLERR, arg[3], false, lmp);

View File

@ -53,14 +53,12 @@ class ComputeSLCSAAtom : public Compute {
value_t descriptorval;
int nmax;
int ncols;
int nevery;
int ncomps;
int nclasses;
const char *database_mean_descriptor_file;
const char *lda_scalings_file;
const char *lr_decision_file;
const char *lr_bias_file;
const char *covmat_file;
const char *maha_file;
class NeighList *list;

View File

@ -202,7 +202,7 @@ void FixNonaffineDisplacement::init()
// need an occasional half neighbor list
if (cut_style == RADIUS) {
auto req = neighbor->add_request(this, NeighConst::REQ_SIZE | NeighConst::REQ_OCCASIONAL);
neighbor->add_request(this, NeighConst::REQ_SIZE | NeighConst::REQ_OCCASIONAL);
} else {
auto req = neighbor->add_request(this, NeighConst::REQ_OCCASIONAL);
if (cut_style == CUSTOM) {
@ -233,7 +233,7 @@ void FixNonaffineDisplacement::init_list(int /*id*/, NeighList *ptr)
/* ---------------------------------------------------------------------- */
void FixNonaffineDisplacement::setup(int vflag)
void FixNonaffineDisplacement::setup(int /*vflag*/)
{
post_force(0); // Save state if needed before starting the 1st timestep
}
@ -285,7 +285,6 @@ void FixNonaffineDisplacement::restart(char *buf)
void FixNonaffineDisplacement::integrate_velocity()
{
int i,n;
dtv = update->dt;
double **v = atom->v;
@ -306,7 +305,6 @@ void FixNonaffineDisplacement::integrate_velocity()
void FixNonaffineDisplacement::save_reference_state()
{
int i, n;
double **x = atom->x;
int *mask = atom->mask;
@ -354,15 +352,14 @@ void FixNonaffineDisplacement::calculate_D2Min()
int i, j, k, l, ii, jj, inum, jnum, itype, jtype;
double evol, j2, edev;
double r[3], r0[3], rsq, rsq0, radsum, temp[3];
double r[3], r0[3], rsq, radsum, temp[3];
double X_tmp[3][3], Y_tmp[3][3], F_tmp[3][3], E[3][3];
double Y_inv[3][3] = {0.0}; // Zero for 2d since not all entries used
double Y_inv[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}; // Zero for 2d since not all entries used
int *ilist, *jlist, *numneigh, **firstneigh;
double **x = atom->x;
double **x0 = array_atom;
double *radius = atom->radius;
tagint *tag = atom->tag;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;

View File

@ -120,7 +120,7 @@ void AngleCosinePeriodic::compute(int eflag, int vflag)
tn = 1.0;
tn_1 = 1.0;
tn_2 = 0.0;
un = 1.0;
un = (m==1) ? 2.0 : 1.0;
un_1 = 2.0;
un_2 = 0.0;

View File

@ -338,7 +338,7 @@ void DihedralQuadratic::born_matrix(int nd, int i1, int i2, int i3, int i4,
double sb1,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s12,c;
double s1,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
double cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
int **dihedrallist = neighbor->dihedrallist;
double **x = atom->x;
@ -405,8 +405,6 @@ void DihedralQuadratic::born_matrix(int nd, int i1, int i2, int i3, int i4,
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;

View File

@ -70,6 +70,8 @@
#include "modify.h"
#include "update.h"
#include "fmt/ranges.h"
#include <cstring>
#include <vector>

View File

@ -68,6 +68,8 @@
#include "pair_kim.h"
#include "variable.h"
#include "fmt/ranges.h"
#include <cstdlib>
#include <cstring>
#include <vector>

View File

@ -931,6 +931,7 @@ void CommKokkos::exchange_device()
if (nextrarecv) {
kkbase->unpack_exchange_kokkos(
k_buf_recv,k_indices,nrecv/data_size,
nrecv1/data_size,nextrarecv1,
ExecutionSpaceFromDevice<DeviceType>::space);
DeviceType().fence();
}

View File

@ -453,8 +453,12 @@ KOKKOS_INLINE_FUNCTION
void FixNeighHistoryKokkos<DeviceType>::operator()(TagFixNeighHistoryUnpackExchange, const int &i) const
{
int index = d_indices(i);
if (index > -1) {
int m = (int) d_ubuf(d_buf(i)).i;
if (i >= nrecv1)
m = nextrarecv1 + (int) d_ubuf(d_buf(nextrarecv1 + i - nrecv1)).i;
int n = (int) d_ubuf(d_buf(m++)).i;
d_npartner(index) = n;
for (int p = 0; p < n; p++) {
@ -471,6 +475,7 @@ void FixNeighHistoryKokkos<DeviceType>::operator()(TagFixNeighHistoryUnpackExcha
template<class DeviceType>
void FixNeighHistoryKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
int nrecv1, int nextrarecv1,
ExecutionSpace /*space*/)
{
d_buf = typename AT::t_xfloat_1d_um(
@ -478,6 +483,9 @@ void FixNeighHistoryKokkos<DeviceType>::unpack_exchange_kokkos(
k_buf.extent(0)*k_buf.extent(1));
d_indices = k_indices.view<DeviceType>();
this->nrecv1 = nrecv1;
this->nextrarecv1 = nextrarecv1;
d_npartner = k_npartner.template view<DeviceType>();
d_partner = k_partner.template view<DeviceType>();
d_valuepartner = k_valuepartner.template view<DeviceType>();

View File

@ -72,12 +72,14 @@ class FixNeighHistoryKokkos : public FixNeighHistory, public KokkosBase {
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
int nrecv1,int nrecv1extra,
ExecutionSpace space) override;
typename DAT::tdual_int_2d k_firstflag;
typename DAT::tdual_float_2d k_firstvalue;
private:
int nrecv1,nextrarecv1;
int nlocal,nsend,beyond_contact;
typename AT::t_tagint_1d tag;

View File

@ -1416,6 +1416,7 @@ KOKKOS_INLINE_FUNCTION
void FixQEqReaxFFKokkos<DeviceType>::operator()(TagQEqUnpackExchange, const int &i) const
{
int index = d_indices(i);
if (index > -1) {
for (int m = 0; m < nprev; m++) d_s_hist(index,m) = d_buf(i*nprev*2 + m);
for (int m = 0; m < nprev; m++) d_t_hist(index,m) = d_buf(i*nprev*2 + nprev+m);
@ -1427,6 +1428,7 @@ void FixQEqReaxFFKokkos<DeviceType>::operator()(TagQEqUnpackExchange, const int
template <class DeviceType>
void FixQEqReaxFFKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
int /*nrecv1*/, int /*nextrarecv1*/,
ExecutionSpace /*space*/)
{
k_buf.sync<DeviceType>();

View File

@ -143,6 +143,7 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase {
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
int nrecv1,int nextrarecv1,
ExecutionSpace space) override;
struct params_qeq{

View File

@ -1581,8 +1581,8 @@ void FixShakeKokkos<DeviceType>::pack_exchange_item(const int &mysend, int &offs
else offset++;
} else {
d_buf[mysend] = nsend + offset;
int m = nsend + offset;
d_buf[mysend] = m;
d_buf[m++] = flag;
if (flag == 1) {
d_buf[m++] = d_shake_atom(i,0);
@ -1703,6 +1703,8 @@ void FixShakeKokkos<DeviceType>::operator()(TagFixShakeUnpackExchange, const int
if (index > -1) {
int m = d_buf[i];
if (i >= nrecv1)
m = nextrarecv1 + d_buf[nextrarecv1 + i - nrecv1];
int flag = d_shake_flag[index] = static_cast<int> (d_buf[m++]);
if (flag == 1) {
@ -1739,6 +1741,7 @@ void FixShakeKokkos<DeviceType>::operator()(TagFixShakeUnpackExchange, const int
template <class DeviceType>
void FixShakeKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
int nrecv1, int nextrarecv1,
ExecutionSpace /*space*/)
{
k_buf.sync<DeviceType>();
@ -1749,6 +1752,9 @@ void FixShakeKokkos<DeviceType>::unpack_exchange_kokkos(
k_buf.extent(0)*k_buf.extent(1));
d_indices = k_indices.view<DeviceType>();
this->nrecv1 = nrecv1;
this->nextrarecv1 = nextrarecv1;
k_shake_flag.template sync<DeviceType>();
k_shake_atom.template sync<DeviceType>();
k_shake_type.template sync<DeviceType>();

View File

@ -110,9 +110,12 @@ class FixShakeKokkos : public FixShake, public KokkosBase {
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
int nrecv1,int nrecv1extra,
ExecutionSpace space) override;
protected:
int nrecv1,nextrarecv1;
typename AT::t_x_array d_x;
typename AT::t_v_array d_v;
typename AT::t_f_array d_f;
@ -257,4 +260,3 @@ struct FixShakeKokkosPackExchangeFunctor {
#endif
#endif

View File

@ -188,8 +188,8 @@ void FixSpringSelfKokkos<DeviceType>::pack_exchange_item(const int &mysend, int
{
const int i = d_exchange_sendlist(mysend);
d_buf[mysend] = nsend + offset;
int m = nsend + offset;
d_buf[mysend] = m;
d_buf[m++] = d_xoriginal(i,0);
d_buf[m++] = d_xoriginal(i,1);
d_buf[m++] = d_xoriginal(i,2);
@ -258,6 +258,8 @@ void FixSpringSelfKokkos<DeviceType>::operator()(TagFixSpringSelfUnpackExchange,
if (index > -1) {
int m = d_buf[i];
if (i >= nrecv1)
m = nextrarecv1 + d_buf[nextrarecv1 + i - nrecv1];
d_xoriginal(index,0) = static_cast<tagint> (d_buf[m++]);
d_xoriginal(index,1) = static_cast<tagint> (d_buf[m++]);
@ -270,6 +272,7 @@ void FixSpringSelfKokkos<DeviceType>::operator()(TagFixSpringSelfUnpackExchange,
template <class DeviceType>
void FixSpringSelfKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
int nrecv1, int nextrarecv1,
ExecutionSpace /*space*/)
{
k_buf.sync<DeviceType>();
@ -280,6 +283,9 @@ void FixSpringSelfKokkos<DeviceType>::unpack_exchange_kokkos(
k_buf.extent(0)*k_buf.extent(1));
d_indices = k_indices.view<DeviceType>();
this->nrecv1 = nrecv1;
this->nextrarecv1 = nextrarecv1;
k_xoriginal.template sync<DeviceType>();
copymode = 1;

View File

@ -58,6 +58,7 @@ class FixSpringSelfKokkos : public FixSpringSelf, public KokkosBase {
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
int nrecv1,int nrecv1extra,
ExecutionSpace space) override;
@ -65,6 +66,8 @@ class FixSpringSelfKokkos : public FixSpringSelf, public KokkosBase {
int unpack_exchange(int, double *) override;
protected:
int nrecv1,nextrarecv1;
DAT::tdual_x_array k_xoriginal;
typename AT::t_x_array d_xoriginal;

View File

@ -419,6 +419,7 @@ void FixWallGranKokkos<DeviceType>::operator()(TagFixWallGranUnpackExchange, con
template<class DeviceType>
void FixWallGranKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
int /*nrecv1*/, int /*nextrarecv1*/,
ExecutionSpace /*space*/)
{
d_buf = typename ArrayTypes<DeviceType>::t_xfloat_1d_um(
@ -430,7 +431,6 @@ void FixWallGranKokkos<DeviceType>::unpack_exchange_kokkos(
copymode = 1;
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType,TagFixWallGranUnpackExchange>(0,nrecv),*this);
copymode = 0;

View File

@ -62,12 +62,13 @@ class FixWallGranKokkos : public FixWallGranOld, public KokkosBase {
void operator()(TagFixWallGranUnpackExchange, const int&) const;
int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf,
DAT::tdual_int_1d k_sendlist,
DAT::tdual_int_1d k_copylist,
ExecutionSpace space) override;
DAT::tdual_int_1d k_sendlist,
DAT::tdual_int_1d k_copylist,
ExecutionSpace space) override;
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
int nrecv1,int nrecv1extra,
ExecutionSpace space) override;
private:
@ -91,6 +92,7 @@ class FixWallGranKokkos : public FixWallGranOld, public KokkosBase {
typename AT::t_int_1d d_copylist;
typename AT::t_int_1d d_indices;
};
}
#endif

View File

@ -47,6 +47,7 @@ class KokkosBase {
ExecutionSpace /*space*/) { return 0; }
virtual void unpack_exchange_kokkos(DAT::tdual_xfloat_2d & /*k_buf*/,
DAT::tdual_int_1d & /*indices*/, int /*nrecv*/,
int /*nrecv1*/, int /*nextrarecv1*/,
ExecutionSpace /*space*/) {}
// Region

View File

@ -44,6 +44,7 @@ AngleLepton::AngleLepton(LAMMPS *_lmp) :
{
writedata = 1;
reinitflag = 0;
auto_offset = 1;
}
/* ---------------------------------------------------------------------- */
@ -90,10 +91,21 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void AngleLepton::eval()
{
std::vector<Lepton::CompiledExpression> angleforce;
std::vector<Lepton::CompiledExpression> anglepot;
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
angleforce.emplace_back(parsed.differentiate("theta").createCompiledExpression());
if (EFLAG) anglepot.emplace_back(parsed.createCompiledExpression());
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
angleforce.emplace_back(parsed.differentiate("theta").createCompiledExpression());
has_ref.push_back(true);
try {
angleforce.back().getVariableReference("theta");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) anglepot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
error->all(FLERR, e.what());
}
const double *const *const x = atom->x;
@ -142,8 +154,7 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void AngleLepton::eval()
const double dtheta = acos(c) - theta0[type];
const int idx = type2expression[type];
angleforce[idx].getVariableReference("theta") = dtheta;
if (has_ref[idx]) angleforce[idx].getVariableReference("theta") = dtheta;
const double a = -angleforce[idx].evaluate() * s;
const double a11 = a * c / rsq1;
const double a12 = -a / (r1 * r2);
@ -179,7 +190,11 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void AngleLepton::eval()
double eangle = 0.0;
if (EFLAG) {
anglepot[idx].getVariableReference("theta") = dtheta;
try {
anglepot[idx].getVariableReference("theta") = dtheta;
} catch (Lepton::Exception &) {
; // ignore -> constant force
}
eangle = anglepot[idx].evaluate() - offset[type];
}
if (EVFLAG)
@ -202,6 +217,24 @@ void AngleLepton::allocate()
for (int i = 1; i < np1; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void AngleLepton::settings(int narg, char **arg)
{
auto_offset = 1;
if (narg > 0) {
if (strcmp(arg[0],"auto_offset") == 0) {
auto_offset = 1;
} else if (strcmp(arg[0],"no_offset") == 0) {
auto_offset = 0;
} else {
error->all(FLERR, "Unknown angle style lepton setting {}", arg[0]);
}
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
@ -224,9 +257,20 @@ void AngleLepton::coeff(int narg, char **arg)
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(exp_one, lmp));
auto anglepot = parsed.createCompiledExpression();
auto angleforce = parsed.differentiate("theta").createCompiledExpression();
anglepot.getVariableReference("theta") = 0.0;
angleforce.getVariableReference("theta") = 0.0;
offset_one = anglepot.evaluate();
try {
anglepot.getVariableReference("theta") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Lepton potential expression {} does not depend on 'theta'", exp_one);
}
try {
angleforce.getVariableReference("theta") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Force from Lepton expression {} does not depend on 'theta'",
exp_one);
}
if (auto_offset) offset_one = anglepot.evaluate();
angleforce.evaluate();
} catch (std::exception &e) {
error->all(FLERR, e.what());
@ -284,6 +328,7 @@ void AngleLepton::write_restart(FILE *fp)
fwrite(&n, sizeof(int), 1, fp);
fwrite(exp.c_str(), sizeof(char), n, fp);
}
fwrite(&auto_offset, sizeof(int), 1, fp);
}
/* ----------------------------------------------------------------------
@ -323,6 +368,9 @@ void AngleLepton::read_restart(FILE *fp)
expressions.emplace_back(buf);
}
if (comm->me == 0) utils::sfread(FLERR, &auto_offset, sizeof(int), 1, fp, nullptr, error);
MPI_Bcast(&auto_offset, 1, MPI_INT, 0, world);
delete[] buf;
}
@ -363,7 +411,11 @@ double AngleLepton::single(int type, int i1, int i2, int i3)
const auto &expr = expressions[type2expression[type]];
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
auto anglepot = parsed.createCompiledExpression();
anglepot.getVariableReference("theta") = dtheta;
try {
anglepot.getVariableReference("theta") = dtheta;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
return anglepot.evaluate() - offset[type];
}

View File

@ -29,6 +29,7 @@ class AngleLepton : public Angle {
AngleLepton(class LAMMPS *);
~AngleLepton() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
double equilibrium_angle(int) override;
void write_restart(FILE *) override;
@ -42,6 +43,7 @@ class AngleLepton : public Angle {
double *theta0;
int *type2expression;
double *offset;
int auto_offset;
virtual void allocate();

View File

@ -37,6 +37,7 @@ BondLepton::BondLepton(LAMMPS *_lmp) :
{
writedata = 1;
reinitflag = 0;
auto_offset = 1;
}
/* ---------------------------------------------------------------------- */
@ -82,10 +83,17 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void BondLepton::eval()
{
std::vector<Lepton::CompiledExpression> bondforce;
std::vector<Lepton::CompiledExpression> bondpot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
bondforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back(true);
try {
bondforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) bondpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -116,7 +124,7 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void BondLepton::eval()
double fbond = 0.0;
if (r > 0.0) {
bondforce[idx].getVariableReference("r") = dr;
if (has_ref[idx]) bondforce[idx].getVariableReference("r") = dr;
fbond = -bondforce[idx].evaluate() / r;
}
@ -136,7 +144,11 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void BondLepton::eval()
double ebond = 0.0;
if (EFLAG) {
bondpot[idx].getVariableReference("r") = dr;
try {
bondpot[idx].getVariableReference("r") = dr;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
ebond = bondpot[idx].evaluate() - offset[type];
}
if (EVFLAG) ev_tally(i1, i2, nlocal, NEWTON_BOND, ebond, fbond, delx, dely, delz);
@ -157,6 +169,24 @@ void BondLepton::allocate()
for (int i = 1; i < np1; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void BondLepton::settings(int narg, char **arg)
{
auto_offset = 1;
if (narg > 0) {
if (strcmp(arg[0],"auto_offset") == 0) {
auto_offset = 1;
} else if (strcmp(arg[0],"no_offset") == 0) {
auto_offset = 0;
} else {
error->all(FLERR, "Unknown bond style lepton setting {}", arg[0]);
}
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
@ -179,9 +209,19 @@ void BondLepton::coeff(int narg, char **arg)
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(exp_one, lmp));
auto bondpot = parsed.createCompiledExpression();
auto bondforce = parsed.differentiate("r").createCompiledExpression();
bondpot.getVariableReference("r") = 0.0;
bondforce.getVariableReference("r") = 0.0;
offset_one = bondpot.evaluate();
try {
bondpot.getVariableReference("r") = 0.0;
} catch (Lepton::Exception &e) {
if (comm->me == 0)
error->warning(FLERR, "Lepton potential expression {} does not depend on 'r'", exp_one);
}
try {
bondforce.getVariableReference("r") = 0.0;
} catch (Lepton::Exception &e) {
if (comm->me == 0)
error->warning(FLERR, "Force from Lepton expression {} does not depend on 'r'", exp_one);
}
if (auto_offset) offset_one = bondpot.evaluate();
bondforce.evaluate();
} catch (std::exception &e) {
error->all(FLERR, e.what());
@ -239,6 +279,7 @@ void BondLepton::write_restart(FILE *fp)
fwrite(&n, sizeof(int), 1, fp);
fwrite(exp.c_str(), sizeof(char), n, fp);
}
fwrite(&auto_offset, sizeof(int), 1, fp);
}
/* ----------------------------------------------------------------------
@ -278,6 +319,9 @@ void BondLepton::read_restart(FILE *fp)
expressions.emplace_back(buf);
}
if (comm->me == 0) utils::sfread(FLERR, &auto_offset, sizeof(int), 1, fp, nullptr, error);
MPI_Bcast(&auto_offset, 1, MPI_INT, 0, world);
delete[] buf;
}
@ -302,8 +346,12 @@ double BondLepton::single(int type, double rsq, int /*i*/, int /*j*/, double &ff
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
auto bondpot = parsed.createCompiledExpression();
auto bondforce = parsed.differentiate("r").createCompiledExpression();
bondforce.getVariableReference("r") = dr;
bondpot.getVariableReference("r") = dr;
try {
bondpot.getVariableReference("r") = dr;
bondforce.getVariableReference("r") = dr;
} catch (Lepton::Exception &) {
; // ignore -> constant potential or force
}
// force and energy

View File

@ -29,6 +29,7 @@ class BondLepton : public Bond {
BondLepton(class LAMMPS *);
~BondLepton() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
double equilibrium_distance(int) override;
void write_restart(FILE *) override;
@ -42,6 +43,7 @@ class BondLepton : public Bond {
double *r0;
int *type2expression;
double *offset;
int auto_offset;
virtual void allocate();

View File

@ -92,10 +92,17 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void DihedralLepton::eval()
{
std::vector<Lepton::CompiledExpression> dihedralforce;
std::vector<Lepton::CompiledExpression> dihedralpot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
dihedralforce.emplace_back(parsed.differentiate("phi").createCompiledExpression());
has_ref.push_back(true);
try {
dihedralforce.back().getVariableReference("phi");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) dihedralpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -278,7 +285,7 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void DihedralLepton::eval()
}
const int idx = type2expression[type];
dihedralforce[idx].getVariableReference("phi") = phi;
if (has_ref[idx]) dihedralforce[idx].getVariableReference("phi") = phi;
double m_du_dphi = -dihedralforce[idx].evaluate();
// ----- Step 4: Calculate the force direction in real space -----
@ -322,7 +329,11 @@ template <int EVFLAG, int EFLAG, int NEWTON_BOND> void DihedralLepton::eval()
double edihedral = 0.0;
if (EFLAG) {
dihedralpot[idx].getVariableReference("phi") = phi;
try {
dihedralpot[idx].getVariableReference("phi") = phi;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
edihedral = dihedralpot[idx].evaluate();
}
if (EVFLAG)
@ -362,8 +373,18 @@ void DihedralLepton::coeff(int narg, char **arg)
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(exp_one, lmp));
auto dihedralpot = parsed.createCompiledExpression();
auto dihedralforce = parsed.differentiate("phi").createCompiledExpression();
dihedralpot.getVariableReference("phi") = 0.0;
dihedralforce.getVariableReference("phi") = 0.0;
try {
dihedralpot.getVariableReference("phi") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Lepton potential expression {} does not depend on 'phi'", exp_one);
}
try {
dihedralforce.getVariableReference("phi") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Force from Lepton expression {} does not depend on 'phi'", exp_one);
}
dihedralforce.evaluate();
} catch (std::exception &e) {
error->all(FLERR, e.what());

View File

@ -13,6 +13,7 @@
#include "fix_wall_lepton.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "Lepton.h"
@ -41,8 +42,18 @@ void FixWallLepton::post_constructor()
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(exp_one, lmp));
auto wallpot = parsed.createCompiledExpression();
auto wallforce = parsed.differentiate("r").createCompiledExpression();
wallpot.getVariableReference("r") = 0.0;
wallforce.getVariableReference("r") = 0.0;
try {
wallpot.getVariableReference("r") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Lepton potential expression {} does not depend on 'r'", exp_one);
}
try {
wallforce.getVariableReference("r") = 0.0;
} catch (Lepton::Exception &) {
if (comm->me == 0)
error->warning(FLERR, "Force from Lepton expression {} does not depend on 'r'", exp_one);
}
wallpot.evaluate();
wallforce.evaluate();
} catch (std::exception &e) {

View File

@ -27,6 +27,7 @@
#include "Lepton.h"
#include "lepton_utils.h"
#include <array>
#include <cmath>
#include <map>
@ -105,11 +106,17 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLepton::eval()
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
pairforce.back().getVariableReference("r");
has_ref.push_back(true);
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -142,8 +149,7 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLepton::eval()
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
double &r_for = pairforce[idx].getVariableReference("r");
r_for = r;
if (has_ref[idx]) pairforce[idx].getVariableReference("r") = r;
const double fpair = -pairforce[idx].evaluate() / r * factor_lj;
fxtmp += delx * fpair;
@ -157,7 +163,11 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLepton::eval()
double evdwl = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
evdwl = pairpot[idx].evaluate() - offset[itype][jtype];
evdwl *= factor_lj;
}
@ -229,8 +239,12 @@ void PairLepton::coeff(int narg, char **arg)
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(exp_one, lmp), functions);
auto pairforce = parsed.differentiate("r").createCompiledExpression();
auto pairpot = parsed.createCompiledExpression();
pairpot.getVariableReference("r") = 1.0;
pairforce.getVariableReference("r") = 1.0;
try {
pairpot.getVariableReference("r") = 1.0;
pairforce.getVariableReference("r") = 1.0;
} catch (Lepton::Exception &) {
; // ignore -> constant potential or force
}
pairpot.evaluate();
pairforce.evaluate();
} catch (std::exception &e) {
@ -270,7 +284,11 @@ double PairLepton::init_one(int i, int j)
try {
auto expr = LeptonUtils::substitute(expressions[type2expression[i][j]], lmp);
auto pairpot = Lepton::Parser::parse(expr, functions).createCompiledExpression();
pairpot.getVariableReference("r") = cut[i][j];
try {
pairpot.getVariableReference("r") = cut[i][j];
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
offset[i][j] = pairpot.evaluate();
} catch (std::exception &) {
}
@ -429,9 +447,12 @@ double PairLepton::single(int /* i */, int /* j */, int itype, int jtype, double
auto pairforce = parsed.differentiate("r").createCompiledExpression();
const double r = sqrt(rsq);
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
try {
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential or force
}
fforce = -pairforce.evaluate() / r * factor_lj;
return (pairpot.evaluate() - offset[itype][jtype]) * factor_lj;
}

View File

@ -28,6 +28,8 @@
#include "Lepton.h"
#include "lepton_utils.h"
#include <array>
#include <cmath>
using namespace LAMMPS_NS;
@ -79,25 +81,30 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonCoul::eval()
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<std::pair<bool, bool>> have_q;
std::vector<std::array<bool, 3>> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back({true, true, true});
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back()[0] = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
pairforce.back().getVariableReference("r");
have_q.emplace_back(true, true);
// check if there are references to charges
try {
pairforce.back().getVariableReference("qi");
} catch (std::exception &) {
have_q.back().first = false;
} catch (Lepton::Exception &) {
has_ref.back()[1] = false;
}
try {
pairforce.back().getVariableReference("qj");
} catch (std::exception &) {
have_q.back().second = false;
} catch (Lepton::Exception &) {
has_ref.back()[2] = false;
}
}
} catch (std::exception &e) {
@ -130,9 +137,9 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonCoul::eval()
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
pairforce[idx].getVariableReference("r") = r;
if (have_q[idx].first) pairforce[idx].getVariableReference("qi") = q2e * q[i];
if (have_q[idx].second) pairforce[idx].getVariableReference("qj") = q2e * q[j];
if (has_ref[idx][0]) pairforce[idx].getVariableReference("r") = r;
if (has_ref[idx][1]) pairforce[idx].getVariableReference("qi") = q2e * q[i];
if (has_ref[idx][2]) pairforce[idx].getVariableReference("qj") = q2e * q[j];
const double fpair = -pairforce[idx].evaluate() / r * factor_coul;
fxtmp += delx * fpair;
@ -146,9 +153,14 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonCoul::eval()
double ecoul = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
if (have_q[idx].first) pairpot[idx].getVariableReference("qi") = q2e * q[i];
if (have_q[idx].second) pairpot[idx].getVariableReference("qj") = q2e * q[j];
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
if (has_ref[idx][1]) pairpot[idx].getVariableReference("qi") = q2e * q[i];
if (has_ref[idx][2]) pairpot[idx].getVariableReference("qj") = q2e * q[j];
ecoul = pairpot[idx].evaluate();
ecoul *= factor_coul;
}
@ -249,18 +261,22 @@ double PairLeptonCoul::single(int i, int j, int itype, int jtype, double rsq, do
const double r = sqrt(rsq);
const double q2e = sqrt(force->qqrd2e);
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
try {
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential or force
}
try {
pairpot.getVariableReference("qi") = q2e * atom->q[i];
pairforce.getVariableReference("qi") = q2e * atom->q[i];
} catch (std::exception &) {
} catch (Lepton::Exception &) {
/* ignore */
}
try {
pairpot.getVariableReference("qj") = q2e * atom->q[j];
pairforce.getVariableReference("qj") = q2e * atom->q[j];
} catch (std::exception &) {
} catch (Lepton::Exception &) {
/* ignore */
}

View File

@ -28,6 +28,7 @@
#include "Lepton.h"
#include "lepton_utils.h"
#include <array>
#include <cmath>
using namespace LAMMPS_NS;
@ -77,25 +78,30 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonSphere::eval()
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<std::pair<bool, bool>> have_rad;
std::vector<std::array<bool, 3>> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back({true, true, true});
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back()[0] = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
pairforce.back().getVariableReference("r");
have_rad.emplace_back(true, true);
// check if there are references to charges
// check if there are references to radii
try {
pairforce.back().getVariableReference("radi");
} catch (std::exception &) {
have_rad.back().first = false;
} catch (Lepton::Exception &) {
has_ref.back()[1] = false;
}
try {
pairforce.back().getVariableReference("radj");
} catch (std::exception &) {
have_rad.back().second = false;
} catch (Lepton::Exception &) {
has_ref.back()[2] = false;
}
}
} catch (std::exception &e) {
@ -128,9 +134,9 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonSphere::eval()
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
pairforce[idx].getVariableReference("r") = r;
if (have_rad[idx].first) pairforce[idx].getVariableReference("radi") = radius[i];
if (have_rad[idx].second) pairforce[idx].getVariableReference("radj") = radius[j];
if (has_ref[idx][0]) pairforce[idx].getVariableReference("r") = r;
if (has_ref[idx][1]) pairforce[idx].getVariableReference("radi") = radius[i];
if (has_ref[idx][2]) pairforce[idx].getVariableReference("radj") = radius[j];
const double fpair = -pairforce[idx].evaluate() / r * factor_lj;
fxtmp += delx * fpair;
@ -144,9 +150,14 @@ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void PairLeptonSphere::eval()
double evdwl = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
if (have_rad[idx].first) pairpot[idx].getVariableReference("radi") = radius[i];
if (have_rad[idx].second) pairpot[idx].getVariableReference("radj") = radius[j];
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
if (has_ref[idx][1]) pairpot[idx].getVariableReference("radi") = radius[i];
if (has_ref[idx][2]) pairpot[idx].getVariableReference("radj") = radius[j];
evdwl = pairpot[idx].evaluate();
evdwl *= factor_lj;
}
@ -211,19 +222,23 @@ double PairLeptonSphere::single(int i, int j, int itype, int jtype, double rsq,
auto pairforce = parsed.differentiate("r").createCompiledExpression();
const double r = sqrt(rsq);
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
try {
pairpot.getVariableReference("r") = r;
pairforce.getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential or force
}
try {
pairpot.getVariableReference("radi") = atom->radius[i];
pairforce.getVariableReference("radi") = atom->radius[i];
} catch (std::exception &) {
/* ignore */
} catch (Lepton::Exception &) {
; // ignore
}
try {
pairpot.getVariableReference("radj") = atom->radius[j];
pairforce.getVariableReference("radj") = atom->radius[j];
} catch (std::exception &) {
/* ignore */
} catch (Lepton::Exception &) {
; // ignore
}
fforce = -pairforce.evaluate() / r * factor_lj;

View File

@ -1,60 +0,0 @@
# bgq = IBM Blue Gene/Q, multiple compiler options, native MPI, ALCF FFTW2
SHELL = /bin/bash
.SUFFIXES: .cpp .u
# ---------------------------------------------------------------------
# build rules and dependencies
# do not edit this section
# select which compiler by editing Makefile.bgq.details
include ../MAKE/MACHINES/bgq.make.details
include Makefile.package.settings
include Makefile.package
EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC)
EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH)
EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) $(DYN_LIB)
EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS)
EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS)
# Path to src files
vpath %.cpp ..
vpath %.h ..
# Link target
$(EXE): main.o $(LMPLIB) $(EXTRA_LINK_DEPENDS)
$(LINK) $(LINKFLAGS) main.o $(EXTRA_PATH) $(LMPLINK) $(EXTRA_LIB) $(LIB) -o $@
$(SIZE) $@
# Library targets
$(ARLIB): $(OBJ) $(EXTRA_LINK_DEPENDS)
@rm -f ../$(ARLIB)
$(ARCHIVE) $(ARFLAGS) ../$(ARLIB) $(OBJ)
@rm -f $(ARLIB)
@ln -s ../$(ARLIB) $(ARLIB)
$(SHLIB): $(OBJ) $(EXTRA_LINK_DEPENDS)
$(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o ../$(SHLIB) \
$(OBJ) $(EXTRA_LIB) $(LIB)
@rm -f $(SHLIB)
@ln -s ../$(SHLIB) $(SHLIB)
# Compilation rules
%.o:%.cpp
$(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $<
# Individual dependencies
depend : fastdep.exe $(SRC)
@./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1
fastdep.exe: ../DEPEND/fastdep.c
cc -O -o $@ $<
sinclude .depend

View File

@ -1,125 +0,0 @@
# xe6 = Cray XE6, Cray CC, native MPI, FFTW
SHELL = /bin/sh
.SUFFIXES: .cpp .d
# ---------------------------------------------------------------------
# compiler/linker settings
# specify flags and libraries needed for your compiler
CC = CC
CCFLAGS = -fastsse
SHFLAGS = -fPIC
DEPFLAGS = -M
LINK = CC
LINKFLAGS = -O
LIB = -lstdc++
SIZE = size
ARCHIVE = ar
ARFLAGS = -rc
SHLIBFLAGS = -shared
# ---------------------------------------------------------------------
# LAMMPS-specific settings, all OPTIONAL
# specify settings for LAMMPS features you will use
# if you change any -D setting, do full re-compile after "make clean"
# LAMMPS ifdef settings
# see possible settings in Section 3.5 of the manual
LMP_INC = -DLAMMPS_GZIP
# MPI library
# see discussion in Section 3.4 of the manual
# MPI wrapper compiler/linker can provide this info
# can point to dummy MPI library in src/STUBS as in Makefile.serial
# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts
# INC = path for mpi.h, MPI compiler settings
# PATH = path for MPI library
# LIB = name of MPI library
MPI_INC = -DMPICH_SKIP_MPICXX
MPI_PATH =
MPI_LIB =
# FFT library
# see discussion in Section 3.5.2 of manual
# can be left blank to use provided KISS FFT library
# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings
# PATH = path for FFT library
# LIB = name of FFT library
FFT_INC =
FFT_PATH =
FFT_LIB =
# JPEG and/or PNG library
# see discussion in Section 3.5.4 of manual
# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC
# INC = path(s) for jpeglib.h and/or png.h
# PATH = path(s) for JPEG library and/or PNG library
# LIB = name(s) of JPEG library and/or PNG library
JPG_INC =
JPG_PATH =
JPG_LIB =
# library for loading shared objects (defaults to -ldl, should be empty on Windows)
# uncomment to change the default
# override DYN_LIB =
# ---------------------------------------------------------------------
# build rules and dependencies
# do not edit this section
include Makefile.package.settings
include Makefile.package
EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC)
EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH)
EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) $(DYN_LIB)
EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS)
EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS)
# Path to src files
vpath %.cpp ..
vpath %.h ..
# Link target
$(EXE): main.o $(LMPLIB) $(EXTRA_LINK_DEPENDS)
$(LINK) $(LINKFLAGS) main.o $(EXTRA_PATH) $(LMPLINK) $(EXTRA_LIB) $(LIB) -o $@
$(SIZE) $@
# Library targets
$(ARLIB): $(OBJ) $(EXTRA_LINK_DEPENDS)
@rm -f ../$(ARLIB)
$(ARCHIVE) $(ARFLAGS) ../$(ARLIB) $(OBJ)
@rm -f $(ARLIB)
@ln -s ../$(ARLIB) $(ARLIB)
$(SHLIB): $(OBJ) $(EXTRA_LINK_DEPENDS)
$(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o ../$(SHLIB) \
$(OBJ) $(EXTRA_LIB) $(LIB)
@rm -f $(SHLIB)
@ln -s ../$(SHLIB) $(SHLIB)
# Compilation rules
%.o:%.cpp
$(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $<
# Individual dependencies
depend : fastdep.exe $(SRC)
@./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1
fastdep.exe: ../DEPEND/fastdep.c
cc -O -o $@ $<
sinclude .depend

View File

@ -1,125 +0,0 @@
# multiple compiler options for BGQ
# ---------------------------------------------------------------------
# compiler/linker settings
# specify flags and libraries needed for your compiler
# uncomment one and only one of the following three lines
# to choose a compiler toolchain
#COMPILER = GCC
#COMPILER = LLVM
COMPILER = XLC
ifeq ($(COMPILER),XLC)
CC = /bgsys/drivers/ppcfloor/comm/xl.ndebug/bin/mpixlcxx_r
CCFLAGS = -O3 -qarch=qp -qtune=qp -qsmp=omp -qsimd=auto -qhot=level=2 -qprefetch -qunroll=yes
FC = /bgsys/drivers/ppcfloor/comm/xl.ndebug/bin/mpixlf90_r
FFLAGS = -O3 -qarch=qp -qtune=qp -qsimd=auto -qhot=level=2 -qprefetch -qunroll=yes -qsmp=omp -qextname -qnosave
DEPFLAGS = -M -qmakedep=gcc
endif
ifeq ($(COMPILER),GCC)
CC = /bgsys/drivers/ppcfloor/comm/gcc.legacy/bin/mpicxx
CCFLAGS = -O3 -fopenmp
FC = /bgsys/drivers/ppcfloor/comm/gcc.legacy/bin/mpif90
FFLAGS = -O3 -fopenmp
DEPFLAGS = -M
endif
ifeq ($(COMPILER),LLVM)
#CC = bgclang++
CC = /home/projects/llvm/mpi/bgclang/bin/mpiclang++
CCFLAGS = -O3 -fopenmp
DEPFLAGS = -M
FC = /bin/false
FFLAGS = LLVM does not have a Fortran front-end!
endif
LINK = $(CC)
LINKFLAGS = $(CCFLAGS)
ifeq ($(COMPILER),XLC)
MASS_LIB = ${IBM_MAIN_DIR}/xlmass/bg/7.3/bglib64
XLF_LIB = ${IBM_MAIN_DIR}/xlf/bg/14.1/bglib64
XLSMP_LIB = ${IBM_MAIN_DIR}/xlsmp/bg/3.1/bglib64
LIB += -L${MASS_LIB} -L${XLF_LIB} -L${XLSMP_LIB}
LIB += -lmassv -lmass
LIB += -lxlf90_r -lxlsmp -lxlopt -lxlfmath -lxl
endif
ifeq ($(COMPILER),GCC)
# libm is definitely slower than libmass...
LIB += -lm -lgfortran
endif
ifeq ($(COMPILER),LLVM)
SLEEF_DIR = /home/projects/llvm/sleef
LIB += -L${SLEEF_DIR}/lib -lsleef
endif
SIZE = size
ARCHIVE = ar
ARFLAGS = -rc
# BGQ should not use shared libraries
SHFLAGS =
SHLIBFLAGS =
# ---------------------------------------------------------------------
# LAMMPS-specific settings, all OPTIONAL
# specify settings for LAMMPS features you will use
# if you change any -D setting, do full re-compile after "make clean"
# LAMMPS ifdef settings
# see possible settings in Section 3.5 of the manual
LMP_INC = -DLAMMPS_GZIP
# MPI library
# see discussion in Section 3.4 of the manual
# MPI wrapper compiler/linker can provide this info
# can point to dummy MPI library in src/STUBS as in Makefile.serial
# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts
# INC = path for mpi.h, MPI compiler settings
# PATH = path for MPI library
# LIB = name of MPI library
MPI_INC =
MPI_PATH =
MPI_LIB =
MPI_INC += -DMPICH_SKIP_MPICXX
MPI_LIB += #/home/jhammond/OSPRI/branches/marpn/wrap/libmpiarbrpn.a
# FFT library
# see discussion in Section 3.5.2 of manual
# can be left blank to use provided KISS FFT library
# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings
# PATH = path for FFT library
# LIB = name of FFT library
FFT_INC = -I/soft/libraries/alcf/current/xl/FFTW2/include -DFFT_FFTW2 -DFFTW_SIZE
FFT_PATH = #/soft/libraries/alcf/current/xl/FFTW2
FFT_LIB = -L/soft/libraries/alcf/current/xl/FFTW2/lib -ldfftw
# JPEG and/or PNG library
# see discussion in Section 3.5.4 of manual
# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC
# INC = path(s) for jpeglib.h and/or png.h
# PATH = path(s) for JPEG library and/or PNG library
# LIB = name(s) of JPEG library and/or PNG library
JPG_INC =
JPG_PATH =
JPG_LIB =
depend : fastdep.exe $(SRC)
@./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1
fastdep.exe: ../DEPEND/fastdep.c
cc -O -o $@ $<
sinclude .depend

View File

@ -580,58 +580,56 @@ void ComputeSNAAtom::select3(int k, int n, double *arr, int *iarr, double **arr3
}
}
double * ComputeSNAAtom::weights(double * rsq, double rcut, int ncounts)
double *ComputeSNAAtom::weights(double *rsq, double rcut, int ncounts)
{
double * w=nullptr;
double *w=nullptr;
memory->destroy(w);
memory->create(w, ncounts, "snann:gauss_weights");
double rloc=0.;
for (int i=0; i<ncounts; i++)
{
rloc = sqrt(rsq[i]);
if (rloc > rcut){
w[i]=0.;
} else {
w[i]=1.;
}
for (int i=0; i<ncounts; i++) {
rloc = sqrt(rsq[i]);
if (rloc > rcut){
w[i]=0.;
} else {
w[i]=1.;
}
}
return w;
}
double * ComputeSNAAtom::tanh_weights(double * rsq, double rcut, double delta, int ncounts)
double *ComputeSNAAtom::tanh_weights(double *rsq, double rcut, double delta, int ncounts)
{
double * w=nullptr;
double *w=nullptr;
memory->destroy(w);
memory->create(w, ncounts, "snann:gauss_weights");
double rloc=0.;
for (int i=0; i<ncounts; i++)
{
rloc = sqrt(rsq[i]);
w[i] = 0.5*(1.-tanh((rloc-rcut)/delta));
}
for (int i=0; i<ncounts; i++) {
rloc = sqrt(rsq[i]);
w[i] = 0.5*(1.-tanh((rloc-rcut)/delta));
}
return w;
}
double ComputeSNAAtom::sum_weights(double * /*rsq*/, double * w, int ncounts)
double ComputeSNAAtom::sum_weights(double * /*rsq*/, double *w, int ncounts)
{
double S=0.;
for (int i=0; i<ncounts; i++)
{
S += w[i];
}
double S=0.0;
for (int i=0; i<ncounts; i++) {
S += w[i];
}
return S;
}
double ComputeSNAAtom::get_target_rcut(double S_target, double * rsq, double rcut, int ncounts, int weightmode, double delta)
double ComputeSNAAtom::get_target_rcut(double S_target, double *rsq, double rcut, int ncounts,
int weightmode, double delta)
{
double S_sol = 0.0;
if (weightmode == 0) {
double * www = weights(rsq, rcut, ncounts);
double *www = weights(rsq, rcut, ncounts);
S_sol = sum_weights(rsq, www, ncounts);
memory->destroy(www);
} else if (weightmode == 1) {
double * www = tanh_weights(rsq, rcut, delta, ncounts);
double *www = tanh_weights(rsq, rcut, delta, ncounts);
S_sol = sum_weights(rsq, www, ncounts);
memory->destroy(www);
}
@ -639,38 +637,31 @@ double ComputeSNAAtom::get_target_rcut(double S_target, double * rsq, double rcu
return err;
}
double * ComputeSNAAtom::dichotomie(double S_target, double a, double b, double e, double * rsq, int ncounts, int weightmode, double delta)
double *ComputeSNAAtom::dichotomie(double S_target, double a, double b, double e, double *rsq,
int ncounts, int weightmode, double delta)
{
double d=b-a;
double * sol = nullptr;
double *sol = nullptr;
memory->destroy(sol);
memory->create(sol, 2, "snann:sol");
double m=0.;
double m=0.0;
int cnt=0;
do
{
m = ( a + b ) / 2.;
d = fabs( b - a );
double f_ra = get_target_rcut(S_target, rsq, a, ncounts, weightmode, delta);
double f_rm = get_target_rcut(S_target, rsq, m, ncounts, weightmode, delta);
if (f_rm == 0.)
{
sol[0]=m;
sol[1]=m;
return sol;
}
else if (f_rm*f_ra > 0.)
{
a = m;
}
else
{
b = m;
}
cnt+=1;
} while ( d > e );
do {
m = (a + b) / 2.0;
d = fabs(b - a);
double f_ra = get_target_rcut(S_target, rsq, a, ncounts, weightmode, delta);
double f_rm = get_target_rcut(S_target, rsq, m, ncounts, weightmode, delta);
if (f_rm == 0.0) {
sol[0]=m;
sol[1]=m;
return sol;
} else if (f_rm*f_ra > 0.0) {
a = m;
} else {
b = m;
}
} while (d > e);
sol[0]=a;
sol[1]=b;
return sol;

View File

@ -140,7 +140,7 @@ void AngleCosinePeriodicOMP::eval(int nfrom, int nto, ThrData * const thr)
tn = 1.0;
tn_1 = 1.0;
tn_2 = 0.0;
un = 1.0;
un = (m==1) ? 2.0 : 1.0;
un_1 = 2.0;
un_2 = 0.0;

View File

@ -91,10 +91,17 @@ void AngleLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
{
std::vector<Lepton::CompiledExpression> angleforce;
std::vector<Lepton::CompiledExpression> anglepot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp));
angleforce.emplace_back(parsed.differentiate("theta").createCompiledExpression());
has_ref.push_back(true);
try {
angleforce.back().getVariableReference("theta");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) anglepot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -146,8 +153,7 @@ void AngleLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
const double dtheta = acos(c) - theta0[type];
const int idx = type2expression[type];
angleforce[idx].getVariableReference("theta") = dtheta;
if (has_ref[idx]) angleforce[idx].getVariableReference("theta") = dtheta;
const double a = -angleforce[idx].evaluate() * s;
const double a11 = a * c / rsq1;
const double a12 = -a / (r1 * r2);
@ -183,7 +189,11 @@ void AngleLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
double eangle = 0.0;
if (EFLAG) {
anglepot[idx].getVariableReference("theta") = dtheta;
try {
anglepot[idx].getVariableReference("theta") = dtheta;
} catch (Lepton::Exception &) {
; // ignore -> constant force
}
eangle = anglepot[idx].evaluate() - offset[type];
}
if (EVFLAG)

View File

@ -89,10 +89,17 @@ void BondLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
{
std::vector<Lepton::CompiledExpression> bondforce;
std::vector<Lepton::CompiledExpression> bondpot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp));
bondforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back(true);
try {
bondforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) bondpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -122,7 +129,7 @@ void BondLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
double fbond = 0.0;
if (r > 0.0) {
bondforce[idx].getVariableReference("r") = dr;
if (has_ref[idx]) bondforce[idx].getVariableReference("r") = dr;
fbond = -bondforce[idx].evaluate() / r;
}
@ -142,7 +149,11 @@ void BondLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
double ebond = 0.0;
if (EFLAG) {
bondpot[idx].getVariableReference("r") = dr;
try {
bondpot[idx].getVariableReference("r") = dr;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
ebond = bondpot[idx].evaluate() - offset[type];
}
if (EVFLAG)

View File

@ -19,9 +19,9 @@
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "math_extra.h"
#include "neighbor.h"
#include "suffix.h"
#include "math_extra.h"
#include <cmath>
@ -94,10 +94,17 @@ void DihedralLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
{
std::vector<Lepton::CompiledExpression> dihedralforce;
std::vector<Lepton::CompiledExpression> dihedralpot;
std::vector<bool> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp));
dihedralforce.emplace_back(parsed.differentiate("phi").createCompiledExpression());
has_ref.push_back(true);
try {
dihedralforce.back().getVariableReference("phi");
} catch (Lepton::Exception &) {
has_ref.back() = false;
}
if (EFLAG) dihedralpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -106,7 +113,7 @@ void DihedralLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
const double *const *const x = atom->x;
auto *_noalias const f = (dbl3_t *) thr->get_f()[0];
const int * const * const dihedrallist = neighbor->dihedrallist;
const int *const *const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
// The dihedral angle "phi" is the angle between n123 and n234
@ -279,7 +286,7 @@ void DihedralLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
}
const int idx = type2expression[type];
dihedralforce[idx].getVariableReference("phi") = phi;
if (has_ref[idx]) dihedralforce[idx].getVariableReference("phi") = phi;
double m_du_dphi = -dihedralforce[idx].evaluate();
// ----- Step 4: Calculate the force direction in real space -----
@ -323,7 +330,11 @@ void DihedralLeptonOMP::eval(int nfrom, int nto, ThrData *const thr)
double edihedral = 0.0;
if (EFLAG) {
dihedralpot[idx].getVariableReference("phi") = phi;
try {
dihedralpot[idx].getVariableReference("phi") = phi;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
edihedral = dihedralpot[idx].evaluate();
}
if (EVFLAG)

View File

@ -15,7 +15,7 @@
// clang-format off
typedef NPairRespaNsqOmp<0,0> NPairHalfRespaNsqNewtoffOmp;
NPairStyle(half/respa/nsq/newtoff/omp,
NPairHalfRespaNsqNewtoff,
NPairHalfRespaNsqNewtoffOmp,
NP_HALF | NP_RESPA | NP_NSQ | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairRespaNsqOmp<1,0> NPairHalfRespaNsqNewtonOmp;

View File

@ -20,11 +20,13 @@
#include "neigh_list.h"
#include "suffix.h"
#include <cmath>
#include "Lepton.h"
#include "lepton_utils.h"
#include "omp_compat.h"
#include <array>
#include <cmath>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
@ -101,25 +103,30 @@ void PairLeptonCoulOMP::eval(int iifrom, int iito, ThrData *const thr)
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<std::pair<bool, bool>> have_q;
std::vector<std::array<bool, 3>> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back({true, true, true});
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back()[0] = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
pairforce.back().getVariableReference("r");
have_q.emplace_back(true, true);
// check if there are references to charges
try {
pairforce.back().getVariableReference("qi");
} catch (std::exception &) {
have_q.back().first = false;
} catch (Lepton::Exception &) {
has_ref.back()[1] = false;
}
try {
pairforce.back().getVariableReference("qj");
} catch (std::exception &) {
have_q.back().second = false;
} catch (Lepton::Exception &) {
has_ref.back()[2] = false;
}
}
} catch (std::exception &e) {
@ -152,9 +159,9 @@ void PairLeptonCoulOMP::eval(int iifrom, int iito, ThrData *const thr)
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
pairforce[idx].getVariableReference("r") = r;
if (have_q[idx].first) pairforce[idx].getVariableReference("qi") = q2e * q[i];
if (have_q[idx].second) pairforce[idx].getVariableReference("qj") = q2e * q[j];
if (has_ref[idx][0]) pairforce[idx].getVariableReference("r") = r;
if (has_ref[idx][1]) pairforce[idx].getVariableReference("qi") = q2e * q[i];
if (has_ref[idx][2]) pairforce[idx].getVariableReference("qj") = q2e * q[j];
const double fpair = -pairforce[idx].evaluate() / r * factor_coul;
fxtmp += delx * fpair;
@ -168,9 +175,14 @@ void PairLeptonCoulOMP::eval(int iifrom, int iito, ThrData *const thr)
double ecoul = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
if (have_q[idx].first) pairpot[idx].getVariableReference("qi") = q2e * q[i];
if (have_q[idx].second) pairpot[idx].getVariableReference("qj") = q2e * q[j];
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
if (has_ref[idx][1]) pairpot[idx].getVariableReference("qi") = q2e * q[i];
if (has_ref[idx][2]) pairpot[idx].getVariableReference("qj") = q2e * q[j];
ecoul = pairpot[idx].evaluate();
ecoul *= factor_coul;
}

View File

@ -20,11 +20,12 @@
#include "neigh_list.h"
#include "suffix.h"
#include <cmath>
#include "Lepton.h"
#include "lepton_utils.h"
#include "omp_compat.h"
#include <array>
#include <cmath>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
@ -96,10 +97,17 @@ void PairLeptonOMP::eval(int iifrom, int iito, ThrData *const thr)
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<bool> have_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
have_ref.push_back(true);
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
have_ref.back() = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
}
} catch (std::exception &e) {
@ -132,7 +140,7 @@ void PairLeptonOMP::eval(int iifrom, int iito, ThrData *const thr)
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
pairforce[idx].getVariableReference("r") = r;
if (have_ref[idx]) pairforce[idx].getVariableReference("r") = r;
const double fpair = -pairforce[idx].evaluate() / r * factor_lj;
fxtmp += delx * fpair;
@ -146,7 +154,11 @@ void PairLeptonOMP::eval(int iifrom, int iito, ThrData *const thr)
double evdwl = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
evdwl = pairpot[idx].evaluate() - offset[itype][jtype];
evdwl *= factor_lj;
}

View File

@ -20,11 +20,13 @@
#include "neigh_list.h"
#include "suffix.h"
#include <cmath>
#include "Lepton.h"
#include "lepton_utils.h"
#include "omp_compat.h"
#include <array>
#include <cmath>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
@ -99,25 +101,30 @@ void PairLeptonSphereOMP::eval(int iifrom, int iito, ThrData *const thr)
std::vector<Lepton::CompiledExpression> pairforce;
std::vector<Lepton::CompiledExpression> pairpot;
std::vector<std::pair<bool, bool>> have_rad;
std::vector<std::array<bool, 3>> has_ref;
try {
for (const auto &expr : expressions) {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, Pointers::lmp), functions);
pairforce.emplace_back(parsed.differentiate("r").createCompiledExpression());
has_ref.push_back({true, true, true});
try {
pairforce.back().getVariableReference("r");
} catch (Lepton::Exception &) {
has_ref.back()[0] = false;
}
if (EFLAG) pairpot.emplace_back(parsed.createCompiledExpression());
pairforce.back().getVariableReference("r");
have_rad.emplace_back(true, true);
// check if there are references to charges
// check if there are references to radii
try {
pairforce.back().getVariableReference("radi");
} catch (std::exception &) {
have_rad.back().first = false;
} catch (Lepton::Exception &) {
has_ref.back()[1] = false;
}
try {
pairforce.back().getVariableReference("radj");
} catch (std::exception &) {
have_rad.back().second = false;
} catch (Lepton::Exception &) {
has_ref.back()[2] = false;
}
}
} catch (std::exception &e) {
@ -150,9 +157,9 @@ void PairLeptonSphereOMP::eval(int iifrom, int iito, ThrData *const thr)
if (rsq < cutsq[itype][jtype]) {
const double r = sqrt(rsq);
const int idx = type2expression[itype][jtype];
pairforce[idx].getVariableReference("r") = r;
if (have_rad[idx].first) pairforce[idx].getVariableReference("radi") = radius[i];
if (have_rad[idx].second) pairforce[idx].getVariableReference("radj") = radius[j];
if (has_ref[idx][0]) pairforce[idx].getVariableReference("r") = r;
if (has_ref[idx][1]) pairforce[idx].getVariableReference("radi") = radius[i];
if (has_ref[idx][2]) pairforce[idx].getVariableReference("radj") = radius[j];
const double fpair = -pairforce[idx].evaluate() / r * factor_lj;
fxtmp += delx * fpair;
@ -166,9 +173,14 @@ void PairLeptonSphereOMP::eval(int iifrom, int iito, ThrData *const thr)
double evdwl = 0.0;
if (EFLAG) {
pairpot[idx].getVariableReference("r") = r;
if (have_rad[idx].first) pairpot[idx].getVariableReference("radi") = radius[i];
if (have_rad[idx].second) pairpot[idx].getVariableReference("radj") = radius[j];
try {
pairpot[idx].getVariableReference("r") = r;
} catch (Lepton::Exception &) {
; // ignore -> constant potential
}
if (has_ref[idx][1]) pairpot[idx].getVariableReference("radi") = radius[i];
if (has_ref[idx][2]) pairpot[idx].getVariableReference("radj") = radius[j];
evdwl = pairpot[idx].evaluate();
evdwl *= factor_lj;
}

View File

@ -338,12 +338,6 @@ void FixQEq::setup_pre_force(int vflag)
if (force->newton_pair == 0)
error->all(FLERR,"QEQ with 'newton pair off' not supported");
if (force->pair) {
if (force->pair->suffix_flag & (Suffix::INTEL|Suffix::GPU))
error->all(FLERR,"QEQ is not compatiple with suffix version "
"of pair style");
}
deallocate_storage();
allocate_storage();

View File

@ -25,4 +25,5 @@ The REACTER methodology is detailed in:
https://doi.org/10.1021/acs.macromol.0c02012
This package was created by Jacob Gissinger
(jacob.r.gissinger@gmail.com) at the NASA Langley Research Center.
(jgissing@stevens.edu) while at the NASA Langley Research Center
and Stevens Institute of Technology.

View File

@ -13,7 +13,7 @@ See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com)
Contributing Author: Jacob Gissinger (jgissing@stevens.edu)
------------------------------------------------------------------------- */
#include "fix_bond_react.h"
@ -670,15 +670,6 @@ FixBondReact::~FixBondReact()
memory->destroy(ghostly_rxn_count);
memory->destroy(reaction_count_total);
if (newton_bond == 0) {
memory->destroy(xspecial);
memory->destroy(nxspecial);
memory->destroy(onemol_xspecial);
memory->destroy(onemol_nxspecial);
memory->destroy(twomol_xspecial);
memory->destroy(twomol_nxspecial);
}
if (attempted_rxn == 1) {
memory->destroy(restore_pt);
memory->destroy(restore);
@ -827,11 +818,10 @@ void FixBondReact::init()
nlevels_respa = (dynamic_cast<Respa *>(update->integrate))->nlevels;
// check cutoff for iatomtype,jatomtype
for (int i = 0; i < nreacts; i++) {
if (!utils::strmatch(force->pair_style,"^hybrid"))
if (force->pair == nullptr || cutsq[i][1] > force->pair->cutsq[iatomtype[i]][jatomtype[i]])
if (!utils::strmatch(force->pair_style,"^hybrid"))
for (int i = 0; i < nreacts; i++)
if (force->pair == nullptr || (closeneigh[i] < 0 && cutsq[i][1] > force->pair->cutsq[iatomtype[i]][jatomtype[i]]))
error->all(FLERR,"Fix bond/react: Fix bond/react cutoff is longer than pairwise cutoff");
}
// need a half neighbor list, built every Nevery steps
neighbor->add_request(this, NeighConst::REQ_OCCASIONAL);
@ -931,29 +921,10 @@ void FixBondReact::post_integrate()
neighbor->build_one(list,1);
// here we define a full special list, independent of Newton setting
if (newton_bond == 1) {
nxspecial = atom->nspecial;
xspecial = atom->special;
} else {
int nall = atom->nlocal + atom->nghost;
memory->destroy(nxspecial);
memory->destroy(xspecial);
memory->create(nxspecial,nall,3,"bond/react:nxspecial");
memory->create(xspecial,nall,atom->maxspecial,"bond/react:xspecial");
for (int i = 0; i < atom->nlocal; i++) {
nxspecial[i][0] = atom->num_bond[i];
for (int j = 0; j < nxspecial[i][0]; j++) {
xspecial[i][j] = atom->bond_atom[i][j];
}
nxspecial[i][1] = atom->nspecial[i][1];
nxspecial[i][2] = atom->nspecial[i][2];
int joffset = nxspecial[i][0] - atom->nspecial[i][0];
for (int j = nxspecial[i][0]; j < nxspecial[i][2]; j++) {
xspecial[i][j+joffset] = atom->special[i][j];
}
}
}
// here we define a full special list
// may need correction for unusual special bond settings
nxspecial = atom->nspecial;
xspecial = atom->special;
int j;
for (rxnID = 0; rxnID < nreacts; rxnID++) {
@ -2541,49 +2512,15 @@ int FixBondReact::get_chirality(double four_coords[12])
/* ----------------------------------------------------------------------
Get xspecials for current molecule templates
may need correction when specials defined explicitly in molecule templates
------------------------------------------------------------------------- */
void FixBondReact::get_molxspecials()
{
if (newton_bond == 1) {
onemol_nxspecial = onemol->nspecial;
onemol_xspecial = onemol->special;
twomol_nxspecial = twomol->nspecial;
twomol_xspecial = twomol->special;
} else {
memory->destroy(onemol_nxspecial);
memory->destroy(onemol_xspecial);
memory->create(onemol_nxspecial,onemol->natoms,3,"bond/react:onemol_nxspecial");
memory->create(onemol_xspecial,onemol->natoms,atom->maxspecial,"bond/react:onemol_xspecial");
for (int i = 0; i < onemol->natoms; i++) {
onemol_nxspecial[i][0] = onemol->num_bond[i];
for (int j = 0; j < onemol_nxspecial[i][0]; j++) {
onemol_xspecial[i][j] = onemol->bond_atom[i][j];
}
onemol_nxspecial[i][1] = onemol->nspecial[i][1];
onemol_nxspecial[i][2] = onemol->nspecial[i][2];
int joffset = onemol_nxspecial[i][0] - onemol->nspecial[i][0];
for (int j = onemol_nxspecial[i][0]; j < onemol_nxspecial[i][2]; j++) {
onemol_xspecial[i][j+joffset] = onemol->special[i][j];
}
}
memory->destroy(twomol_nxspecial);
memory->destroy(twomol_xspecial);
memory->create(twomol_nxspecial,twomol->natoms,3,"bond/react:twomol_nxspecial");
memory->create(twomol_xspecial,twomol->natoms,atom->maxspecial,"bond/react:twomol_xspecial");
for (int i = 0; i < twomol->natoms; i++) {
twomol_nxspecial[i][0] = twomol->num_bond[i];
for (int j = 0; j < twomol_nxspecial[i][0]; j++) {
twomol_xspecial[i][j] = twomol->bond_atom[i][j];
}
twomol_nxspecial[i][1] = twomol->nspecial[i][1];
twomol_nxspecial[i][2] = twomol->nspecial[i][2];
int joffset = twomol_nxspecial[i][0] - twomol->nspecial[i][0];
for (int j = twomol_nxspecial[i][0]; j < twomol_nxspecial[i][2]; j++) {
twomol_xspecial[i][j+joffset] = twomol->special[i][j];
}
}
}
onemol_nxspecial = onemol->nspecial;
onemol_xspecial = onemol->special;
twomol_nxspecial = twomol->nspecial;
twomol_xspecial = twomol->special;
}
/* ----------------------------------------------------------------------
@ -2682,16 +2619,43 @@ void FixBondReact::find_landlocked_atoms(int myrxn)
}
// also, if atoms change number of bonds, but aren't landlocked, that could be bad
int warnflag = 0;
if (comm->me == 0)
for (int i = 0; i < twomol->natoms; i++) {
if ((create_atoms[i][myrxn] == 0) &&
(twomol_nxspecial[i][0] != onemol_nxspecial[equivalences[i][1][myrxn]-1][0]) &&
(landlocked_atoms[i][myrxn] == 0))
error->warning(FLERR, "Fix bond/react: Atom affected by reaction {} is too close "
"to template edge",rxn_name[myrxn]);
break;
(landlocked_atoms[i][myrxn] == 0)) {
warnflag = 1;
break;
}
}
// also, if an atom changes any of its bonds, but is not landlocked, that could be bad
int thereflag;
if (comm->me == 0)
for (int i = 0; i < twomol->natoms; i++) {
if (landlocked_atoms[i][myrxn] == 1) continue;
for (int j = 0; j < twomol_nxspecial[i][0]; j++) {
int oneneighID = equivalences[twomol_xspecial[i][j]-1][1][myrxn];
int ii = equivalences[i][1][myrxn] - 1;
thereflag = 0;
for (int k = 0; k < onemol_nxspecial[ii][0]; k++) {
if (oneneighID == onemol_xspecial[ii][k]) {
thereflag = 1;
break;
}
}
if (thereflag == 0) {
warnflag = 1;
break;
}
}
if (warnflag == 1) break;
}
if (comm->me == 0 && warnflag == 1) error->warning(FLERR, "Fix bond/react: Atom affected "
"by reaction {} is too close to template edge",rxn_name[myrxn]);
// finally, if a created atom is not landlocked, bad!
for (int i = 0; i < twomol->natoms; i++) {
if (create_atoms[i][myrxn] == 1 && landlocked_atoms[i][myrxn] == 0) {
@ -3349,7 +3313,7 @@ void FixBondReact::update_everything()
dynamic_cast<FixBondHistory *>(ihistory)->clear_cache();
// Angles! First let's delete all angle info:
if (force->angle && twomol->angleflag) {
if (force->angle) {
int *num_angle = atom->num_angle;
int **angle_type = atom->angle_type;
tagint **angle_atom1 = atom->angle_atom1;
@ -3390,33 +3354,35 @@ void FixBondReact::update_everything()
}
}
// now let's add the new angle info.
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_angle[atom->map(update_mega_glove[jj+1][i])] = twomol->num_angle[j];
delta_angle += twomol->num_angle[j];
for (int p = 0; p < twomol->num_angle[j]; p++) {
angle_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->angle_type[j][p];
angle_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom1[j][p]-1][1][rxnID]][i];
angle_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom2[j][p]-1][1][rxnID]][i];
angle_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom3[j][p]-1][1][rxnID]][i];
if (twomol->angleflag) {
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_angle[atom->map(update_mega_glove[jj+1][i])] = twomol->num_angle[j];
delta_angle += twomol->num_angle[j];
for (int p = 0; p < twomol->num_angle[j]; p++) {
angle_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->angle_type[j][p];
angle_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom1[j][p]-1][1][rxnID]][i];
angle_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom2[j][p]-1][1][rxnID]][i];
angle_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->angle_atom3[j][p]-1][1][rxnID]][i];
}
}
}
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_angle[j]; p++) {
if (landlocked_atoms[twomol->angle_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->angle_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->angle_atom3[j][p]-1][rxnID] == 1) {
insert_num = num_angle[atom->map(update_mega_glove[jj+1][i])];
angle_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->angle_type[j][p];
angle_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom1[j][p]-1][1][rxnID]][i];
angle_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom2[j][p]-1][1][rxnID]][i];
angle_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom3[j][p]-1][1][rxnID]][i];
num_angle[atom->map(update_mega_glove[jj+1][i])]++;
if (num_angle[atom->map(update_mega_glove[jj+1][i])] > atom->angle_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_angle++;
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_angle[j]; p++) {
if (landlocked_atoms[twomol->angle_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->angle_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->angle_atom3[j][p]-1][rxnID] == 1) {
insert_num = num_angle[atom->map(update_mega_glove[jj+1][i])];
angle_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->angle_type[j][p];
angle_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom1[j][p]-1][1][rxnID]][i];
angle_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom2[j][p]-1][1][rxnID]][i];
angle_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->angle_atom3[j][p]-1][1][rxnID]][i];
num_angle[atom->map(update_mega_glove[jj+1][i])]++;
if (num_angle[atom->map(update_mega_glove[jj+1][i])] > atom->angle_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_angle++;
}
}
}
}
@ -3426,7 +3392,7 @@ void FixBondReact::update_everything()
}
// Dihedrals! first let's delete all dihedral info for landlocked atoms
if (force->dihedral && twomol->dihedralflag) {
if (force->dihedral) {
int *num_dihedral = atom->num_dihedral;
int **dihedral_type = atom->dihedral_type;
tagint **dihedral_atom1 = atom->dihedral_atom1;
@ -3470,36 +3436,38 @@ void FixBondReact::update_everything()
}
}
// now let's add new dihedral info
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_dihedral[atom->map(update_mega_glove[jj+1][i])] = twomol->num_dihedral[j];
delta_dihed += twomol->num_dihedral[j];
for (int p = 0; p < twomol->num_dihedral[j]; p++) {
dihedral_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->dihedral_type[j][p];
dihedral_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom1[j][p]-1][1][rxnID]][i];
dihedral_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom2[j][p]-1][1][rxnID]][i];
dihedral_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom3[j][p]-1][1][rxnID]][i];
dihedral_atom4[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom4[j][p]-1][1][rxnID]][i];
if (twomol->dihedralflag) {
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_dihedral[atom->map(update_mega_glove[jj+1][i])] = twomol->num_dihedral[j];
delta_dihed += twomol->num_dihedral[j];
for (int p = 0; p < twomol->num_dihedral[j]; p++) {
dihedral_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->dihedral_type[j][p];
dihedral_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom1[j][p]-1][1][rxnID]][i];
dihedral_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom2[j][p]-1][1][rxnID]][i];
dihedral_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom3[j][p]-1][1][rxnID]][i];
dihedral_atom4[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->dihedral_atom4[j][p]-1][1][rxnID]][i];
}
}
}
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_dihedral[j]; p++) {
if (landlocked_atoms[twomol->dihedral_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom3[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom4[j][p]-1][rxnID] == 1) {
insert_num = num_dihedral[atom->map(update_mega_glove[jj+1][i])];
dihedral_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->dihedral_type[j][p];
dihedral_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom1[j][p]-1][1][rxnID]][i];
dihedral_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom2[j][p]-1][1][rxnID]][i];
dihedral_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom3[j][p]-1][1][rxnID]][i];
dihedral_atom4[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom4[j][p]-1][1][rxnID]][i];
num_dihedral[atom->map(update_mega_glove[jj+1][i])]++;
if (num_dihedral[atom->map(update_mega_glove[jj+1][i])] > atom->dihedral_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_dihed++;
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_dihedral[j]; p++) {
if (landlocked_atoms[twomol->dihedral_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom3[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->dihedral_atom4[j][p]-1][rxnID] == 1) {
insert_num = num_dihedral[atom->map(update_mega_glove[jj+1][i])];
dihedral_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->dihedral_type[j][p];
dihedral_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom1[j][p]-1][1][rxnID]][i];
dihedral_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom2[j][p]-1][1][rxnID]][i];
dihedral_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom3[j][p]-1][1][rxnID]][i];
dihedral_atom4[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->dihedral_atom4[j][p]-1][1][rxnID]][i];
num_dihedral[atom->map(update_mega_glove[jj+1][i])]++;
if (num_dihedral[atom->map(update_mega_glove[jj+1][i])] > atom->dihedral_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_dihed++;
}
}
}
}
@ -3509,7 +3477,7 @@ void FixBondReact::update_everything()
}
// finally IMPROPERS!!!! first let's delete all improper info for landlocked atoms
if (force->improper && twomol->improperflag) {
if (force->improper) {
int *num_improper = atom->num_improper;
int **improper_type = atom->improper_type;
tagint **improper_atom1 = atom->improper_atom1;
@ -3553,36 +3521,38 @@ void FixBondReact::update_everything()
}
}
// now let's add new improper info
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_improper[atom->map(update_mega_glove[jj+1][i])] = twomol->num_improper[j];
delta_imprp += twomol->num_improper[j];
for (int p = 0; p < twomol->num_improper[j]; p++) {
improper_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->improper_type[j][p];
improper_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom1[j][p]-1][1][rxnID]][i];
improper_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom2[j][p]-1][1][rxnID]][i];
improper_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom3[j][p]-1][1][rxnID]][i];
improper_atom4[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom4[j][p]-1][1][rxnID]][i];
if (twomol->improperflag) {
for (int j = 0; j < twomol->natoms; j++) {
int jj = equivalences[j][1][rxnID]-1;
if (atom->map(update_mega_glove[jj+1][i]) < nlocal && atom->map(update_mega_glove[jj+1][i]) >= 0) {
if (landlocked_atoms[j][rxnID] == 1) {
num_improper[atom->map(update_mega_glove[jj+1][i])] = twomol->num_improper[j];
delta_imprp += twomol->num_improper[j];
for (int p = 0; p < twomol->num_improper[j]; p++) {
improper_type[atom->map(update_mega_glove[jj+1][i])][p] = twomol->improper_type[j][p];
improper_atom1[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom1[j][p]-1][1][rxnID]][i];
improper_atom2[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom2[j][p]-1][1][rxnID]][i];
improper_atom3[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom3[j][p]-1][1][rxnID]][i];
improper_atom4[atom->map(update_mega_glove[jj+1][i])][p] = update_mega_glove[equivalences[twomol->improper_atom4[j][p]-1][1][rxnID]][i];
}
}
}
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_improper[j]; p++) {
if (landlocked_atoms[twomol->improper_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom3[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom4[j][p]-1][rxnID] == 1) {
insert_num = num_improper[atom->map(update_mega_glove[jj+1][i])];
improper_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->improper_type[j][p];
improper_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom1[j][p]-1][1][rxnID]][i];
improper_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom2[j][p]-1][1][rxnID]][i];
improper_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom3[j][p]-1][1][rxnID]][i];
improper_atom4[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom4[j][p]-1][1][rxnID]][i];
num_improper[atom->map(update_mega_glove[jj+1][i])]++;
if (num_improper[atom->map(update_mega_glove[jj+1][i])] > atom->improper_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_imprp++;
if (landlocked_atoms[j][rxnID] == 0) {
for (int p = 0; p < twomol->num_improper[j]; p++) {
if (landlocked_atoms[twomol->improper_atom1[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom2[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom3[j][p]-1][rxnID] == 1 ||
landlocked_atoms[twomol->improper_atom4[j][p]-1][rxnID] == 1) {
insert_num = num_improper[atom->map(update_mega_glove[jj+1][i])];
improper_type[atom->map(update_mega_glove[jj+1][i])][insert_num] = twomol->improper_type[j][p];
improper_atom1[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom1[j][p]-1][1][rxnID]][i];
improper_atom2[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom2[j][p]-1][1][rxnID]][i];
improper_atom3[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom3[j][p]-1][1][rxnID]][i];
improper_atom4[atom->map(update_mega_glove[jj+1][i])][insert_num] = update_mega_glove[equivalences[twomol->improper_atom4[j][p]-1][1][rxnID]][i];
num_improper[atom->map(update_mega_glove[jj+1][i])]++;
if (num_improper[atom->map(update_mega_glove[jj+1][i])] > atom->improper_per_atom)
error->one(FLERR,"Fix bond/react topology/atom exceed system topology/atom");
delta_imprp++;
}
}
}
}
@ -3895,7 +3865,8 @@ int FixBondReact::insert_atoms(tagint **my_update_mega_glove, int iupdate)
// guess a somewhat reasonable initial velocity based on reaction site
// further control is possible using bond_react_MASTER_group
// compute |velocity| corresponding to a given temperature t, using specific atom's mass
double vtnorm = sqrt(t / (force->mvv2e / (dimension * force->boltz)) / atom->mass[twomol->type[m]]);
double mymass = atom->rmass ? atom->rmass[n] : atom->mass[twomol->type[m]];
double vtnorm = sqrt(t / (force->mvv2e / (dimension * force->boltz)) / mymass);
v[n][0] = random[rxnID]->uniform();
v[n][1] = random[rxnID]->uniform();
v[n][2] = random[rxnID]->uniform();

View File

@ -12,7 +12,7 @@
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing Author: Jacob Gissinger (jacob.r.gissinger@gmail.com)
Contributing Author: Jacob Gissinger (jgissing@stevens.edu)
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
@ -139,7 +139,7 @@ class FixBondReact : public Fix {
int avail_guesses; // num of restore points available
int *guess_branch; // used when there is more than two choices when guessing
int **restore_pt; // contains info about restore points
tagint **restore; // contaings info about restore points
tagint **restore; // contains info about restore points
int *pioneer_count; // counts pioneers
int **edge; // atoms in molecule templates with incorrect valences

View File

@ -26,6 +26,7 @@
#include "input.h"
#include "label_map.h"
#include "math_const.h"
#include "math_extra.h"
#include "memory.h"
#include "modify.h"
#include "molecule.h"
@ -2127,6 +2128,15 @@ std::vector<Molecule *>Atom::get_molecule_by_id(const std::string &id)
void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint offset)
{
if (onemol->qflag && q_flag) q[ilocal] = onemol->q[iatom];
if (onemol->muflag && mu_flag) {
double r[3], rotmat[3][3];
MathExtra::quat_to_mat(onemol->quat_external, rotmat);
MathExtra::matvec(rotmat, onemol->mu[iatom], r);
mu[ilocal][0] = r[0];
mu[ilocal][1] = r[1];
mu[ilocal][2] = r[2];
mu[ilocal][3] = sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
}
if (onemol->radiusflag && radius_flag) radius[ilocal] = onemol->radius[iatom];
if (onemol->rmassflag && rmass_flag) rmass[ilocal] = onemol->rmass[iatom];
else if (rmass_flag)

View File

@ -75,7 +75,7 @@ ComputePair::ComputePair(LAMMPS *lmp, int narg, char **arg) :
pair = force->pair_match(pstyle, 1, nsub);
}
if (!pair) error->all(FLERR, "Unrecognized pair style {} in compute pair command", pstyle);
if (!pair) error->all(FLERR, "Unused pair style {} in compute pair command", pstyle);
npair = pair->nextra;
if (npair) {

View File

@ -19,15 +19,12 @@
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "fix_bond_history.h"
#include "force.h"
#include "group.h"
#include "modify.h"
#include "special.h"
#if defined(LMP_BPM)
#include "fix_bond_history.h"
#endif
#include <cstring>
using namespace LAMMPS_NS;
@ -121,11 +118,9 @@ void DeleteBonds::command(int narg, char **arg)
iarg++;
}
#if defined(LMP_BPM)
// find instances of bond history to delete data
auto histories = modify->get_fix_by_style("BOND_HISTORY");
int n_histories = histories.size();
#endif
// border swap to ensure type and mask is current for off-proc atoms
// enforce PBC before in case atoms are outside box
@ -342,13 +337,11 @@ void DeleteBonds::command(int narg, char **arg)
n = atom->num_bond[i];
atom->bond_type[i][m] = atom->bond_type[i][n-1];
atom->bond_atom[i][m] = atom->bond_atom[i][n-1];
#if defined(LMP_BPM)
if (n_histories > 0)
for (auto &ihistory: histories) {
dynamic_cast<FixBondHistory *>(ihistory)->shift_history(i,m,n-1);
dynamic_cast<FixBondHistory *>(ihistory)->delete_history(i,n-1);
}
#endif
atom->num_bond[i]--;
} else m++;
} else m++;

View File

@ -99,8 +99,8 @@ class Fix : protected Pointers {
int size_local_cols; // 0 = vector, N = columns in local array
int local_freq; // frequency local data is available at
int pergrid_flag; // 0/1 if per-grid data is stored
int pergrid_freq; // frequency per-grid data is available at
int pergrid_flag; // 0/1 if per-grid data is stored
int pergrid_freq; // frequency per-grid data is available at
int extscalar; // 0/1 if global scalar is intensive/extensive
int extvector; // 0/1/-1 if global vector is all int/ext/extlist
@ -129,11 +129,11 @@ class Fix : protected Pointers {
// KOKKOS flags and variables
int kokkosable; // 1 if Kokkos fix
int forward_comm_device; // 1 if forward comm on Device
int exchange_comm_device; // 1 if exchange comm on Device
int fuse_integrate_flag; // 1 if can fuse initial integrate with final integrate
int sort_device; // 1 if sort on Device
int kokkosable; // 1 if Kokkos fix
int forward_comm_device; // 1 if forward comm on Device
int exchange_comm_device; // 1 if exchange comm on Device
int fuse_integrate_flag; // 1 if can fuse initial integrate with final integrate
int sort_device; // 1 if sort on Device
ExecutionSpace execution_space;
unsigned int datamask_read, datamask_modify;
@ -223,7 +223,7 @@ class Fix : protected Pointers {
virtual void unpack_reverse_grid(int, void *, int, int *){};
virtual void pack_remap_grid(int, void *, int, int *){};
virtual void unpack_remap_grid(int, void *, int, int *){};
virtual int unpack_read_grid(int, char *) {return 0;};
virtual int unpack_read_grid(int, char *) { return 0; };
virtual void pack_write_grid(int, void *){};
virtual void unpack_write_grid(int, void *, int *){};

View File

@ -1279,7 +1279,6 @@ void FixMove::set_arrays(int i)
double *quat;
double **x = atom->x;
double **quat_atom = atom->quat;
imageint *image = atom->image;
int *ellipsoid = atom->ellipsoid;
int *line = atom->line;
@ -1372,6 +1371,7 @@ void FixMove::set_arrays(int i)
// qoriginal = f(quat,-delta); // NOTE: edit this line
}
} else if (quat_atom_flag) {
// double **quat_atom = atom->quat;
// qoriginal[0] = quat_atom[i][0]; // NOTE: edit this line
// qoriginal[1] = quat_atom[i][1]; // NOTE: edit this line
// qoriginal[2] = quat_atom[i][2]; // NOTE: edit this line
@ -1434,6 +1434,7 @@ void FixMove::set_arrays(int i)
// qoriginal = f(quat,-delta); // NOTE: edit this line
}
} else if (quat_atom_flag) {
// double **quat_atom = atom->quat;
// qoriginal[0] = quat_atom[i][0]; // NOTE: edit this line
// qoriginal[1] = quat_atom[i][1]; // NOTE: edit this line
// qoriginal[2] = quat_atom[i][2]; // NOTE: edit this line

View File

@ -12,7 +12,7 @@
#include <memory> // std::unique_ptr
#include <vector>
#include "core.h"
#include "format.h" // std_string_view
FMT_BEGIN_NAMESPACE
@ -22,8 +22,9 @@ template <typename T> struct is_reference_wrapper : std::false_type {};
template <typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
template <typename T> const T& unwrap(const T& v) { return v; }
template <typename T> const T& unwrap(const std::reference_wrapper<T>& v) {
template <typename T> auto unwrap(const T& v) -> const T& { return v; }
template <typename T>
auto unwrap(const std::reference_wrapper<T>& v) -> const T& {
return static_cast<const T&>(v);
}
@ -50,7 +51,7 @@ class dynamic_arg_list {
std::unique_ptr<node<>> head_;
public:
template <typename T, typename Arg> const T& push(const Arg& arg) {
template <typename T, typename Arg> auto push(const Arg& arg) -> const T& {
auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
auto& value = new_node->value;
new_node->next = std::move(head_);
@ -110,14 +111,14 @@ class dynamic_format_arg_store
friend class basic_format_args<Context>;
unsigned long long get_types() const {
auto get_types() const -> unsigned long long {
return detail::is_unpacked_bit | data_.size() |
(named_info_.empty()
? 0ULL
: static_cast<unsigned long long>(detail::has_named_args_bit));
}
const basic_format_arg<Context>* data() const {
auto data() const -> const basic_format_arg<Context>* {
return named_info_.empty() ? data_.data() : data_.data() + 1;
}

View File

@ -18,7 +18,7 @@
#include <ostream>
#include <type_traits>
#include "format.h"
#include "ostream.h" // formatbuf
FMT_BEGIN_NAMESPACE
@ -72,7 +72,8 @@ template <typename To, typename From,
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
std::numeric_limits<From>::is_signed ==
std::numeric_limits<To>::is_signed)>
FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) {
FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
-> To {
ec = 0;
using F = std::numeric_limits<From>;
using T = std::numeric_limits<To>;
@ -101,7 +102,8 @@ template <typename To, typename From,
FMT_ENABLE_IF(!std::is_same<From, To>::value &&
std::numeric_limits<From>::is_signed !=
std::numeric_limits<To>::is_signed)>
FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) {
FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
-> To {
ec = 0;
using F = std::numeric_limits<From>;
using T = std::numeric_limits<To>;
@ -133,7 +135,8 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) {
template <typename To, typename From,
FMT_ENABLE_IF(std::is_same<From, To>::value)>
FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) {
FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
-> To {
ec = 0;
return from;
} // function
@ -154,7 +157,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) {
// clang-format on
template <typename To, typename From,
FMT_ENABLE_IF(!std::is_same<From, To>::value)>
FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) {
FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
ec = 0;
using T = std::numeric_limits<To>;
static_assert(std::is_floating_point<From>::value, "From must be floating");
@ -176,7 +179,7 @@ FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) {
template <typename To, typename From,
FMT_ENABLE_IF(std::is_same<From, To>::value)>
FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) {
FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
ec = 0;
static_assert(std::is_floating_point<From>::value, "From must be floating");
return from;
@ -188,8 +191,8 @@ FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) {
template <typename To, typename FromRep, typename FromPeriod,
FMT_ENABLE_IF(std::is_integral<FromRep>::value),
FMT_ENABLE_IF(std::is_integral<typename To::rep>::value)>
To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
int& ec) {
auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
int& ec) -> To {
using From = std::chrono::duration<FromRep, FromPeriod>;
ec = 0;
// the basic idea is that we need to convert from count() in the from type
@ -240,8 +243,8 @@ To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
template <typename To, typename FromRep, typename FromPeriod,
FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),
FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>
To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
int& ec) {
auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
int& ec) -> To {
using From = std::chrono::duration<FromRep, FromPeriod>;
ec = 0;
if (std::isnan(from.count())) {
@ -321,12 +324,12 @@ To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
namespace detail {
template <typename T = void> struct null {};
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline null<> localtime_s(...) { return null<>(); }
inline null<> gmtime_r(...) { return null<>(); }
inline null<> gmtime_s(...) { return null<>(); }
inline auto localtime_r FMT_NOMACRO(...) -> null<> { return null<>(); }
inline auto localtime_s(...) -> null<> { return null<>(); }
inline auto gmtime_r(...) -> null<> { return null<>(); }
inline auto gmtime_s(...) -> null<> { return null<>(); }
inline const std::locale& get_classic_locale() {
inline auto get_classic_locale() -> const std::locale& {
static const auto& locale = std::locale::classic();
return locale;
}
@ -336,8 +339,6 @@ template <typename CodeUnit> struct codecvt_result {
CodeUnit buf[max_size];
CodeUnit* end;
};
template <typename CodeUnit>
constexpr const size_t codecvt_result<CodeUnit>::max_size;
template <typename CodeUnit>
void write_codecvt(codecvt_result<CodeUnit>& out, string_view in_buf,
@ -408,8 +409,7 @@ inline void do_write(buffer<Char>& buf, const std::tm& time,
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
auto&& os = std::basic_ostream<Char>(&format_buf);
os.imbue(loc);
using iterator = std::ostreambuf_iterator<Char>;
const auto& facet = std::use_facet<std::time_put<Char, iterator>>(loc);
const auto& facet = std::use_facet<std::time_put<Char>>(loc);
auto end = facet.put(os, os, Char(' '), &time, format, modifier);
if (end.failed()) FMT_THROW(format_error("failed to format time"));
}
@ -432,6 +432,51 @@ auto write(OutputIt out, const std::tm& time, const std::locale& loc,
return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc);
}
template <typename Rep1, typename Rep2>
struct is_same_arithmetic_type
: public std::integral_constant<bool,
(std::is_integral<Rep1>::value &&
std::is_integral<Rep2>::value) ||
(std::is_floating_point<Rep1>::value &&
std::is_floating_point<Rep2>::value)> {
};
template <
typename To, typename FromRep, typename FromPeriod,
FMT_ENABLE_IF(is_same_arithmetic_type<FromRep, typename To::rep>::value)>
auto fmt_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
#if FMT_SAFE_DURATION_CAST
// Throwing version of safe_duration_cast is only available for
// integer to integer or float to float casts.
int ec;
To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
if (ec) FMT_THROW(format_error("cannot format duration"));
return to;
#else
// Standard duration cast, may overflow.
return std::chrono::duration_cast<To>(from);
#endif
}
template <
typename To, typename FromRep, typename FromPeriod,
FMT_ENABLE_IF(!is_same_arithmetic_type<FromRep, typename To::rep>::value)>
auto fmt_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
// Mixed integer <-> float cast is not supported by safe_duration_cast.
return std::chrono::duration_cast<To>(from);
}
template <typename Duration>
auto to_time_t(
std::chrono::time_point<std::chrono::system_clock, Duration> time_point)
-> std::time_t {
// Cannot use std::chrono::system_clock::to_time_t since this would first
// require a cast to std::chrono::system_clock::time_point, which could
// overflow.
return fmt_duration_cast<std::chrono::duration<std::time_t>>(
time_point.time_since_epoch())
.count();
}
} // namespace detail
FMT_BEGIN_EXPORT
@ -441,29 +486,29 @@ FMT_BEGIN_EXPORT
expressed in local time. Unlike ``std::localtime``, this function is
thread-safe on most platforms.
*/
inline std::tm localtime(std::time_t time) {
inline auto localtime(std::time_t time) -> std::tm {
struct dispatcher {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t) : time_(t) {}
bool run() {
auto run() -> bool {
using namespace fmt::detail;
return handle(localtime_r(&time_, &tm_));
}
bool handle(std::tm* tm) { return tm != nullptr; }
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
bool handle(detail::null<>) {
auto handle(detail::null<>) -> bool {
using namespace fmt::detail;
return fallback(localtime_s(&tm_, &time_));
}
bool fallback(int res) { return res == 0; }
auto fallback(int res) -> bool { return res == 0; }
#if !FMT_MSC_VERSION
bool fallback(detail::null<>) {
auto fallback(detail::null<>) -> bool {
using namespace fmt::detail;
std::tm* tm = std::localtime(&time_);
if (tm) tm_ = *tm;
@ -480,8 +525,8 @@ inline std::tm localtime(std::time_t time) {
#if FMT_USE_LOCAL_TIME
template <typename Duration>
inline auto localtime(std::chrono::local_time<Duration> time) -> std::tm {
return localtime(std::chrono::system_clock::to_time_t(
std::chrono::current_zone()->to_sys(time)));
return localtime(
detail::to_time_t(std::chrono::current_zone()->to_sys(time)));
}
#endif
@ -490,29 +535,29 @@ inline auto localtime(std::chrono::local_time<Duration> time) -> std::tm {
expressed in Coordinated Universal Time (UTC). Unlike ``std::gmtime``, this
function is thread-safe on most platforms.
*/
inline std::tm gmtime(std::time_t time) {
inline auto gmtime(std::time_t time) -> std::tm {
struct dispatcher {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t) : time_(t) {}
bool run() {
auto run() -> bool {
using namespace fmt::detail;
return handle(gmtime_r(&time_, &tm_));
}
bool handle(std::tm* tm) { return tm != nullptr; }
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
bool handle(detail::null<>) {
auto handle(detail::null<>) -> bool {
using namespace fmt::detail;
return fallback(gmtime_s(&tm_, &time_));
}
bool fallback(int res) { return res == 0; }
auto fallback(int res) -> bool { return res == 0; }
#if !FMT_MSC_VERSION
bool fallback(detail::null<>) {
auto fallback(detail::null<>) -> bool {
std::tm* tm = std::gmtime(&time_);
if (tm) tm_ = *tm;
return tm != nullptr;
@ -525,9 +570,11 @@ inline std::tm gmtime(std::time_t time) {
return gt.tm_;
}
inline std::tm gmtime(
std::chrono::time_point<std::chrono::system_clock> time_point) {
return gmtime(std::chrono::system_clock::to_time_t(time_point));
template <typename Duration>
inline auto gmtime(
std::chrono::time_point<std::chrono::system_clock, Duration> time_point)
-> std::tm {
return gmtime(detail::to_time_t(time_point));
}
namespace detail {
@ -566,7 +613,8 @@ inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
}
}
template <typename Period> FMT_CONSTEXPR inline const char* get_units() {
template <typename Period>
FMT_CONSTEXPR inline auto get_units() -> const char* {
if (std::is_same<Period, std::atto>::value) return "as";
if (std::is_same<Period, std::femto>::value) return "fs";
if (std::is_same<Period, std::pico>::value) return "ps";
@ -584,8 +632,9 @@ template <typename Period> FMT_CONSTEXPR inline const char* get_units() {
if (std::is_same<Period, std::tera>::value) return "Ts";
if (std::is_same<Period, std::peta>::value) return "Ps";
if (std::is_same<Period, std::exa>::value) return "Es";
if (std::is_same<Period, std::ratio<60>>::value) return "m";
if (std::is_same<Period, std::ratio<60>>::value) return "min";
if (std::is_same<Period, std::ratio<3600>>::value) return "h";
if (std::is_same<Period, std::ratio<86400>>::value) return "d";
return nullptr;
}
@ -621,9 +670,8 @@ auto write_padding(OutputIt out, pad_type pad) -> OutputIt {
// Parses a put_time-like format string and invokes handler actions.
template <typename Char, typename Handler>
FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
const Char* end,
Handler&& handler) {
FMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end,
Handler&& handler) -> const Char* {
if (begin == end || *begin == '}') return begin;
if (*begin != '%') FMT_THROW(format_error("invalid format"));
auto ptr = begin;
@ -954,25 +1002,25 @@ struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
FMT_CONSTEXPR void on_tz_name() {}
};
inline const char* tm_wday_full_name(int wday) {
inline auto tm_wday_full_name(int wday) -> const char* {
static constexpr const char* full_name_list[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?";
}
inline const char* tm_wday_short_name(int wday) {
inline auto tm_wday_short_name(int wday) -> const char* {
static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"};
return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???";
}
inline const char* tm_mon_full_name(int mon) {
inline auto tm_mon_full_name(int mon) -> const char* {
static constexpr const char* full_name_list[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?";
}
inline const char* tm_mon_short_name(int mon) {
inline auto tm_mon_short_name(int mon) -> const char* {
static constexpr const char* short_name_list[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
@ -1004,21 +1052,21 @@ inline void tzset_once() {
// Converts value to Int and checks that it's in the range [0, upper).
template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline Int to_nonnegative_int(T value, Int upper) {
FMT_ASSERT(std::is_unsigned<Int>::value ||
(value >= 0 && to_unsigned(value) <= to_unsigned(upper)),
"invalid value");
(void)upper;
inline auto to_nonnegative_int(T value, Int upper) -> Int {
if (!std::is_unsigned<Int>::value &&
(value < 0 || to_unsigned(value) > to_unsigned(upper))) {
FMT_THROW(fmt::format_error("chrono value is out of range"));
}
return static_cast<Int>(value);
}
template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>
inline Int to_nonnegative_int(T value, Int upper) {
inline auto to_nonnegative_int(T value, Int upper) -> Int {
if (value < 0 || value > static_cast<T>(upper))
FMT_THROW(format_error("invalid value"));
return static_cast<Int>(value);
}
constexpr long long pow10(std::uint32_t n) {
constexpr auto pow10(std::uint32_t n) -> long long {
return n == 0 ? 1 : 10 * pow10(n - 1);
}
@ -1052,13 +1100,12 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
std::chrono::seconds::rep>::type,
std::ratio<1, detail::pow10(num_fractional_digits)>>;
const auto fractional =
d - std::chrono::duration_cast<std::chrono::seconds>(d);
const auto fractional = d - fmt_duration_cast<std::chrono::seconds>(d);
const auto subseconds =
std::chrono::treat_as_floating_point<
typename subsecond_precision::rep>::value
? fractional.count()
: std::chrono::duration_cast<subsecond_precision>(fractional).count();
: fmt_duration_cast<subsecond_precision>(fractional).count();
auto n = static_cast<uint32_or_64_or_128_t<long long>>(subseconds);
const int num_digits = detail::count_digits(n);
@ -1109,11 +1156,11 @@ void write_floating_seconds(memory_buffer& buf, Duration duration,
num_fractional_digits = 6;
}
format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"),
std::fmod(val * static_cast<rep>(Duration::period::num) /
static_cast<rep>(Duration::period::den),
static_cast<rep>(60)),
num_fractional_digits);
fmt::format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"),
std::fmod(val * static_cast<rep>(Duration::period::num) /
static_cast<rep>(Duration::period::den),
static_cast<rep>(60)),
num_fractional_digits);
}
template <typename OutputIt, typename Char,
@ -1174,8 +1221,7 @@ class tm_writer {
return static_cast<int>(l);
}
// Algorithm:
// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_from_a_month_and_day_of_the_month_or_ordinal_date
// Algorithm: https://en.wikipedia.org/wiki/ISO_week_date.
auto iso_year_weeks(long long curr_year) const noexcept -> int {
const auto prev_year = curr_year - 1;
const auto curr_p =
@ -1315,7 +1361,7 @@ class tm_writer {
subsecs_(subsecs),
tm_(tm) {}
OutputIt out() const { return out_; }
auto out() const -> OutputIt { return out_; }
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
out_ = copy_str<Char>(begin, end, out_);
@ -1579,6 +1625,7 @@ struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
template <typename Char>
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
FMT_CONSTEXPR void on_day_of_year() {}
FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
@ -1597,16 +1644,16 @@ struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
template <typename T,
FMT_ENABLE_IF(std::is_integral<T>::value&& has_isfinite<T>::value)>
inline bool isfinite(T) {
inline auto isfinite(T) -> bool {
return true;
}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline T mod(T x, int y) {
inline auto mod(T x, int y) -> T {
return x % static_cast<T>(y);
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline T mod(T x, int y) {
inline auto mod(T x, int y) -> T {
return std::fmod(x, static_cast<T>(y));
}
@ -1621,49 +1668,38 @@ template <typename T> struct make_unsigned_or_unchanged<T, true> {
using type = typename std::make_unsigned<T>::type;
};
#if FMT_SAFE_DURATION_CAST
// throwing version of safe_duration_cast
template <typename To, typename FromRep, typename FromPeriod>
To fmt_safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) {
int ec;
To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
if (ec) FMT_THROW(format_error("cannot format duration"));
return to;
}
#endif
template <typename Rep, typename Period,
FMT_ENABLE_IF(std::is_integral<Rep>::value)>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
std::chrono::duration<Rep, Period> d) {
inline auto get_milliseconds(std::chrono::duration<Rep, Period> d)
-> std::chrono::duration<Rep, std::milli> {
// this may overflow and/or the result may not fit in the
// target type.
#if FMT_SAFE_DURATION_CAST
using CommonSecondsType =
typename std::common_type<decltype(d), std::chrono::seconds>::type;
const auto d_as_common = fmt_safe_duration_cast<CommonSecondsType>(d);
const auto d_as_common = fmt_duration_cast<CommonSecondsType>(d);
const auto d_as_whole_seconds =
fmt_safe_duration_cast<std::chrono::seconds>(d_as_common);
fmt_duration_cast<std::chrono::seconds>(d_as_common);
// this conversion should be nonproblematic
const auto diff = d_as_common - d_as_whole_seconds;
const auto ms =
fmt_safe_duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
fmt_duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
return ms;
#else
auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
auto s = fmt_duration_cast<std::chrono::seconds>(d);
return fmt_duration_cast<std::chrono::milliseconds>(d - s);
#endif
}
template <typename Char, typename Rep, typename OutputIt,
FMT_ENABLE_IF(std::is_integral<Rep>::value)>
OutputIt format_duration_value(OutputIt out, Rep val, int) {
auto format_duration_value(OutputIt out, Rep val, int) -> OutputIt {
return write<Char>(out, val);
}
template <typename Char, typename Rep, typename OutputIt,
FMT_ENABLE_IF(std::is_floating_point<Rep>::value)>
OutputIt format_duration_value(OutputIt out, Rep val, int precision) {
auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {
auto specs = format_specs<Char>();
specs.precision = precision;
specs.type = precision >= 0 ? presentation_type::fixed_lower
@ -1672,12 +1708,12 @@ OutputIt format_duration_value(OutputIt out, Rep val, int precision) {
}
template <typename Char, typename OutputIt>
OutputIt copy_unit(string_view unit, OutputIt out, Char) {
auto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt {
return std::copy(unit.begin(), unit.end(), out);
}
template <typename OutputIt>
OutputIt copy_unit(string_view unit, OutputIt out, wchar_t) {
auto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt {
// This works when wchar_t is UTF-32 because units only contain characters
// that have the same representation in UTF-16 and UTF-32.
utf8_to_utf16 u(unit);
@ -1685,7 +1721,7 @@ OutputIt copy_unit(string_view unit, OutputIt out, wchar_t) {
}
template <typename Char, typename Period, typename OutputIt>
OutputIt format_duration_unit(OutputIt out) {
auto format_duration_unit(OutputIt out) -> OutputIt {
if (const char* unit = get_units<Period>())
return copy_unit(string_view(unit), out, Char());
*out++ = '[';
@ -1752,18 +1788,12 @@ struct chrono_formatter {
// this may overflow and/or the result may not fit in the
// target type.
#if FMT_SAFE_DURATION_CAST
// might need checked conversion (rep!=Rep)
auto tmpval = std::chrono::duration<rep, Period>(val);
s = fmt_safe_duration_cast<seconds>(tmpval);
#else
s = std::chrono::duration_cast<seconds>(
std::chrono::duration<rep, Period>(val));
#endif
s = fmt_duration_cast<seconds>(std::chrono::duration<rep, Period>(val));
}
// returns true if nan or inf, writes to out.
bool handle_nan_inf() {
auto handle_nan_inf() -> bool {
if (isfinite(val)) {
return false;
}
@ -1780,17 +1810,22 @@ struct chrono_formatter {
return true;
}
Rep hour() const { return static_cast<Rep>(mod((s.count() / 3600), 24)); }
auto days() const -> Rep { return static_cast<Rep>(s.count() / 86400); }
auto hour() const -> Rep {
return static_cast<Rep>(mod((s.count() / 3600), 24));
}
Rep hour12() const {
auto hour12() const -> Rep {
Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12));
return hour <= 0 ? 12 : hour;
}
Rep minute() const { return static_cast<Rep>(mod((s.count() / 60), 60)); }
Rep second() const { return static_cast<Rep>(mod(s.count(), 60)); }
auto minute() const -> Rep {
return static_cast<Rep>(mod((s.count() / 60), 60));
}
auto second() const -> Rep { return static_cast<Rep>(mod(s.count(), 60)); }
std::tm time() const {
auto time() const -> std::tm {
auto time = std::tm();
time.tm_hour = to_nonnegative_int(hour(), 24);
time.tm_min = to_nonnegative_int(minute(), 60);
@ -1858,10 +1893,14 @@ struct chrono_formatter {
void on_dec0_week_of_year(numeric_system) {}
void on_dec1_week_of_year(numeric_system) {}
void on_iso_week_of_year(numeric_system) {}
void on_day_of_year() {}
void on_day_of_month(numeric_system) {}
void on_day_of_month_space(numeric_system) {}
void on_day_of_year() {
if (handle_nan_inf()) return;
write(days(), 0);
}
void on_24_hour(numeric_system ns, pad_type pad) {
if (handle_nan_inf()) return;
@ -1968,7 +2007,7 @@ class weekday {
weekday() = default;
explicit constexpr weekday(unsigned wd) noexcept
: value(static_cast<unsigned char>(wd != 7 ? wd : 0)) {}
constexpr unsigned c_encoding() const noexcept { return value; }
constexpr auto c_encoding() const noexcept -> unsigned { return value; }
};
class year_month_day {};
@ -2083,25 +2122,22 @@ struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
period::num != 1 || period::den != 1 ||
std::is_floating_point<typename Duration::rep>::value)) {
const auto epoch = val.time_since_epoch();
auto subsecs = std::chrono::duration_cast<Duration>(
epoch - std::chrono::duration_cast<std::chrono::seconds>(epoch));
auto subsecs = detail::fmt_duration_cast<Duration>(
epoch - detail::fmt_duration_cast<std::chrono::seconds>(epoch));
if (subsecs.count() < 0) {
auto second =
std::chrono::duration_cast<Duration>(std::chrono::seconds(1));
detail::fmt_duration_cast<Duration>(std::chrono::seconds(1));
if (epoch.count() < ((Duration::min)() + second).count())
FMT_THROW(format_error("duration is too small"));
subsecs += second;
val -= second;
}
return formatter<std::tm, Char>::do_format(
gmtime(std::chrono::time_point_cast<std::chrono::seconds>(val)), ctx,
&subsecs);
return formatter<std::tm, Char>::do_format(gmtime(val), ctx, &subsecs);
}
return formatter<std::tm, Char>::format(
gmtime(std::chrono::time_point_cast<std::chrono::seconds>(val)), ctx);
return formatter<std::tm, Char>::format(gmtime(val), ctx);
}
};
@ -2120,17 +2156,13 @@ struct formatter<std::chrono::local_time<Duration>, Char>
if (period::num != 1 || period::den != 1 ||
std::is_floating_point<typename Duration::rep>::value) {
const auto epoch = val.time_since_epoch();
const auto subsecs = std::chrono::duration_cast<Duration>(
epoch - std::chrono::duration_cast<std::chrono::seconds>(epoch));
const auto subsecs = detail::fmt_duration_cast<Duration>(
epoch - detail::fmt_duration_cast<std::chrono::seconds>(epoch));
return formatter<std::tm, Char>::do_format(
localtime(std::chrono::time_point_cast<std::chrono::seconds>(val)),
ctx, &subsecs);
return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
}
return formatter<std::tm, Char>::format(
localtime(std::chrono::time_point_cast<std::chrono::seconds>(val)),
ctx);
return formatter<std::tm, Char>::format(localtime(val), ctx);
}
};
#endif

View File

@ -233,7 +233,7 @@ class text_style {
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
: set_foreground_color(), set_background_color(), ems(em) {}
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
FMT_CONSTEXPR auto operator|=(const text_style& rhs) -> text_style& {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
@ -257,29 +257,29 @@ class text_style {
return *this;
}
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
const text_style& rhs) {
friend FMT_CONSTEXPR auto operator|(text_style lhs, const text_style& rhs)
-> text_style {
return lhs |= rhs;
}
FMT_CONSTEXPR bool has_foreground() const noexcept {
FMT_CONSTEXPR auto has_foreground() const noexcept -> bool {
return set_foreground_color;
}
FMT_CONSTEXPR bool has_background() const noexcept {
FMT_CONSTEXPR auto has_background() const noexcept -> bool {
return set_background_color;
}
FMT_CONSTEXPR bool has_emphasis() const noexcept {
FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool {
return static_cast<uint8_t>(ems) != 0;
}
FMT_CONSTEXPR detail::color_type get_foreground() const noexcept {
FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type {
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
return foreground_color;
}
FMT_CONSTEXPR detail::color_type get_background() const noexcept {
FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type {
FMT_ASSERT(has_background(), "no background specified for this style");
return background_color;
}
FMT_CONSTEXPR emphasis get_emphasis() const noexcept {
FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis {
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
return ems;
}
@ -297,9 +297,11 @@ class text_style {
}
}
friend FMT_CONSTEXPR text_style fg(detail::color_type foreground) noexcept;
friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept
-> text_style;
friend FMT_CONSTEXPR text_style bg(detail::color_type background) noexcept;
friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept
-> text_style;
detail::color_type foreground_color;
detail::color_type background_color;
@ -309,16 +311,19 @@ class text_style {
};
/** Creates a text style from the foreground (text) color. */
FMT_CONSTEXPR inline text_style fg(detail::color_type foreground) noexcept {
FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
-> text_style {
return text_style(true, foreground);
}
/** Creates a text style from the background color. */
FMT_CONSTEXPR inline text_style bg(detail::color_type background) noexcept {
FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
-> text_style {
return text_style(false, background);
}
FMT_CONSTEXPR inline text_style operator|(emphasis lhs, emphasis rhs) noexcept {
FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept
-> text_style {
return text_style(lhs) | rhs;
}
@ -384,8 +389,8 @@ template <typename Char> struct ansi_color_escape {
}
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
FMT_CONSTEXPR const Char* begin() const noexcept { return buffer; }
FMT_CONSTEXPR_CHAR_TRAITS const Char* end() const noexcept {
FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
FMT_CONSTEXPR20 auto end() const noexcept -> const Char* {
return buffer + std::char_traits<Char>::length(buffer);
}
@ -400,25 +405,27 @@ template <typename Char> struct ansi_color_escape {
out[2] = static_cast<Char>('0' + c % 10);
out[3] = static_cast<Char>(delimiter);
}
static FMT_CONSTEXPR bool has_emphasis(emphasis em, emphasis mask) noexcept {
static FMT_CONSTEXPR auto has_emphasis(emphasis em, emphasis mask) noexcept
-> bool {
return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask);
}
};
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
detail::color_type foreground) noexcept {
FMT_CONSTEXPR auto make_foreground_color(detail::color_type foreground) noexcept
-> ansi_color_escape<Char> {
return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
detail::color_type background) noexcept {
FMT_CONSTEXPR auto make_background_color(detail::color_type background) noexcept
-> ansi_color_escape<Char> {
return ansi_color_escape<Char>(background, "\x1b[48;2;");
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) noexcept {
FMT_CONSTEXPR auto make_emphasis(emphasis em) noexcept
-> ansi_color_escape<Char> {
return ansi_color_escape<Char>(em);
}
@ -427,9 +434,10 @@ template <typename Char> inline void reset_color(buffer<Char>& buffer) {
buffer.append(reset_color.begin(), reset_color.end());
}
template <typename T> struct styled_arg {
template <typename T> struct styled_arg : detail::view {
const T& value;
text_style style;
styled_arg(const T& v, text_style s) : value(v), style(s) {}
};
template <typename Char>
@ -510,9 +518,10 @@ void print(const text_style& ts, const S& format_str, const Args&... args) {
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
inline auto vformat(
const text_style& ts, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, detail::to_string_view(format_str), args);
return fmt::to_string(buf);
@ -531,8 +540,8 @@ inline std::basic_string<Char> vformat(
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
const Args&... args) {
inline auto format(const text_style& ts, const S& format_str,
const Args&... args) -> std::basic_string<Char> {
return fmt::vformat(ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}
@ -542,9 +551,10 @@ inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
*/
template <typename OutputIt, typename Char,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
OutputIt vformat_to(
OutputIt out, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto vformat_to(OutputIt out, const text_style& ts,
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, ts, format_str, args);
return detail::get_iterator(buf, out);
@ -562,9 +572,10 @@ OutputIt vformat_to(
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&&
detail::is_string<S>::value>
template <
typename OutputIt, typename S, typename... Args,
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value &&
detail::is_string<S>::value>
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type {

View File

@ -14,8 +14,8 @@ FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char, typename InputIt>
FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
FMT_CONSTEXPR inline auto copy_str(InputIt begin, InputIt end,
counting_iterator it) -> counting_iterator {
return it + (end - begin);
}
@ -57,7 +57,7 @@ struct udl_compiled_string : compiled_string {
#endif
template <typename T, typename... Tail>
const T& first(const T& value, const Tail&...) {
auto first(const T& value, const Tail&...) -> const T& {
return value;
}
@ -489,18 +489,19 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
const S& format_str, Args&&... args) {
auto format_to_n(OutputIt out, size_t n, const S& format_str, Args&&... args)
-> format_to_n_result<OutputIt> {
using traits = detail::fixed_buffer_traits;
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
format_to(std::back_inserter(buf), format_str, std::forward<Args>(args)...);
fmt::format_to(std::back_inserter(buf), format_str,
std::forward<Args>(args)...);
return {buf.out(), buf.count()};
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR20 size_t formatted_size(const S& format_str,
const Args&... args) {
FMT_CONSTEXPR20 auto formatted_size(const S& format_str, const Args&... args)
-> size_t {
return fmt::format_to(detail::counting_iterator(), format_str, args...)
.count();
}

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@
# include <locale>
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(FMT_WINDOWS_NO_WCHAR)
# include <io.h> // _isatty
#endif
@ -36,10 +36,6 @@ FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
std::terminate();
}
FMT_FUNC void throw_format_error(const char* message) {
FMT_THROW(format_error(message));
}
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
string_view message) noexcept {
// Report error code making sure that the output fits into
@ -58,8 +54,8 @@ FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
auto it = buffer_appender<char>(out);
if (message.size() <= inline_buffer_size - error_code_size)
format_to(it, FMT_STRING("{}{}"), message, SEP);
format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
fmt::format_to(it, FMT_STRING("{}{}"), message, SEP);
fmt::format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
FMT_ASSERT(out.size() <= inline_buffer_size, "");
}
@ -73,9 +69,8 @@ FMT_FUNC void report_error(format_func func, int error_code,
}
// A wrapper around fwrite that throws on error.
inline void fwrite_fully(const void* ptr, size_t size, size_t count,
FILE* stream) {
size_t written = std::fwrite(ptr, size, count, stream);
inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) {
size_t written = std::fwrite(ptr, 1, count, stream);
if (written < count)
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
}
@ -86,7 +81,7 @@ locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
static_assert(std::is_same<Locale, std::locale>::value, "");
}
template <typename Locale> Locale locale_ref::get() const {
template <typename Locale> auto locale_ref::get() const -> Locale {
static_assert(std::is_same<Locale, std::locale>::value, "");
return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
}
@ -98,7 +93,8 @@ FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();
return {std::move(grouping), thousands_sep};
}
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
template <typename Char>
FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char {
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
.decimal_point();
}
@ -127,6 +123,10 @@ FMT_FUNC auto write_loc(appender out, loc_value value,
}
} // namespace detail
FMT_FUNC void throw_format_error(const char* message) {
FMT_THROW(format_error(message));
}
template <typename Locale> typename Locale::id format_facet<Locale>::id;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
@ -144,24 +144,25 @@ FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
}
#endif
FMT_FUNC std::system_error vsystem_error(int error_code, string_view fmt,
format_args args) {
FMT_FUNC auto vsystem_error(int error_code, string_view fmt, format_args args)
-> std::system_error {
auto ec = std::error_code(error_code, std::generic_category());
return std::system_error(ec, vformat(fmt, args));
}
namespace detail {
template <typename F> inline bool operator==(basic_fp<F> x, basic_fp<F> y) {
template <typename F>
inline auto operator==(basic_fp<F> x, basic_fp<F> y) -> bool {
return x.f == y.f && x.e == y.e;
}
// Compilers should be able to optimize this into the ror instruction.
FMT_CONSTEXPR inline uint32_t rotr(uint32_t n, uint32_t r) noexcept {
FMT_CONSTEXPR inline auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {
r &= 31;
return (n >> r) | (n << (32 - r));
}
FMT_CONSTEXPR inline uint64_t rotr(uint64_t n, uint32_t r) noexcept {
FMT_CONSTEXPR inline auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {
r &= 63;
return (n >> r) | (n << (64 - r));
}
@ -170,14 +171,14 @@ FMT_CONSTEXPR inline uint64_t rotr(uint64_t n, uint32_t r) noexcept {
namespace dragonbox {
// Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a
// 64-bit unsigned integer.
inline uint64_t umul96_upper64(uint32_t x, uint64_t y) noexcept {
inline auto umul96_upper64(uint32_t x, uint64_t y) noexcept -> uint64_t {
return umul128_upper64(static_cast<uint64_t>(x) << 32, y);
}
// Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a
// 128-bit unsigned integer.
inline uint128_fallback umul192_lower128(uint64_t x,
uint128_fallback y) noexcept {
inline auto umul192_lower128(uint64_t x, uint128_fallback y) noexcept
-> uint128_fallback {
uint64_t high = x * y.high();
uint128_fallback high_low = umul128(x, y.low());
return {high + high_low.high(), high_low.low()};
@ -185,12 +186,12 @@ inline uint128_fallback umul192_lower128(uint64_t x,
// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a
// 64-bit unsigned integer.
inline uint64_t umul96_lower64(uint32_t x, uint64_t y) noexcept {
inline auto umul96_lower64(uint32_t x, uint64_t y) noexcept -> uint64_t {
return x * y;
}
// Various fast log computations.
inline int floor_log10_pow2_minus_log10_4_over_3(int e) noexcept {
inline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int {
FMT_ASSERT(e <= 2936 && e >= -2985, "too large exponent");
return (e * 631305 - 261663) >> 21;
}
@ -204,7 +205,7 @@ FMT_INLINE_VARIABLE constexpr struct {
// divisible by pow(10, N).
// Precondition: n <= pow(10, N + 1).
template <int N>
bool check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept {
auto check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept -> bool {
// The numbers below are chosen such that:
// 1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100,
// 2. nm mod 2^k < m if and only if n is divisible by d,
@ -229,7 +230,7 @@ bool check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept {
// Computes floor(n / pow(10, N)) for small n and N.
// Precondition: n <= pow(10, N + 1).
template <int N> uint32_t small_division_by_pow10(uint32_t n) noexcept {
template <int N> auto small_division_by_pow10(uint32_t n) noexcept -> uint32_t {
constexpr auto info = div_small_pow10_infos[N - 1];
FMT_ASSERT(n <= info.divisor * 10, "n is too large");
constexpr uint32_t magic_number =
@ -238,12 +239,12 @@ template <int N> uint32_t small_division_by_pow10(uint32_t n) noexcept {
}
// Computes floor(n / 10^(kappa + 1)) (float)
inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) noexcept {
inline auto divide_by_10_to_kappa_plus_1(uint32_t n) noexcept -> uint32_t {
// 1374389535 = ceil(2^37/100)
return static_cast<uint32_t>((static_cast<uint64_t>(n) * 1374389535) >> 37);
}
// Computes floor(n / 10^(kappa + 1)) (double)
inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) noexcept {
inline auto divide_by_10_to_kappa_plus_1(uint64_t n) noexcept -> uint64_t {
// 2361183241434822607 = ceil(2^(64+7)/1000)
return umul128_upper64(n, 2361183241434822607ull) >> 7;
}
@ -255,7 +256,7 @@ template <> struct cache_accessor<float> {
using carrier_uint = float_info<float>::carrier_uint;
using cache_entry_type = uint64_t;
static uint64_t get_cached_power(int k) noexcept {
static auto get_cached_power(int k) noexcept -> uint64_t {
FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
"k is out of range");
static constexpr const uint64_t pow10_significands[] = {
@ -297,20 +298,23 @@ template <> struct cache_accessor<float> {
bool is_integer;
};
static compute_mul_result compute_mul(
carrier_uint u, const cache_entry_type& cache) noexcept {
static auto compute_mul(carrier_uint u,
const cache_entry_type& cache) noexcept
-> compute_mul_result {
auto r = umul96_upper64(u, cache);
return {static_cast<carrier_uint>(r >> 32),
static_cast<carrier_uint>(r) == 0};
}
static uint32_t compute_delta(const cache_entry_type& cache,
int beta) noexcept {
static auto compute_delta(const cache_entry_type& cache, int beta) noexcept
-> uint32_t {
return static_cast<uint32_t>(cache >> (64 - 1 - beta));
}
static compute_mul_parity_result compute_mul_parity(
carrier_uint two_f, const cache_entry_type& cache, int beta) noexcept {
static auto compute_mul_parity(carrier_uint two_f,
const cache_entry_type& cache,
int beta) noexcept
-> compute_mul_parity_result {
FMT_ASSERT(beta >= 1, "");
FMT_ASSERT(beta < 64, "");
@ -319,22 +323,22 @@ template <> struct cache_accessor<float> {
static_cast<uint32_t>(r >> (32 - beta)) == 0};
}
static carrier_uint compute_left_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_left_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return static_cast<carrier_uint>(
(cache - (cache >> (num_significand_bits<float>() + 2))) >>
(64 - num_significand_bits<float>() - 1 - beta));
}
static carrier_uint compute_right_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_right_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return static_cast<carrier_uint>(
(cache + (cache >> (num_significand_bits<float>() + 1))) >>
(64 - num_significand_bits<float>() - 1 - beta));
}
static carrier_uint compute_round_up_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_round_up_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return (static_cast<carrier_uint>(
cache >> (64 - num_significand_bits<float>() - 2 - beta)) +
1) /
@ -346,7 +350,7 @@ template <> struct cache_accessor<double> {
using carrier_uint = float_info<double>::carrier_uint;
using cache_entry_type = uint128_fallback;
static uint128_fallback get_cached_power(int k) noexcept {
static auto get_cached_power(int k) noexcept -> uint128_fallback {
FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
"k is out of range");
@ -985,8 +989,7 @@ template <> struct cache_accessor<double> {
{0xe0accfa875af45a7, 0x93eb1b80a33b8606},
{0x8c6c01c9498d8b88, 0xbc72f130660533c4},
{0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b5},
{ 0xdb68c2ca82ed2a05,
0xa67398db9f6820e2 }
{0xdb68c2ca82ed2a05, 0xa67398db9f6820e2},
#else
{0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
{0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
@ -1071,19 +1074,22 @@ template <> struct cache_accessor<double> {
bool is_integer;
};
static compute_mul_result compute_mul(
carrier_uint u, const cache_entry_type& cache) noexcept {
static auto compute_mul(carrier_uint u,
const cache_entry_type& cache) noexcept
-> compute_mul_result {
auto r = umul192_upper128(u, cache);
return {r.high(), r.low() == 0};
}
static uint32_t compute_delta(cache_entry_type const& cache,
int beta) noexcept {
static auto compute_delta(cache_entry_type const& cache, int beta) noexcept
-> uint32_t {
return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta));
}
static compute_mul_parity_result compute_mul_parity(
carrier_uint two_f, const cache_entry_type& cache, int beta) noexcept {
static auto compute_mul_parity(carrier_uint two_f,
const cache_entry_type& cache,
int beta) noexcept
-> compute_mul_parity_result {
FMT_ASSERT(beta >= 1, "");
FMT_ASSERT(beta < 64, "");
@ -1092,35 +1098,35 @@ template <> struct cache_accessor<double> {
((r.high() << beta) | (r.low() >> (64 - beta))) == 0};
}
static carrier_uint compute_left_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_left_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return (cache.high() -
(cache.high() >> (num_significand_bits<double>() + 2))) >>
(64 - num_significand_bits<double>() - 1 - beta);
}
static carrier_uint compute_right_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_right_endpoint_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return (cache.high() +
(cache.high() >> (num_significand_bits<double>() + 1))) >>
(64 - num_significand_bits<double>() - 1 - beta);
}
static carrier_uint compute_round_up_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept {
static auto compute_round_up_for_shorter_interval_case(
const cache_entry_type& cache, int beta) noexcept -> carrier_uint {
return ((cache.high() >> (64 - num_significand_bits<double>() - 2 - beta)) +
1) /
2;
}
};
FMT_FUNC uint128_fallback get_cached_power(int k) noexcept {
FMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback {
return cache_accessor<double>::get_cached_power(k);
}
// Various integer checks
template <typename T>
bool is_left_endpoint_integer_shorter_interval(int exponent) noexcept {
auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool {
const int case_shorter_interval_left_endpoint_lower_threshold = 2;
const int case_shorter_interval_left_endpoint_upper_threshold = 3;
return exponent >= case_shorter_interval_left_endpoint_lower_threshold &&
@ -1132,7 +1138,7 @@ FMT_INLINE int remove_trailing_zeros(uint32_t& n, int s = 0) noexcept {
FMT_ASSERT(n != 0, "");
// Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1.
constexpr uint32_t mod_inv_5 = 0xcccccccd;
constexpr uint32_t mod_inv_25 = 0xc28f5c29; // = mod_inv_5 * mod_inv_5
constexpr uint32_t mod_inv_25 = 0xc28f5c29; // = mod_inv_5 * mod_inv_5
while (true) {
auto q = rotr(n * mod_inv_25, 2);
@ -1168,7 +1174,7 @@ FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept {
// If n is not divisible by 10^8, work with n itself.
constexpr uint64_t mod_inv_5 = 0xcccccccccccccccd;
constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29; // = mod_inv_5 * mod_inv_5
constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29; // mod_inv_5 * mod_inv_5
int s = 0;
while (true) {
@ -1234,7 +1240,7 @@ FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) noexcept {
return ret_value;
}
template <typename T> decimal_fp<T> to_decimal(T x) noexcept {
template <typename T> auto to_decimal(T x) noexcept -> decimal_fp<T> {
// Step 1: integer promotion & Schubfach multiplier calculation.
using carrier_uint = typename float_info<T>::carrier_uint;
@ -1373,15 +1379,15 @@ template <> struct formatter<detail::bigint> {
for (auto i = n.bigits_.size(); i > 0; --i) {
auto value = n.bigits_[i - 1u];
if (first) {
out = format_to(out, FMT_STRING("{:x}"), value);
out = fmt::format_to(out, FMT_STRING("{:x}"), value);
first = false;
continue;
}
out = format_to(out, FMT_STRING("{:08x}"), value);
out = fmt::format_to(out, FMT_STRING("{:08x}"), value);
}
if (n.exp_ > 0)
out = format_to(out, FMT_STRING("p{}"),
n.exp_ * detail::bigint::bigit_bits);
out = fmt::format_to(out, FMT_STRING("p{}"),
n.exp_ * detail::bigint::bigit_bits);
return out;
}
};
@ -1417,7 +1423,7 @@ FMT_FUNC void report_system_error(int error_code,
report_error(format_system_error, error_code, message);
}
FMT_FUNC std::string vformat(string_view fmt, format_args args) {
FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
// Don't optimize the "{}" case to keep the binary size small and because it
// can be better optimized in fmt::format anyway.
auto buffer = memory_buffer();
@ -1426,33 +1432,38 @@ FMT_FUNC std::string vformat(string_view fmt, format_args args) {
}
namespace detail {
#ifndef _WIN32
FMT_FUNC bool write_console(std::FILE*, string_view) { return false; }
#if !defined(_WIN32) || defined(FMT_WINDOWS_NO_WCHAR)
FMT_FUNC auto write_console(int, string_view) -> bool { return false; }
#else
using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
void*, const void*, dword, dword*, void*);
FMT_FUNC bool write_console(std::FILE* f, string_view text) {
auto fd = _fileno(f);
if (!_isatty(fd)) return false;
FMT_FUNC bool write_console(int fd, string_view text) {
auto u16 = utf8_to_utf16(text);
auto written = dword();
return WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)), u16.c_str(),
static_cast<uint32_t>(u16.size()), &written, nullptr) != 0;
static_cast<dword>(u16.size()), nullptr, nullptr) != 0;
}
#endif
#ifdef _WIN32
// Print assuming legacy (non-Unicode) encoding.
FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args) {
auto buffer = memory_buffer();
detail::vformat_to(buffer, fmt,
basic_format_args<buffer_context<char>>(args));
fwrite_fully(buffer.data(), 1, buffer.size(), f);
detail::vformat_to(buffer, fmt, args);
fwrite_fully(buffer.data(), buffer.size(), f);
}
#endif
FMT_FUNC void print(std::FILE* f, string_view text) {
if (!write_console(f, text)) fwrite_fully(text.data(), 1, text.size(), f);
#ifdef _WIN32
int fd = _fileno(f);
if (_isatty(fd)) {
std::fflush(f);
if (write_console(fd, text)) return;
}
#endif
fwrite_fully(text.data(), text.size(), f);
}
} // namespace detail

File diff suppressed because it is too large Load Diff

View File

@ -13,12 +13,14 @@
#include <cstdio>
#include <system_error> // std::system_error
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
#if defined __APPLE__ || defined(__FreeBSD__)
# if FMT_HAS_INCLUDE(<xlocale.h>)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
# endif
#endif
#ifndef FMT_USE_FCNTL
// UWP doesn't provide _pipe.
# if FMT_HAS_INCLUDE("winapifamily.h")
@ -46,6 +48,7 @@
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_HAS_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) ::call
@ -114,7 +117,7 @@ template <typename Char> class basic_cstring_view {
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
/** Returns the pointer to a C string. */
const Char* c_str() const { return data_; }
auto c_str() const -> const Char* { return data_; }
};
using cstring_view = basic_cstring_view<char>;
@ -169,7 +172,7 @@ std::system_error windows_error(int error_code, string_view message,
// Can be used to report errors from destructors.
FMT_API void report_windows_error(int error_code, const char* message) noexcept;
#else
inline const std::error_category& system_category() noexcept {
inline auto system_category() noexcept -> const std::error_category& {
return std::system_category();
}
#endif // _WIN32
@ -206,7 +209,7 @@ class buffered_file {
other.file_ = nullptr;
}
buffered_file& operator=(buffered_file&& other) {
auto operator=(buffered_file&& other) -> buffered_file& {
close();
file_ = other.file_;
other.file_ = nullptr;
@ -220,9 +223,9 @@ class buffered_file {
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE* get() const noexcept { return file_; }
auto get() const noexcept -> FILE* { return file_; }
FMT_API int descriptor() const;
FMT_API auto descriptor() const -> int;
void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
@ -235,6 +238,7 @@ class buffered_file {
};
#if FMT_USE_FCNTL
// A file. Closed file is represented by a file object with descriptor -1.
// Methods that are not declared with noexcept may throw
// fmt::system_error in case of failure. Note that some errors such as
@ -248,6 +252,8 @@ class FMT_API file {
// Constructs a file object with a given descriptor.
explicit file(int fd) : fd_(fd) {}
friend struct pipe;
public:
// Possible values for the oflag argument to the constructor.
enum {
@ -272,7 +278,7 @@ class FMT_API file {
file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
// Move assignment is not noexcept because close may throw.
file& operator=(file&& other) {
auto operator=(file&& other) -> file& {
close();
fd_ = other.fd_;
other.fd_ = -1;
@ -283,24 +289,24 @@ class FMT_API file {
~file() noexcept;
// Returns the file descriptor.
int descriptor() const noexcept { return fd_; }
auto descriptor() const noexcept -> int { return fd_; }
// Closes the file.
void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
long long size() const;
auto size() const -> long long;
// Attempts to read count bytes from the file into the specified buffer.
size_t read(void* buffer, size_t count);
auto read(void* buffer, size_t count) -> size_t;
// Attempts to write count bytes from the specified buffer to the file.
size_t write(const void* buffer, size_t count);
auto write(const void* buffer, size_t count) -> size_t;
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
static file dup(int fd);
static auto dup(int fd) -> file;
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
@ -310,13 +316,9 @@ class FMT_API file {
// necessary.
void dup2(int fd, std::error_code& ec) noexcept;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
static void pipe(file& read_end, file& write_end);
// Creates a buffered_file object associated with this file and detaches
// this file object from the file.
buffered_file fdopen(const char* mode);
auto fdopen(const char* mode) -> buffered_file;
# if defined(_WIN32) && !defined(__MINGW32__)
// Opens a file and constructs a file object representing this file by
@ -325,15 +327,24 @@ class FMT_API file {
# endif
};
struct FMT_API pipe {
file read_end;
file write_end;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
pipe();
};
// Returns the memory page size.
long getpagesize();
auto getpagesize() -> long;
namespace detail {
struct buffer_size {
buffer_size() = default;
size_t value = 0;
buffer_size operator=(size_t val) const {
auto operator=(size_t val) const -> buffer_size {
auto bs = buffer_size();
bs.value = val;
return bs;
@ -366,9 +377,10 @@ struct ostream_params {
};
class file_buffer final : public buffer<char> {
private:
file file_;
FMT_API void grow(size_t) override;
FMT_API static void grow(buffer<char>& buf, size_t);
public:
FMT_API file_buffer(cstring_view path, const ostream_params& params);
@ -410,7 +422,7 @@ class FMT_API ostream {
void flush() { buffer_.flush(); }
template <typename... T>
friend ostream output_file(cstring_view path, T... params);
friend auto output_file(cstring_view path, T... params) -> ostream;
void close() { buffer_.close(); }
@ -419,7 +431,7 @@ class FMT_API ostream {
output to the file.
*/
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
vformat_to(detail::buffer_appender<char>(buffer_), fmt,
vformat_to(std::back_inserter(buffer_), fmt,
fmt::make_format_args(args...));
}
};
@ -440,7 +452,7 @@ class FMT_API ostream {
\endrst
*/
template <typename... T>
inline ostream output_file(cstring_view path, T... params) {
inline auto output_file(cstring_view path, T... params) -> ostream {
return {path, detail::ostream_params(params...)};
}
#endif // FMT_USE_FCNTL

View File

@ -10,19 +10,50 @@
#include <fstream> // std::filebuf
#if defined(_WIN32) && defined(__GLIBCXX__)
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
# include <__std_stream>
#ifdef _WIN32
# ifdef __GLIBCXX__
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
# endif
# include <io.h>
#endif
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Streambuf> class formatbuf : public Streambuf {
private:
using char_type = typename Streambuf::char_type;
using streamsize = decltype(std::declval<Streambuf>().sputn(nullptr, 0));
using int_type = typename Streambuf::int_type;
using traits_type = typename Streambuf::traits_type;
buffer<char_type>& buffer_;
public:
explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}
protected:
// The put area is always empty. This makes the implementation simpler and has
// the advantage that the streambuf and the buffer are always in sync and
// sputc never writes into uninitialized memory. A disadvantage is that each
// call to sputc always results in a (virtual) call to overflow. There is no
// disadvantage here for sputn since this always results in a call to xsputn.
auto overflow(int_type ch) -> int_type override {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<char_type>(ch));
return ch;
}
auto xsputn(const char_type* s, streamsize count) -> streamsize override {
buffer_.append(s, s + count);
return count;
}
};
// Generate a unique explicit instantion in every translation unit using a tag
// type in an anonymous namespace.
namespace {
@ -37,36 +68,40 @@ class file_access {
template class file_access<file_access_tag, std::filebuf,
&std::filebuf::_Myfile>;
auto get_file(std::filebuf&) -> FILE*;
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
template class file_access<file_access_tag, std::__stdoutbuf<char>,
&std::__stdoutbuf<char>::__file_>;
auto get_file(std::__stdoutbuf<char>&) -> FILE*;
#endif
inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) {
inline auto write_ostream_unicode(std::ostream& os, fmt::string_view data)
-> bool {
FILE* f = nullptr;
#if FMT_MSC_VERSION
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#elif defined(_WIN32) && defined(__GLIBCXX__)
auto* rdbuf = os.rdbuf();
FILE* c_file;
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
c_file = sfbuf->file();
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
c_file = fbuf->file();
f = get_file(*buf);
else
return false;
#elif defined(_WIN32) && defined(__GLIBCXX__)
auto* rdbuf = os.rdbuf();
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
f = sfbuf->file();
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
f = fbuf->file();
else
return false;
if (c_file) return write_console(c_file, data);
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
if (auto* buf = dynamic_cast<std::__stdoutbuf<char>*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#else
ignore_unused(os, data);
ignore_unused(os, data, f);
#endif
#ifdef _WIN32
if (f) {
int fd = _fileno(f);
if (_isatty(fd)) {
os.flush();
return write_console(fd, data);
}
}
#endif
return false;
}
inline bool write_ostream_unicode(std::wostream&,
fmt::basic_string_view<wchar_t>) {
inline auto write_ostream_unicode(std::wostream&,
fmt::basic_string_view<wchar_t>) -> bool {
return false;
}
@ -87,18 +122,19 @@ void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
}
template <typename Char, typename T>
void format_value(buffer<Char>& buf, const T& value,
locale_ref loc = locale_ref()) {
void format_value(buffer<Char>& buf, const T& value) {
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
auto&& output = std::basic_ostream<Char>(&format_buf);
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
if (loc) output.imbue(loc.get<std::locale>());
output.imbue(std::locale::classic()); // The default is always unlocalized.
#endif
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
}
template <typename T> struct streamed_view { const T& value; };
template <typename T> struct streamed_view {
const T& value;
};
} // namespace detail
@ -111,7 +147,7 @@ struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
-> OutputIt {
auto buffer = basic_memory_buffer<Char>();
detail::format_value(buffer, value, ctx.locale());
detail::format_value(buffer, value);
return formatter<basic_string_view<Char>, Char>::format(
{buffer.data(), buffer.size()}, ctx);
}
@ -140,7 +176,7 @@ struct formatter<detail::streamed_view<T>, Char>
\endrst
*/
template <typename T>
auto streamed(const T& value) -> detail::streamed_view<T> {
constexpr auto streamed(const T& value) -> detail::streamed_view<T> {
return {value};
}

View File

@ -16,13 +16,19 @@
FMT_BEGIN_NAMESPACE
FMT_BEGIN_EXPORT
template <typename T> struct printf_formatter { printf_formatter() = delete; };
template <typename T> struct printf_formatter {
printf_formatter() = delete;
};
template <typename Char> class basic_printf_context {
private:
detail::buffer_appender<Char> out_;
basic_format_args<basic_printf_context> args_;
static_assert(std::is_same<Char, char>::value ||
std::is_same<Char, wchar_t>::value,
"Unsupported code unit type.");
public:
using char_type = Char;
using parse_context_type = basic_format_parse_context<Char>;
@ -47,9 +53,7 @@ template <typename Char> class basic_printf_context {
return args_.get(id);
}
FMT_CONSTEXPR void on_error(const char* message) {
detail::error_handler().on_error(message);
}
void on_error(const char* message) { throw_format_error(message); }
};
namespace detail {
@ -102,7 +106,9 @@ struct is_zero_int {
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
template <> struct make_unsigned_or_bool<bool> {
using type = bool;
};
template <typename T, typename Context> class arg_converter {
private:
@ -157,7 +163,7 @@ template <typename T, typename Context> class arg_converter {
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_format_arg<Context>& arg, Char type) {
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
arg.visit(arg_converter<T, Context>(arg, type));
}
// Converts an integer argument to char for printf.
@ -360,8 +366,8 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
if (specs.width == -1) throw_format_error("number is too big");
} else if (*it == '*') {
++it;
specs.width = static_cast<int>(visit_format_arg(
detail::printf_width_handler<Char>(specs), get_arg(-1)));
specs.width = static_cast<int>(
get_arg(-1).visit(detail::printf_width_handler<Char>(specs)));
}
}
return arg_index;
@ -456,8 +462,8 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
specs.precision = parse_nonnegative_int(it, end, 0);
} else if (c == '*') {
++it;
specs.precision = static_cast<int>(
visit_format_arg(printf_precision_handler(), get_arg(-1)));
specs.precision =
static_cast<int>(get_arg(-1).visit(printf_precision_handler()));
} else {
specs.precision = 0;
}
@ -471,14 +477,14 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
specs.fill[0] = ' ';
}
if (specs.precision >= 0 && arg.type() == type::cstring_type) {
auto str = visit_format_arg(get_cstring<Char>(), arg);
auto str = arg.visit(get_cstring<Char>());
auto str_end = str + specs.precision;
auto nul = std::find(str, str_end, Char());
auto sv = basic_string_view<Char>(
str, to_unsigned(nul != str_end ? nul - str : specs.precision));
arg = make_arg<basic_printf_context<Char>>(sv);
}
if (specs.alt && visit_format_arg(is_zero_int(), arg)) specs.alt = false;
if (specs.alt && arg.visit(is_zero_int())) specs.alt = false;
if (specs.fill[0] == '0') {
if (arg.is_arithmetic() && specs.align != align::left)
specs.align = align::numeric;
@ -538,7 +544,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
type = 'd';
break;
case 'c':
visit_format_arg(char_converter<basic_printf_context<Char>>(arg), arg);
arg.visit(char_converter<basic_printf_context<Char>>(arg));
break;
}
}
@ -549,7 +555,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
start = it;
// Format argument.
visit_format_arg(printf_arg_formatter<Char>(out, specs, context), arg);
arg.visit(printf_arg_formatter<Char>(out, specs, context));
}
write(out, basic_string_view<Char>(start, to_unsigned(it - start)));
}

View File

@ -1,13 +1,9 @@
// Formatting library for C++ - experimental range support
// Formatting library for C++ - range and tuple support
//
// Copyright (c) 2012 - present, Victor Zverovich
// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
// All rights reserved.
//
// For the license information refer to format.h.
//
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
// All Rights Reserved
// {fmt} support for ranges, containers and types tuple interface.
#ifndef FMT_RANGES_H_
#define FMT_RANGES_H_
@ -187,7 +183,7 @@ template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
template <typename T, T... N> struct integer_sequence {
using value_type = T;
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
static FMT_CONSTEXPR auto size() -> size_t { return sizeof...(N); }
};
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
@ -211,15 +207,15 @@ class is_tuple_formattable_ {
};
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
template <std::size_t... Is>
static std::true_type check2(index_sequence<Is...>,
integer_sequence<bool, (Is == Is)...>);
static std::false_type check2(...);
static auto check2(index_sequence<Is...>,
integer_sequence<bool, (Is == Is)...>) -> std::true_type;
static auto check2(...) -> std::false_type;
template <std::size_t... Is>
static decltype(check2(
static auto check(index_sequence<Is...>) -> decltype(check2(
index_sequence<Is...>{},
integer_sequence<
bool, (is_formattable<typename std::tuple_element<Is, T>::type,
C>::value)...>{})) check(index_sequence<Is...>);
integer_sequence<bool,
(is_formattable<typename std::tuple_element<Is, T>::type,
C>::value)...>{}));
public:
static constexpr const bool value =
@ -421,6 +417,12 @@ struct is_formattable_delayed
#endif
} // namespace detail
template <typename...> struct conjunction : std::true_type {};
template <typename P> struct conjunction<P> : P {};
template <typename P1, typename... Pn>
struct conjunction<P1, Pn...>
: conditional_t<bool(P1::value), conjunction<Pn...>, P1> {};
template <typename T, typename Char, typename Enable = void>
struct range_formatter;
@ -486,7 +488,8 @@ struct range_formatter<
for (; it != end; ++it) {
if (i > 0) out = detail::copy_str<Char>(separator_, out);
ctx.advance_to(out);
out = underlying_.format(mapper.map(*it), ctx);
auto&& item = *it;
out = underlying_.format(mapper.map(item), ctx);
++i;
}
out = detail::copy_str<Char>(closing_bracket_, out);
@ -571,6 +574,83 @@ struct formatter<
Char> {
};
template <typename It, typename Sentinel, typename Char = char>
struct join_view : detail::view {
It begin;
Sentinel end;
basic_string_view<Char> sep;
join_view(It b, Sentinel e, basic_string_view<Char> s)
: begin(b), end(e), sep(s) {}
};
template <typename It, typename Sentinel, typename Char>
struct formatter<join_view<It, Sentinel, Char>, Char> {
private:
using value_type =
#ifdef __cpp_lib_ranges
std::iter_value_t<It>;
#else
typename std::iterator_traits<It>::value_type;
#endif
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
public:
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
return value_formatter_.parse(ctx);
}
template <typename FormatContext>
auto format(const join_view<It, Sentinel, Char>& value,
FormatContext& ctx) const -> decltype(ctx.out()) {
auto it = value.begin;
auto out = ctx.out();
if (it != value.end) {
out = value_formatter_.format(*it, ctx);
++it;
while (it != value.end) {
out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
ctx.advance_to(out);
out = value_formatter_.format(*it, ctx);
++it;
}
}
return out;
}
};
/**
Returns a view that formats the iterator range `[begin, end)` with elements
separated by `sep`.
*/
template <typename It, typename Sentinel>
auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
return {begin, end, sep};
}
/**
\rst
Returns a view that formats `range` with elements separated by `sep`.
**Example**::
std::vector<int> v = {1, 2, 3};
fmt::print("{}", fmt::join(v, ", "));
// Output: "1, 2, 3"
``fmt::join`` applies passed format specifiers to the range elements::
fmt::print("{:02}", fmt::join(v, ", "));
// Output: "01, 02, 03"
\endrst
*/
template <typename Range>
auto join(Range&& range, string_view sep)
-> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>> {
return join(std::begin(range), std::end(range), sep);
}
template <typename Char, typename... T> struct tuple_join_view : detail::view {
const std::tuple<T...>& tuple;
basic_string_view<Char> sep;
@ -705,13 +785,6 @@ FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
return {tuple, sep};
}
template <typename... T>
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple,
basic_string_view<wchar_t> sep)
-> tuple_join_view<wchar_t, T...> {
return {tuple, sep};
}
/**
\rst
Returns an object that formats `initializer_list` with elements separated by

View File

@ -38,6 +38,10 @@
# endif
#endif
#if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)
# include <source_location>
#endif
// GCC 4 does not support FMT_HAS_INCLUDE.
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
# include <cxxabi.h>
@ -59,43 +63,53 @@
# endif
#endif
#ifdef __cpp_lib_filesystem
// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
#ifndef FMT_CPP_LIB_FILESYSTEM
# ifdef __cpp_lib_filesystem
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
# else
# define FMT_CPP_LIB_FILESYSTEM 0
# endif
#endif
#ifndef FMT_CPP_LIB_VARIANT
# ifdef __cpp_lib_variant
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
# else
# define FMT_CPP_LIB_VARIANT 0
# endif
#endif
#if FMT_CPP_LIB_FILESYSTEM
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char> auto get_path_string(const std::filesystem::path& p) {
return p.string<Char>();
template <typename Char, typename PathChar>
auto get_path_string(const std::filesystem::path& p,
const std::basic_string<PathChar>& native) {
if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);
else
return p.string<Char>();
}
template <typename Char>
template <typename Char, typename PathChar>
void write_escaped_path(basic_memory_buffer<Char>& quoted,
const std::filesystem::path& p) {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}
# ifdef _WIN32
template <>
inline auto get_path_string<char>(const std::filesystem::path& p) {
return to_utf8<wchar_t>(p.native(), to_utf8_error_policy::replace);
}
template <>
inline void write_escaped_path<char>(memory_buffer& quoted,
const std::filesystem::path& p) {
auto buf = basic_memory_buffer<wchar_t>();
write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
FMT_ASSERT(valid, "invalid utf16");
}
# endif // _WIN32
template <>
inline void write_escaped_path<std::filesystem::path::value_type>(
basic_memory_buffer<std::filesystem::path::value_type>& quoted,
const std::filesystem::path& p) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), p.native());
const std::filesystem::path& p,
const std::basic_string<PathChar>& native) {
if constexpr (std::is_same_v<Char, char> &&
std::is_same_v<PathChar, wchar_t>) {
auto buf = basic_memory_buffer<wchar_t>();
write_escaped_string<wchar_t>(std::back_inserter(buf), native);
bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
FMT_ASSERT(valid, "invalid utf16");
} else if constexpr (std::is_same_v<Char, PathChar>) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), native);
} else {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}
}
} // namespace detail
@ -106,6 +120,7 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
format_specs<Char> specs_;
detail::arg_ref<Char> width_ref_;
bool debug_ = false;
char path_type_ = 0;
public:
FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
@ -122,29 +137,62 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
debug_ = true;
++it;
}
if (it != end && (*it == 'g')) path_type_ = *it++;
return it;
}
template <typename FormatContext>
auto format(const std::filesystem::path& p, FormatContext& ctx) const {
auto specs = specs_;
# ifdef _WIN32
auto path_string = !path_type_ ? p.native() : p.generic_wstring();
# else
auto path_string = !path_type_ ? p.native() : p.generic_string();
# endif
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
if (!debug_) {
auto s = detail::get_path_string<Char>(p);
auto s = detail::get_path_string<Char>(p, path_string);
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
}
auto quoted = basic_memory_buffer<Char>();
detail::write_escaped_path(quoted, p);
detail::write_escaped_path(quoted, p, path_string);
return detail::write(ctx.out(),
basic_string_view<Char>(quoted.data(), quoted.size()),
specs);
}
};
FMT_END_NAMESPACE
#endif
#endif // FMT_CPP_LIB_FILESYSTEM
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <std::size_t N, typename Char>
struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
private:
// Functor because C++11 doesn't support generic lambdas.
struct writer {
const std::bitset<N>& bs;
template <typename OutputIt>
FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {
for (auto pos = N; pos > 0; --pos) {
out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));
}
return out;
}
};
public:
template <typename FormatContext>
auto format(const std::bitset<N>& bs, FormatContext& ctx) const
-> decltype(ctx.out()) {
return write_padded(ctx, writer{bs});
}
};
FMT_EXPORT
template <typename Char>
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
@ -180,7 +228,7 @@ struct formatter<std::optional<T>, Char,
}
template <typename FormatContext>
auto format(std::optional<T> const& opt, FormatContext& ctx) const
auto format(const std::optional<T>& opt, FormatContext& ctx) const
-> decltype(ctx.out()) {
if (!opt) return detail::write<Char>(ctx.out(), none);
@ -194,7 +242,32 @@ struct formatter<std::optional<T>, Char,
FMT_END_NAMESPACE
#endif // __cpp_lib_optional
#ifdef __cpp_lib_variant
#ifdef __cpp_lib_source_location
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <> struct formatter<std::source_location> {
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const std::source_location& loc, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write(out, loc.file_name());
out = detail::write(out, ':');
out = detail::write<char>(out, loc.line());
out = detail::write(out, ':');
out = detail::write<char>(out, loc.column());
out = detail::write(out, ": ");
out = detail::write(out, loc.function_name());
return out;
}
};
FMT_END_NAMESPACE
#endif
#if FMT_CPP_LIB_VARIANT
FMT_BEGIN_NAMESPACE
namespace detail {
@ -285,7 +358,7 @@ struct formatter<
}
};
FMT_END_NAMESPACE
#endif // __cpp_lib_variant
#endif // FMT_CPP_LIB_VARIANT
FMT_BEGIN_NAMESPACE
FMT_EXPORT
@ -309,7 +382,7 @@ template <typename Char> struct formatter<std::error_code, Char> {
FMT_EXPORT
template <typename T, typename Char>
struct formatter<
T, Char,
T, Char, // DEPRECATED! Mixing code unit types.
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
private:
bool with_typename_ = false;
@ -340,7 +413,7 @@ struct formatter<
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
int status = 0;
std::size_t size = 0;
std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
string_view demangled_name_view;
@ -451,15 +524,14 @@ struct formatter<std::atomic<T>, Char,
#ifdef __cpp_lib_atomic_flag_test
FMT_EXPORT
template <typename Char>
struct formatter<std::atomic_flag, Char>
: formatter<bool, Char> {
struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
template <typename FormatContext>
auto format(const std::atomic_flag& v, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<bool, Char>::format(v.test(), ctx);
}
};
#endif // __cpp_lib_atomic_flag_test
#endif // __cpp_lib_atomic_flag_test
FMT_END_NAMESPACE
#endif // FMT_STD_H_

View File

@ -11,6 +11,7 @@
#include <cwchar>
#include "format.h"
#include "ranges.h"
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
# include <locale>
@ -22,7 +23,7 @@ namespace detail {
template <typename T>
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
inline auto write_loc(back_insert_iterator<detail::buffer<wchar_t>> out,
loc_value value, const format_specs<wchar_t>& specs,
locale_ref loc) -> bool {
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
@ -63,14 +64,15 @@ template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {};
template <typename... T>
constexpr format_arg_store<wformat_context, T...> make_wformat_args(
const T&... args) {
constexpr auto make_wformat_args(const T&... args)
-> format_arg_store<wformat_context, T...> {
return {args...};
}
inline namespace literals {
#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
constexpr detail::udl_arg<wchar_t> operator"" _a(const wchar_t* s, size_t) {
constexpr auto operator""_a(const wchar_t* s, size_t)
-> detail::udl_arg<wchar_t> {
return {s};
}
#endif
@ -95,6 +97,12 @@ auto join(std::initializer_list<T> list, wstring_view sep)
return join(std::begin(list), std::end(list), sep);
}
template <typename... T>
auto join(const std::tuple<T...>& tuple, basic_string_view<wchar_t> sep)
-> tuple_join_view<wchar_t, T...> {
return {tuple, sep};
}
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
auto vformat(basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
@ -172,11 +180,11 @@ inline auto vformat_to(
return detail::get_iterator(buf, out);
}
template <
typename OutputIt, typename Locale, typename S, typename... T,
typename Char = char_t<S>,
bool enable = detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_locale<Locale>::value&& detail::is_exotic_char<Char>::value>
template <typename OutputIt, typename Locale, typename S, typename... T,
typename Char = char_t<S>,
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
detail::is_locale<Locale>::value &&
detail::is_exotic_char<Char>::value>
inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
T&&... args) ->
typename std::enable_if<enable, OutputIt>::type {

View File

@ -19,8 +19,8 @@
# include <sys/stat.h>
# include <sys/types.h>
# ifdef _WRS_KERNEL // VxWorks7 kernel
# include <ioLib.h> // getpagesize
# ifdef _WRS_KERNEL // VxWorks7 kernel
# include <ioLib.h> // getpagesize
# endif
# ifndef _WIN32
@ -183,10 +183,14 @@ void buffered_file::close() {
}
int buffered_file::descriptor() const {
#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
int fd = fileno(file_);
#else
#if !defined(fileno)
int fd = FMT_POSIX_CALL(fileno(file_));
#elif defined(FMT_HAS_SYSTEM)
// fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
# define FMT_DISABLE_MACRO
int fd = FMT_SYSTEM(fileno FMT_DISABLE_MACRO(file_));
#else
int fd = fileno(file_);
#endif
if (fd == -1)
FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
@ -197,6 +201,7 @@ int buffered_file::descriptor() const {
# ifdef _WIN32
using mode_t = int;
# endif
constexpr mode_t default_open_mode =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
@ -298,29 +303,6 @@ void file::dup2(int fd, std::error_code& ec) noexcept {
if (result == -1) ec = std::error_code(errno, std::generic_category());
}
void file::pipe(file& read_end, file& write_end) {
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end.close();
write_end.close();
int fds[2] = {};
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
# endif
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
// The following assignments don't throw because read_fd and write_fd
// are closed.
read_end = file(fds[0]);
write_end = file(fds[1]);
}
buffered_file file::fdopen(const char* mode) {
// Don't retry as fdopen doesn't return EINTR.
# if defined(__MINGW32__) && defined(_POSIX_)
@ -349,6 +331,24 @@ file file::open_windows_file(wcstring_view path, int oflag) {
}
# endif
pipe::pipe() {
int fds[2] = {};
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
# endif
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
// The following assignments don't throw.
read_end = file(fds[0]);
write_end = file(fds[1]);
}
# if !defined(__MSDOS__)
long getpagesize() {
# ifdef _WIN32
@ -371,18 +371,17 @@ long getpagesize() {
namespace detail {
void file_buffer::grow(size_t) {
if (this->size() == this->capacity()) flush();
void file_buffer::grow(buffer<char>& buf, size_t) {
if (buf.size() == buf.capacity()) static_cast<file_buffer&>(buf).flush();
}
file_buffer::file_buffer(cstring_view path,
const detail::ostream_params& params)
: file_(path, params.oflag) {
file_buffer::file_buffer(cstring_view path, const ostream_params& params)
: buffer<char>(grow), file_(path, params.oflag) {
set(new char[params.buffer_size], params.buffer_size);
}
file_buffer::file_buffer(file_buffer&& other)
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
: buffer<char>(grow, other.data(), other.size(), other.capacity()),
file_(std::move(other.file_)) {
other.clear();
other.set(nullptr, 0);

View File

@ -41,15 +41,16 @@ using namespace LAMMPS_NS;
Molecule::Molecule(LAMMPS *lmp, int narg, char **arg, int &index) :
Pointers(lmp), id(nullptr), x(nullptr), type(nullptr), molecule(nullptr), q(nullptr),
radius(nullptr), rmass(nullptr), num_bond(nullptr), bond_type(nullptr), bond_atom(nullptr),
num_angle(nullptr), angle_type(nullptr), angle_atom1(nullptr), angle_atom2(nullptr),
angle_atom3(nullptr), num_dihedral(nullptr), dihedral_type(nullptr), dihedral_atom1(nullptr),
dihedral_atom2(nullptr), dihedral_atom3(nullptr), dihedral_atom4(nullptr),
num_improper(nullptr), improper_type(nullptr), improper_atom1(nullptr), improper_atom2(nullptr),
improper_atom3(nullptr), improper_atom4(nullptr), nspecial(nullptr), special(nullptr),
shake_flag(nullptr), shake_atom(nullptr), shake_type(nullptr), avec_body(nullptr),
ibodyparams(nullptr), dbodyparams(nullptr), fragmentmask(nullptr), dx(nullptr), dxcom(nullptr),
dxbody(nullptr), quat_external(nullptr), fp(nullptr), count(nullptr)
radius(nullptr), rmass(nullptr), mu(nullptr), num_bond(nullptr), bond_type(nullptr),
bond_atom(nullptr), num_angle(nullptr), angle_type(nullptr), angle_atom1(nullptr),
angle_atom2(nullptr), angle_atom3(nullptr), num_dihedral(nullptr), dihedral_type(nullptr),
dihedral_atom1(nullptr), dihedral_atom2(nullptr), dihedral_atom3(nullptr),
dihedral_atom4(nullptr), num_improper(nullptr), improper_type(nullptr), improper_atom1(nullptr),
improper_atom2(nullptr), improper_atom3(nullptr), improper_atom4(nullptr), nspecial(nullptr),
special(nullptr), shake_flag(nullptr), shake_atom(nullptr), shake_type(nullptr),
avec_body(nullptr), ibodyparams(nullptr), dbodyparams(nullptr), fragmentmask(nullptr),
dx(nullptr), dxcom(nullptr), dxbody(nullptr), quat_external(nullptr), fp(nullptr),
count(nullptr)
{
me = comm->me;
@ -132,7 +133,7 @@ Molecule::Molecule(LAMMPS *lmp, int narg, char **arg, int &index) :
// initialize all fields to empty
initialize();
Molecule::initialize();
// scan file for sizes of all fields and allocate storage for them
@ -141,28 +142,30 @@ Molecule::Molecule(LAMMPS *lmp, int narg, char **arg, int &index) :
if (fp == nullptr)
error->one(FLERR, "Cannot open molecule file {}: {}", arg[ifile], utils::getsyserror());
}
read(0);
Molecule::read(0);
if (me == 0) fclose(fp);
allocate();
Molecule::allocate();
// read file again to populate all fields
if (me == 0) fp = fopen(arg[ifile], "r");
read(1);
Molecule::read(1);
if (me == 0) fclose(fp);
// stats
if (title.empty()) title = "(no title)";
if (me == 0)
utils::logmesg(lmp,
"Read molecule template {}:\n {} molecules\n"
"Read molecule template {}:\n{}\n"
" {} molecules\n"
" {} fragments\n"
" {} atoms with max type {}\n"
" {} bonds with max type {}\n"
" {} angles with max type {}\n"
" {} dihedrals with max type {}\n"
" {} impropers with max type {}\n",
id, nmolecules, nfragments, natoms, ntypes, nbonds, nbondtypes, nangles,
id, title, nmolecules, nfragments, natoms, ntypes, nbonds, nbondtypes, nangles,
nangletypes, ndihedrals, ndihedraltypes, nimpropers, nimpropertypes);
}
@ -423,6 +426,8 @@ void Molecule::read(int flag)
if (eof == nullptr) error->one(FLERR, "Unexpected end of molecule file");
}
if (flag == 0) title = utils::trim(line);
// read header lines
// skip blank lines or lines that start with "#"
// stop when read an unrecognized line
@ -572,6 +577,12 @@ void Molecule::read(int flag)
diameters(line);
else
skip_lines(natoms, line, keyword);
} else if (keyword == "Dipoles") {
muflag = 1;
if (flag)
dipoles(line);
else
skip_lines(natoms, line, keyword);
} else if (keyword == "Masses") {
rmassflag = 1;
if (flag)
@ -948,6 +959,40 @@ void Molecule::diameters(char *line)
}
}
/* ----------------------------------------------------------------------
read charges from file
------------------------------------------------------------------------- */
void Molecule::dipoles(char *line)
{
for (int i = 0; i < natoms; i++) count[i] = 0;
try {
for (int i = 0; i < natoms; i++) {
readline(line);
ValueTokenizer values(utils::trim_comment(line));
if ((int) values.count() != 4)
error->all(FLERR, "Invalid line in Dipoles section of molecule file: {}", line);
int iatom = values.next_int() - 1;
if (iatom < 0 || iatom >= natoms)
error->all(FLERR, "Invalid atom index in Dipoles section of molecule file");
count[iatom]++;
mu[iatom][0] = values.next_double();
mu[iatom][1] = values.next_double();
mu[iatom][2] = values.next_double();
}
} catch (TokenizerException &e) {
error->all(FLERR, "Invalid line in Dipoles section of molecule file: {}\n{}", e.what(), line);
}
for (int i = 0; i < natoms; i++) {
if (count[i] == 0)
error->all(FLERR, "Atom {} missing in Dipoles section of molecule file", i + 1);
}
}
/* ----------------------------------------------------------------------
read masses from file
------------------------------------------------------------------------- */
@ -1828,6 +1873,7 @@ void Molecule::check_attributes()
int mismatch = 0;
if (qflag && !atom->q_flag) mismatch = 1;
if (muflag && !atom->mu_flag) mismatch = 1;
if (radiusflag && !atom->radius_flag) mismatch = 1;
if (rmassflag && !atom->rmass_flag) mismatch = 1;
@ -1869,6 +1915,7 @@ void Molecule::check_attributes()
void Molecule::initialize()
{
title.clear();
natoms = 0;
nbonds = nangles = ndihedrals = nimpropers = 0;
ntypes = 0;
@ -1880,7 +1927,7 @@ void Molecule::initialize()
bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
maxspecial = 0;
xflag = typeflag = moleculeflag = fragmentflag = qflag = radiusflag = rmassflag = 0;
xflag = typeflag = moleculeflag = fragmentflag = qflag = radiusflag = muflag = rmassflag = 0;
bondflag = angleflag = dihedralflag = improperflag = 0;
nspecialflag = specialflag = 0;
shakeflag = shakeflagflag = shakeatomflag = shaketypeflag = 0;
@ -1943,6 +1990,7 @@ void Molecule::allocate()
for (int j = 0; j < natoms; j++) fragmentmask[i][j] = 0;
}
if (qflag) memory->create(q, natoms, "molecule:q");
if (muflag) memory->create(mu, natoms, 3, "molecule:mu");
if (radiusflag) memory->create(radius, natoms, "molecule:radius");
if (rmassflag) memory->create(rmass, natoms, "molecule:rmass");
@ -2167,6 +2215,11 @@ void Molecule::print()
for (int i = 0; i < natoms; i++)
printf(" %d %g\n",i+1,radius[i]);
}
if (muflag) {
printf( "Dipoles:\n");
for (int i = 0; i < natoms; i++)
printf(" %d %g %g %g\n",i+1,mu[i][0],mu[i][1],mu[i][2]);
}
if (rmassflag) {
printf( "Masses:\n");
for (int i = 0; i < natoms; i++)

View File

@ -25,6 +25,8 @@ class Molecule : protected Pointers {
// else 0 if not first in set
int last; // 1 if last molecule in set, else 0
std::string title; // title string of the molecule file
// number of atoms,bonds,etc in molecule
// nibody,ndbody = # of integer/double fields in body
@ -41,7 +43,7 @@ class Molecule : protected Pointers {
// 1 if attribute defined in file, 0 if not
int xflag, typeflag, moleculeflag, fragmentflag, qflag, radiusflag, rmassflag;
int xflag, typeflag, moleculeflag, fragmentflag, qflag, radiusflag, muflag, rmassflag;
int bondflag, angleflag, dihedralflag, improperflag;
int nspecialflag, specialflag;
int shakeflag, shakeflagflag, shakeatomflag, shaketypeflag;
@ -63,6 +65,7 @@ class Molecule : protected Pointers {
double *q; // charge on each atom
double *radius; // radius of each atom
double *rmass; // mass of each atom
double **mu; // dipole vector of each atom
int *num_bond; // bonds, angles, dihedrals, impropers for each atom
int **bond_type;
@ -142,6 +145,7 @@ class Molecule : protected Pointers {
void fragments(char *);
void charges(char *);
void diameters(char *);
void dipoles(char *);
void masses(char *);
void bonds(int, char *);
void angles(int, char *);

View File

@ -1,6 +1,6 @@
---
lammps_version: 8 Apr 2021
date_generated: Thu Apr 8 09:28:11 2021
lammps_version: 21 Nov 2023
date_generated: Fri Jan 12 18:39:55 2024
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -10,77 +10,77 @@ post_commands: ! ""
input_file: in.fourmol
angle_style: cosine/periodic
angle_coeff: ! |
1 75.0 1 2
2 45.0 -1 2
1 75.0 1 1
2 45.0 1 2
3 50.0 -1 3
4 100.0 -1 4
equilibrium: 4 3.141592653589793 1.5707963267948966 2.0943951023931957 2.356194490192345
equilibrium: 4 3.141592653589793 3.141592653589793 2.0943951023931957 2.356194490192345
extract: ! ""
natoms: 29
init_energy: 605.3643061001458
init_stress: ! |-
-1.7082420754402889e+01 -7.3281097507808681e+00 2.4410530505183818e+01 8.5827033671406951e+01 1.4260977966148616e+02 4.1579557432232576e+01
init_energy: 1178.5476942873006
init_stress: ! |2-
2.7790958427902001e+02 -2.3729473006795436e+02 -4.0614854211065634e+01 2.9034222204142930e+02 1.4123449070173780e+02 2.0504975338277421e+02
init_forces: ! |2
1 7.9609486050127529e+00 -3.9274211736421961e+01 -3.8917410871887981e+01
2 4.6997439470662350e+00 3.8052682089524090e+01 3.0599010994189470e+01
3 -7.1532072701475698e+01 9.6873528247272844e+01 7.3410935137796983e+01
4 3.1784763224659116e+01 -4.4133218046130608e+01 -6.2234613362865147e+01
5 5.8817481848549889e+01 -2.5112568523390145e+01 3.9611729278121981e+00
6 -8.7258065964885336e+00 -4.2663580774228997e+01 -1.6819642012415606e+01
3 -4.4330179925982058e+01 -1.6514501437366098e+00 1.9894582317318523e+01
4 1.1465928779203908e+01 -7.1462736556935234e+00 -1.8983545733370338e+01
5 2.7634466780141157e+01 1.5504150132065057e+01 1.0078115065618357e+01
6 2.2512674572611367e+01 -5.4260358088923418e+01 -6.0646506351853276e+01
7 -1.5578858996464229e+01 1.3895348629116569e+01 -3.3939856789628062e+00
8 -1.6678237064738614e+01 -2.6557373913973738e+01 8.7708427797183326e+00
9 -9.4419020144376677e+00 1.3812152922900303e+01 -1.2280697239365450e+00
10 1.0844630504236606e+02 1.9274264686364820e+01 1.2594098114786526e+01
11 -1.1888648487599809e+01 1.7288532453781471e+00 1.8714004234488471e+00
12 9.7432958614920665e+01 1.1284647087939499e+02 -1.3445218835244805e+02
13 -2.2887258478933525e+01 -5.9815335453575649e+01 4.1237962971772127e+01
14 -4.6498844054867675e+01 -3.0251289808967520e+01 1.5556535565006259e+01
15 -5.3477741242848616e+01 -1.7885978453267143e+01 4.6284681424489207e+01
16 -7.3215663693592745e+01 1.7514552522777997e+01 7.4857846653898914e+00
8 -6.7011983808365656e+01 -2.4458090084467077e+01 1.7084632474743671e+02
9 9.4419020144376677e+00 -1.3812152922900303e+01 1.2280697239365450e+00
10 1.3360859023844577e+02 1.1499274633292617e+02 -1.0838863098947982e+02
11 1.1888648487599809e+01 -1.7288532453781471e+00 -1.8714004234488471e+00
12 2.9260930345940537e+01 -9.2146025429432186e+00 -8.5323421000107373e+01
13 -4.6656310032990458e+00 -1.2502935413462930e+01 1.4918864440944628e+01
14 -2.1383527724886850e+01 -9.3422692044635554e+00 7.5125645645164223e+00
15 -8.0644375221897171e+00 -2.6783296801963008e+00 6.9267625241565547e+00
16 -1.1822204683814408e+02 2.1928896047729104e+01 4.0247121672886962e+01
17 2.0782832048872386e+01 -2.8304296512773977e+01 1.5273484998106287e+01
18 1.6481336531704756e+00 1.7222946144801426e+01 -6.9896289164966490e+01
19 -2.0180190840279820e+01 -2.5140421523544326e+01 2.9933594625645306e+01
20 1.8532057187109345e+01 7.9174753787429015e+00 3.9962694539321184e+01
21 1.6243294930835876e+01 2.0333921382774719e+01 -6.0768622624445221e+01
22 -2.8924589352090472e+01 -1.9720769613680826e+01 2.1482552755004811e+01
23 1.2681294421254595e+01 -6.1315176909389102e-01 3.9286069869440411e+01
24 -1.5837796600466618e+01 6.1562453937228881e+01 -3.6651923703785549e+01
25 -1.2704181131223443e+01 -4.2563815285902912e+01 6.9610494863238124e+00
26 2.8541977731690061e+01 -1.8998638651325965e+01 2.9690874217461737e+01
27 -8.7971258084923178e+00 7.2217511410368814e+01 -2.4599681382405976e+01
28 -1.9235439225569891e+01 -4.3179911322776611e+01 1.0030656861974458e+00
29 2.8032565034062209e+01 -2.9037600087592210e+01 2.3596615696208531e+01
run_energy: 603.8182365368202
run_stress: ! |-
-1.6098625319219664e+01 -7.7961962067566510e+00 2.3894821525976329e+01 8.7036156470651477e+01 1.4262918929621054e+02 4.2523803236880880e+01
18 5.2071052608093424e+00 5.4414090328604708e+01 -2.2082998810309599e+02
19 -6.3757194500832497e+01 -7.9428522633699004e+01 9.4572049876109048e+01
20 5.8550089240023155e+01 2.5014432305094296e+01 1.2625793822698694e+02
21 5.6300281919954635e+01 7.0478650499360143e+01 -2.1062786831190908e+02
22 -1.0025444602684506e+02 -6.8353427900946826e+01 7.4459879083463136e+01
23 4.3954164106890424e+01 -2.1252225984133197e+00 1.3616798922844595e+02
24 -4.9480288140032329e+01 1.9233281221276744e+02 -1.1450757902121047e+02
25 -3.9690277556511717e+01 -1.3297745247110566e+02 2.1747642240220362e+01
26 8.9170565696544045e+01 -5.9355359741661772e+01 9.2759936780990117e+01
27 -2.6339504856062320e+01 2.1622670107205670e+02 -7.3653991239272059e+01
28 -5.7592895215991106e+01 -1.2928512206483205e+02 3.0032824456190355e+00
29 8.3932400072053426e+01 -8.6941579007224647e+01 7.0650708793653024e+01
run_energy: 1174.6225600630123
run_stress: ! |2-
2.7658169122411005e+02 -2.3743377487623573e+02 -3.9147916347874407e+01 2.9007767114801470e+02 1.4053974438881829e+02 2.0434258995590761e+02
run_forces: ! |2
1 8.1036664069391833e+00 -3.9279459516104339e+01 -3.8959949625007155e+01
2 4.6488532958171156e+00 3.7987813821226069e+01 3.0712083303318757e+01
3 -7.1419656269516480e+01 9.7015207052323333e+01 7.3123837986656483e+01
4 3.1774739774255771e+01 -4.4324760214341296e+01 -6.1918121921961003e+01
5 5.8630133295649813e+01 -2.5003101567718115e+01 3.8957656941403842e+00
6 -8.6686835699933500e+00 -4.2717543793109854e+01 -1.6944132920021204e+01
7 -1.5605967450730276e+01 1.3924972058096937e+01 -3.4081311693274161e+00
8 -1.6735469954990947e+01 -2.6654949908594496e+01 8.9412902423392993e+00
9 -9.4705763934675620e+00 1.3861186924074314e+01 -1.2218212802251793e+00
10 1.0864309846473817e+02 1.9311615651482960e+01 1.2534898619395602e+01
11 -1.1889594908454491e+01 1.6849924892427488e+00 1.9039966312260486e+00
12 9.6643785665770423e+01 1.1329932305772147e+02 -1.3435213826206018e+02
13 -2.2815824864999897e+01 -5.9701629573330088e+01 4.1148977584672039e+01
14 -4.6226658006998740e+01 -3.0469540424436548e+01 1.5534272011399247e+01
15 -5.3141801628038777e+01 -1.8156497866651446e+01 4.6272398149175629e+01
16 -7.3254211788300807e+01 1.7569251761827239e+01 7.4522974142679850e+00
17 2.0784167932320894e+01 -2.8346879951708846e+01 1.5284477542010659e+01
18 1.7456021018344252e+00 1.7528557172698406e+01 -7.0852460721917453e+01
19 -2.0389936120749365e+01 -2.5462340563923114e+01 3.0421727677614534e+01
20 1.8644334018914940e+01 7.9337833912247095e+00 4.0430733044302912e+01
21 1.6517268317097550e+01 2.0531536618559141e+01 -6.1717967915716365e+01
22 -2.9293957935776255e+01 -1.9905577364456363e+01 2.1870035659045151e+01
23 1.2776689618678706e+01 -6.2595925410277875e-01 3.9847932256671214e+01
24 -1.6067082221526842e+01 6.2373469754139357e+01 -3.7096821397423525e+01
25 -1.2753486814048248e+01 -4.3101082367336026e+01 7.0662489242667057e+00
26 2.8820569035575090e+01 -1.9272387386803331e+01 3.0030572473156820e+01
27 -8.9233162938210242e+00 7.2669056612963558e+01 -2.4610439704365813e+01
28 -1.9256705992379011e+01 -4.3442840232212284e+01 9.5666525994413210e-01
29 2.8180022286200035e+01 -2.9226216380751275e+01 2.3653774444421682e+01
1 8.0595702750384035e+00 -3.9275884134753326e+01 -3.8921834417294036e+01
2 4.6450877605699539e+00 3.7989319483282912e+01 3.0709930248716290e+01
3 -4.4176357886610745e+01 -1.3121510542286003e+00 1.9849684676752698e+01
4 1.1432955202502885e+01 -7.3978491141098957e+00 -1.8963452056001909e+01
5 2.7565769767176914e+01 1.5533965780817836e+01 1.0064393045239932e+01
6 2.2440837721485856e+01 -5.4307979505823312e+01 -6.0734450726614625e+01
7 -1.5580688823052480e+01 1.3904189059068386e+01 -3.4017896378595758e+00
8 -6.6989876135866879e+01 -2.4455457095150752e+01 1.7071695622632274e+02
9 9.4762227087055635e+00 -1.3904425552883753e+01 1.2252549039361496e+00
10 1.3329492642527092e+02 1.1514887273699682e+02 -1.0807688660290995e+02
11 1.1927511834955308e+01 -1.7182396158290132e+00 -1.8914765821083073e+00
12 2.9230443011207992e+01 -9.0747074093425084e+00 -8.5406656692466896e+01
13 -4.6010476121847610e+00 -1.2371262892106342e+01 1.4758380429325644e+01
14 -2.1309655373546295e+01 -9.6560166053345498e+00 7.4826455796077642e+00
15 -8.0586553706859778e+00 -2.8089895416921884e+00 7.1963114045665719e+00
16 -1.1814487049351524e+02 2.2070805476502699e+01 4.0103979455896329e+01
17 2.0787826988548556e+01 -2.8364190015414366e+01 1.5289010744891176e+01
18 5.4411962659043454e+00 5.4597888596162299e+01 -2.2067472725627243e+02
19 -6.3374090856904559e+01 -7.9190934240040519e+01 9.4782037192716302e+01
20 5.7932894591000213e+01 2.4593045643878220e+01 1.2589269006355613e+02
21 5.6478944470524624e+01 7.0203094061683373e+01 -2.1102883364979709e+02
22 -9.9996788696603545e+01 -6.7985401318866863e+01 7.4849357252797518e+01
23 4.3517844226078921e+01 -2.2176927428165065e+00 1.3617947639699958e+02
24 -4.9663522759553963e+01 1.9280842870258854e+02 -1.1467096111871800e+02
25 -3.9280982289108742e+01 -1.3314956089589265e+02 2.1920816048609726e+01
26 8.8944505048662705e+01 -5.9658867806695888e+01 9.2750145070108275e+01
27 -2.6592186096443989e+01 2.1652356998534560e+02 -7.3330722990707770e+01
28 -5.7218787679563256e+01 -1.2939713888992102e+02 2.9266537226802889e+00
29 8.3810973776007245e+01 -8.7126431095424564e+01 7.0404069268027484e+01
...

View File

@ -9,7 +9,7 @@ prerequisites: ! |
pre_commands: ! ""
post_commands: ! ""
input_file: in.fourmol
angle_style: lepton
angle_style: lepton auto_offset
angle_coeff: ! |
1 110.1 "k*theta^2; k=75.0"
2 111.0 "k*theta^2; k=45.0"

View File

@ -0,0 +1,88 @@
---
lammps_version: 22 Dec 2022
date_generated: Fri Dec 23 15:10:29 2022
epsilon: 7.5e-13
skip_tests:
prerequisites: ! |
atom full
angle lepton
pre_commands: ! ""
post_commands: ! ""
input_file: in.fourmol
angle_style: lepton no_offset
angle_coeff: ! |
1 110.1 "k*theta^2; k=75.0"
2 111.0 "k*theta^2; k=45.0"
3 120.0 "k*theta^2; k=50.0"
4 108.5 "k*theta^2; k=100.0"
equilibrium: 4 1.9216075064457567 1.9373154697137058 2.0943951023931953 1.8936822384138476
extract: ! |
theta0 1
natoms: 29
init_energy: 41.53081789649104
init_stress: ! |2-
8.9723357320869297e+01 -8.7188643750026529e+01 -2.5347135708427655e+00 9.2043419883119782e+01 -2.8187238090404904e+01 -1.5291148024926793e+00
init_forces: ! |2
1 4.7865489310693540e+01 7.8760925902181516e+00 -3.2694525514709866e+01
2 -1.1124882516177341e+00 -9.0075464203887403e+00 -7.2431691227364459e+00
3 -5.9057050592859328e+00 5.3263619873546261e+01 5.2353380124691469e+01
4 -1.6032230038990633e+01 -2.4560529343731403e+01 1.2891625920422307e+01
5 -4.4802331573497639e+01 -4.8300919461089379e+01 -2.3310767889219324e+01
6 4.7083124388174824e+01 -9.5212933434476312e+00 -3.2526392870546800e+01
7 -1.6208182775476303e+01 1.4458587960739102e+01 -3.5314745459502710e+00
8 -6.5664612141881040e+00 -2.5126850154274202e+01 8.2187944731423329e+01
9 -1.5504395262358301e+01 1.6121044185227817e+01 -4.2007069622477866e-01
10 9.9863759179365275e+00 4.1873540105704549e+01 -6.6085640966037403e+01
11 -2.0441876158908627e+01 -6.5186824168985984e+00 9.0023620309811072e+00
12 -1.0772126658369565e+01 -1.0807367300158219e+01 -9.6049647456797871e+00
13 2.8847886813946291e+00 7.2973241014859198e+00 -1.0414233993842981e-01
14 1.5267407478336393e+01 -9.4754911480231776e+00 -6.6307012925544200e+00
15 1.2402914209534773e+01 -6.2644630791613967e+00 1.8484576795819933e+01
16 3.8927757686508357e-01 1.0690061587911176e+01 6.1542759189377696e+00
17 1.4664194297570785e+00 -1.9971277376602425e+00 1.0776844613215999e+00
18 1.5785371874873322e-01 1.6495665212200166e+00 -6.6944747776990434e+00
19 -1.9328033033421670e+00 -2.4078805870919706e+00 2.8669575541313534e+00
20 1.7749495845934338e+00 7.5831406587195394e-01 3.8275172235676900e+00
21 3.4186149299343742e+00 4.2795410364249484e+00 -1.2789555411020650e+01
22 -6.0875600315279677e+00 -4.1504951869796605e+00 4.5212856070195766e+00
23 2.6689451015935934e+00 -1.2904584944528752e-01 8.2682698040010738e+00
24 -1.3053945393770587e+00 5.0741459325183271e+00 -3.0209518576073018e+00
25 -1.0471133765834284e+00 -3.5082261409793856e+00 5.7374874908501228e-01
26 2.3525079159604871e+00 -1.5659197915389413e+00 2.4472031085222894e+00
27 -2.8720725187343754e-01 2.3577465459557132e+00 -8.0312673032168869e-01
28 -6.2799575211500369e-01 -1.4097313073755862e+00 3.2747938980616453e-02
29 9.1520300398844123e-01 -9.4801523858012704e-01 7.7037879134107223e-01
run_energy: 41.28323739029462
run_stress: ! |2-
8.8236221596506681e+01 -8.6492260623309562e+01 -1.7439609731970940e+00 9.0601855980531312e+01 -2.8735005690484968e+01 -2.6097632235197477e+00
run_forces: ! |2
1 4.7316793853445830e+01 8.2815577813110188e+00 -3.2021703111755464e+01
2 -1.1508196824491330e+00 -9.3814982172707460e+00 -7.5761211707510139e+00
3 -5.1083163691832576e+00 5.2667553294971619e+01 5.1784852458007592e+01
4 -1.6078177452605999e+01 -2.4156048365236213e+01 1.3140924677013103e+01
5 -4.4915734474022280e+01 -4.8095168640411821e+01 -2.3331149037574161e+01
6 4.7077916942842350e+01 -9.5906213020090156e+00 -3.2570331503075487e+01
7 -1.6228599672412471e+01 1.4485102617342370e+01 -3.5441153194985300e+00
8 -6.5097893981550730e+00 -2.5117582302614530e+01 8.2131369512416001e+01
9 -1.5527440970965937e+01 1.6147270375910470e+01 -4.0812004993325646e-01
10 1.0070812216240984e+01 4.1571532807578805e+01 -6.5968810328796337e+01
11 -2.0431584971707451e+01 -6.4817395192247664e+00 8.9879981618991636e+00
12 -1.0884695976714678e+01 -1.1067390190389006e+01 -9.1551242768940568e+00
13 2.8052913970098801e+00 7.1296301666594912e+00 1.3173039168682621e-02
14 1.5254877537873529e+01 -8.9700095533297350e+00 -6.5719846903613162e+00
15 1.2392009100170984e+01 -6.0827695435257292e+00 1.7929674392339596e+01
16 4.7158712437377481e-01 1.0631038523396533e+01 6.0960085687560355e+00
17 1.4458707962589659e+00 -1.9708579331587350e+00 1.0634586790394520e+00
18 1.4201882413835909e-01 1.4265339757773337e+00 -5.7663956896747992e+00
19 -1.6609130686729365e+00 -2.0735307593211125e+00 2.4755525101127143e+00
20 1.5188942445345774e+00 6.4699678354377899e-01 3.2908431795620849e+00
21 3.2242729509516406e+00 4.0079233768386153e+00 -1.2047892238650988e+01
22 -5.7215184687399772e+00 -3.8871624402883409e+00 4.2679223469272234e+00
23 2.4972455177883366e+00 -1.2076093655027398e-01 7.7799698917237645e+00
24 -1.1661978296905471e+00 4.5271404898674854e+00 -2.6925565853370195e+00
25 -9.2712094527152167e-01 -3.1291890525017125e+00 5.1208215565053827e-01
26 2.0933187749620688e+00 -1.3979514373657731e+00 2.1804744296864813e+00
27 -2.6804542538020537e-01 2.1830651328698103e+00 -7.3931790038945400e-01
28 -5.7927072943128310e-01 -1.3052929090347909e+00 2.8365455885795865e-02
29 8.4731615481148848e-01 -8.7777222383501941e-01 7.1095244450365813e-01
...

View File

@ -0,0 +1,89 @@
---
lammps_version: 21 Nov 2023
date_generated: Thu Jan 18 10:15:41 2024
epsilon: 2.5e-13
skip_tests:
prerequisites: ! |
atom full
bond lepton
pre_commands: ! ""
post_commands: ! ""
input_file: in.fourmol
bond_style: lepton no_offset
bond_coeff: ! |
1 1.5 "k*r^2; k=250.0"
2 1.1 "k2*r^2 + k3*r^3 + k4*r^4; k2=300.0; k3=-100.0; k4=50.0"
3 1.3 "k*r^2; k=350.0"
4 1.2 "k*(r-0.2)^2; k=500.0"
5 1.0 "k*r^2; k=450.0"
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! |
r0 1
natoms: 29
init_energy: 38.295825321689215
init_stress: ! |-
-4.7778964706834920e+01 -9.3066674567350432e+01 3.4789470658440035e+02 -3.0023920169312170e+01 -8.0421418879842847e+01 5.8592449335969732e+01
init_forces: ! |2
1 -5.9149914305071416e+00 -3.7728809612345245e+01 -2.7769433362963369e+01
2 -9.4281609567839944e+00 -7.7586487054273015e+00 1.1096676787527940e+01
3 3.2211742366572125e+01 2.7682361264425523e+01 -7.0109911672970497e+00
4 4.9260777576375503e+00 -1.3809750102765932e+00 3.4951785613141868e+00
5 -1.2606902198593501e+00 -1.9373397933007170e+00 6.4372463095041841e+00
6 -3.8858476307965482e+01 6.8567296300319640e+01 1.9889888806614337e+02
7 7.5297927100028144e+00 -3.8622600737556944e+01 -1.9268793182212875e+02
8 1.3018665172824681e+01 -1.2902789438539877e+01 3.2406676637830003e+00
9 7.4343536239661590e-01 8.0072549738604493e-01 3.2899591078538779e+00
10 6.1558871886113291e+00 -2.2419470219698296e+00 1.0080175092279852e+01
11 -3.7020922615305768e-01 -9.1704102274126453e-01 -1.5046795827370363e+00
12 5.2437190958790678e+00 3.4225915524442998e+00 -2.5523597276998897e+00
13 -1.1277007635800260e+01 4.4610677459696646e+00 2.1195215396108269e-01
14 2.9813926585641828e+00 -6.0667387499775116e-01 7.7317115100728788e+00
15 2.5872825164662799e-01 -9.9415365173790704e+00 -3.5428115826174169e+00
16 5.2775953236493464e+01 -3.1855535724919463e+01 -1.6524229620195118e+02
17 -5.8735858023559175e+01 4.0959855098908882e+01 1.5582804819495431e+02
18 -9.0963607969319646e+00 -4.3343406270234155e+00 -1.7623055551859267e+01
19 1.2597490501067170e+01 8.0591915019111742e+00 1.5261489294231819e+01
20 -3.5011297041352050e+00 -3.7248508748877587e+00 2.3615662576274494e+00
21 -1.5332952658285048e+00 5.9630208068632040e-01 -7.4967230017303281e+00
22 4.2380253233105529e+00 1.0270453290850614e+00 6.6489894421385651e+00
23 -2.7047300574820481e+00 -1.6233474097713818e+00 8.4773355959176278e-01
24 -6.6588083188726532e+00 3.5110922792825918e+00 -6.5625174267043489e+00
25 7.9844426562464141e+00 -1.2853795683286129e+00 6.7123710742192300e+00
26 -1.3256343373737607e+00 -2.2257127109539789e+00 -1.4985364751488087e-01
27 6.6999960289138851e+00 6.3808952243186141e+00 2.0100808779497248e+00
28 -8.8466157439236681e-01 3.8018717064230995e-01 -5.9857060538593476e-01
29 -5.8153344545215182e+00 -6.7610823949609244e+00 -1.4115102725637900e+00
run_energy: 37.78424389351509
run_stress: ! |-
-4.6127506998693484e+01 -9.2129732247211749e+01 3.4548310342284810e+02 -2.9841348469661163e+01 -7.8434962689387717e+01 5.9253167412123155e+01
run_forces: ! |2
1 -5.8451208652159004e+00 -3.7483084455000643e+01 -2.7706576989352534e+01
2 -9.4646964278974774e+00 -7.8058897724822449e+00 1.1098831256058579e+01
3 3.1827086102630346e+01 2.7573911030624821e+01 -6.9576662575837211e+00
4 5.1502169659901655e+00 -1.4367546726785101e+00 3.6631301025186187e+00
5 -1.2208420775139264e+00 -1.8781699435112362e+00 6.2332639085051911e+00
6 -3.8491523409043303e+01 6.8063273218541468e+01 1.9723141045830272e+02
7 7.4838209349394775e+00 -3.8394258853636330e+01 -1.9092625515909930e+02
8 1.2676329319901857e+01 -1.2475162287097550e+01 3.3659783337736577e+00
9 6.8845241565874460e-01 7.3814593866184031e-01 3.0434095400342533e+00
10 6.2545583994797553e+00 -2.9600470917047201e+00 9.4247125735981765e+00
11 -1.9554747834212524e-01 -4.8434314068172696e-01 -7.9452259566032057e-01
12 5.2092795750960841e+00 3.1431929551776721e+00 -3.1346654851373348e+00
13 -1.1496483840617872e+01 4.5245217971580018e+00 2.1348220240918236e-01
14 3.1913399826660909e+00 -6.3760720126489068e-01 8.2740980433927742e+00
15 2.7338564489784484e-01 -9.7206665011069671e+00 -3.4841809697094543e+00
16 5.2461611410918316e+01 -3.1639255494702798e+01 -1.6483607587596811e+02
17 -5.8501866653548078e+01 4.0872194473703807e+01 1.5529162691391761e+02
18 -7.0990354207248405e+00 -2.4743922643289666e+00 -1.7824398936159682e+01
19 1.2019842510974870e+01 7.7105128268768715e+00 1.4523712108141252e+01
20 -4.9208070902500296e+00 -5.2361205625479048e+00 3.3006868280184283e+00
21 -1.8548628650934149e+00 2.7467524264262122e-01 -6.7601469408617412e+00
22 3.9136757840663186e+00 9.5561415744904055e-01 6.1181929861632272e+00
23 -2.0588129189729036e+00 -1.2302894000916618e+00 6.4195395469851357e-01
24 -5.7681973234153086e+00 2.0209144998436366e+00 -5.2864044021513967e+00
25 6.3696975292216704e+00 -1.0109756418053095e+00 5.3564043759405795e+00
26 -6.0150020580636188e-01 -1.0099388580383271e+00 -6.9999973789182365e-02
27 6.8467535469188450e+00 5.7500299184200578e+00 2.2775780974490298e+00
28 -1.3929430925479587e+00 5.9772788540443345e-01 -9.4056106886485980e-01
29 -5.4538104543708865e+00 -6.3477578038244911e+00 -1.3370170285841700e+00
...

View File

@ -1,6 +1,6 @@
---
lammps_version: 22 Dec 2022
date_generated: Thu Dec 22 09:57:30 2022
lammps_version: 21 Nov 2023
date_generated: Thu Jan 18 11:01:50 2024
epsilon: 5e-14
skip_tests: intel
prerequisites: ! |
@ -23,23 +23,24 @@ pair_coeff: ! |
2 4 "4.0*eps*((sig/r)^12-(sig/r)^6);eps=0.005;sig=0.5"
2 5 "4.0*eps*((sig/r)^12-(sig/r)^6);eps=0.00866025;sig=2.05"
3 3 "4.0*eps*((sig/r)^12-(sig/r)^6);eps=0.02;sig=3.2"
3 4 "4.0*eps*((sig/r)^12-(sig/r)^6);eps=0.0173205;sig=3.15"
3 4 "-eps*r;eps=0.0173205;sig=3.15"
3 5 "4.0*eps*((sig/r)^12-(sig/r)^6);eps=0.0173205;sig=3.15"
4 4 "10.0"
extract: ! ""
natoms: 29
init_vdwl: 749.2468149791969
init_vdwl: 746.1575578155301
init_coul: 0
init_stress: ! |2-
2.1793853434038242e+03 2.1988955172192768e+03 4.6653977523326257e+03 -7.5956547636050584e+02 2.4751536734032861e+01 6.6652028436400667e+02
2.1723526811665593e+03 2.1959162890293533e+03 4.6328064825512138e+03 -7.5509180369489252e+02 9.4506578600439983e+00 6.7585028859193505e+02
init_forces: ! |2
1 -2.3333390280895912e+01 2.6994567613322641e+02 3.3272827850356805e+02
1 -2.3359983837422618e+01 2.6996030011590727e+02 3.3274783233743295e+02
2 1.5828554630414899e+02 1.3025008843535872e+02 -1.8629682358935722e+02
3 -1.3528903738169066e+02 -3.8704313358319990e+02 -1.4568978437133106e+02
4 -7.8711096705893366e+00 2.1350518625373538e+00 -5.5954532185548134e+00
5 -2.5176757268228540e+00 -4.0521510681020239e+00 1.2152704057877019e+01
6 -8.3190662465252137e+02 9.6394149462625603e+02 1.1509093566509248e+03
7 5.8203388932513583e+01 -3.3608997951626793e+02 -1.7179617996573040e+03
8 1.4451392284291535e+02 -1.0927475861088995e+02 3.9990593492420442e+02
7 6.6340523101244187e+01 -3.4078810185436379e+02 -1.7003039516942540e+03
8 1.3674478037618434e+02 -1.0517874373121482e+02 3.8291074246191346e+02
9 7.9156945283097443e+01 8.5273009783986538e+01 3.5032175698445189e+02
10 5.3118875219105360e+02 -6.1040990859419412e+02 -1.8355872642619292e+02
11 -2.3530157267965532e+00 -5.9077640073819717e+00 -9.6590723955414290e+00
@ -48,8 +49,8 @@ init_forces: ! |2
14 -3.3852721292265153e+00 6.8636181241903649e-01 -8.7507190862499868e+00
15 -2.0454999188605300e-01 8.4846165523049883e+00 3.0131615419406712e+00
16 4.6326310311812108e+02 -3.3087715736498188e+02 -1.1893024561782554e+03
17 -4.5334300923766727e+02 3.1554283255882569e+02 1.2058417793481203e+03
18 -1.8862623280672661e-02 -3.3402010907951661e-02 3.1000479299095260e-02
17 -4.5371128972368928e+02 3.1609940794953951e+02 1.2052011419527653e+03
18 8.0197172683943874e-03 -2.4939258820032362e-03 -1.0571459969936936e-02
19 3.1843079640570047e-04 -2.3918627818763426e-04 1.7427252638513439e-03
20 -9.9760831209706009e-04 -1.0209184826753090e-03 3.6910972636601454e-04
21 -7.1566125273265186e+01 -8.1615678329920655e+01 2.2589561408339890e+02
@ -61,38 +62,38 @@ init_forces: ! |2
27 5.1810388677546001e+01 -2.2705458321213797e+02 9.0849111082069669e+01
28 -1.8041307121444069e+02 7.7534042932772905e+01 -1.2206956760706598e+02
29 1.2861057254925012e+02 1.4952711274394568e+02 3.1216025556267880e+01
run_vdwl: 719.4530651193046
run_vdwl: 716.5213000416621
run_coul: 0
run_stress: ! |2-
2.1330153957371017e+03 2.1547728168285516e+03 4.3976497417710125e+03 -7.3873328448298525e+02 4.1743821105370067e+01 6.2788012209191027e+02
2.1263870112744726e+03 2.1520080341389726e+03 4.3663519512361027e+03 -7.3456213833770062e+02 2.6927285459244832e+01 6.3691834104928068e+02
run_forces: ! |2
1 -2.0299419751359164e+01 2.6686193378823020e+02 3.2358785870694015e+02
2 1.5298617928491225e+02 1.2596516341409203e+02 -1.7961292655338619e+02
3 -1.3353630652439830e+02 -3.7923748696131315e+02 -1.4291839793625817e+02
4 -7.8374717836161762e+00 2.1276610789823409e+00 -5.5845014473820616e+00
5 -2.5014258630866735e+00 -4.0250131424704412e+00 1.2103512372025639e+01
6 -8.0681462887292457e+02 9.2165637136761688e+02 1.0270795806932783e+03
7 5.5780279349903523e+01 -3.1117530951561656e+02 -1.5746991292869018e+03
8 1.3452983055535049e+02 -1.0064659350255911e+02 3.8851791558207651e+02
9 7.6746213883425980e+01 8.2501469877402130e+01 3.3944351200617882e+02
10 5.2128033527695595e+02 -5.9920098848285863e+02 -1.8126029815043339e+02
11 -2.3573118090915246e+00 -5.8616944550888359e+00 -9.6049808811326205e+00
12 1.7503975847822900e+01 1.0626930310560814e+01 -8.0603160272054968e+00
13 8.0530313322973104e+00 -3.1756495170399117e+00 -1.4618315664740528e-01
14 -3.3416065168069773e+00 6.6492606336082150e-01 -8.6345131440469700e+00
15 -2.2253843262374914e-01 8.5025661635348779e+00 3.0369735873081622e+00
16 4.3476311264989465e+02 -3.1171086735551415e+02 -1.1135217194927448e+03
17 -4.2469846140777133e+02 2.9615411776780593e+02 1.1302573488400669e+03
18 -1.8849981672825908e-02 -3.3371636477421307e-02 3.0986293443778727e-02
19 3.0940277774414027e-04 -2.4634536455373044e-04 1.7433360008861016e-03
20 -9.8648131277150790e-04 -1.0112587134526946e-03 3.6932948773965417e-04
21 -7.0490745283106378e+01 -7.9749153581142139e+01 2.2171003384646431e+02
22 -1.0638717908920071e+02 -2.5949502163177968e+01 -1.6645589526812276e+02
23 1.7686797710735027e+02 1.0571018898885514e+02 -5.5243337084099387e+01
24 3.8206017656281375e+01 -2.1022820141992960e+02 1.1260711266189014e+02
25 -1.4918881473530880e+02 2.3762151395876508e+01 -1.2549188139143085e+02
26 1.1097059498808308e+02 1.8645503634228518e+02 1.2861559677865248e+01
27 5.0800844984832125e+01 -2.2296588090685469e+02 8.8607367716323253e+01
28 -1.7694190504288886e+02 7.6029945485182026e+01 -1.1950518150242071e+02
29 1.2614894925528141e+02 1.4694250820033548e+02 3.0893386672863034e+01
1 -2.0326040164905073e+01 2.6687684422507328e+02 3.2360752654223910e+02
2 1.5298608857690186e+02 1.2596506573447739e+02 -1.7961281277841888e+02
3 -1.3353631293077220e+02 -3.7923732277833739e+02 -1.4291833260989750e+02
4 -7.8374717116975035e+00 2.1276610267113969e+00 -5.5845014524498486e+00
5 -2.5014258756924157e+00 -4.0250131713717776e+00 1.2103512280982228e+01
6 -8.0714971444536457e+02 9.2203068890526424e+02 1.0274502514782534e+03
7 6.3722543724608350e+01 -3.1586173092061807e+02 -1.5580743968587681e+03
8 1.2737293861904031e+02 -9.6945064279519002e+01 3.7231518354375891e+02
9 7.6709940036396304e+01 8.2451980339096536e+01 3.3926849385746954e+02
10 5.2123408713149831e+02 -5.9914309504622599e+02 -1.8121478407355445e+02
11 -2.3573086824741427e+00 -5.8616969504300931e+00 -9.6049799947287671e+00
12 1.7504108236707797e+01 1.0626901299509713e+01 -8.0602444903747301e+00
13 8.0530313558451159e+00 -3.1756495145404533e+00 -1.4618321144421534e-01
14 -3.3416062225209915e+00 6.6492609500227240e-01 -8.6345136470911594e+00
15 -2.2253820242887132e-01 8.5025660110994483e+00 3.0369741645942137e+00
16 4.3476708820318731e+02 -3.1171425443331651e+02 -1.1135289618967258e+03
17 -4.2507048343681140e+02 2.9671384825884064e+02 1.1296230654445915e+03
18 8.0130752607770750e-03 -2.4895867517657545e-03 -1.0574351684568857e-02
19 3.0939970262803125e-04 -2.4635874092791046e-04 1.7433490521479268e-03
20 -9.8648319666298735e-04 -1.0112621691758337e-03 3.6933139856766442e-04
21 -7.0490745298133859e+01 -7.9749153568373742e+01 2.2171003384665224e+02
22 -1.0638717908973166e+02 -2.5949502162671845e+01 -1.6645589526807785e+02
23 1.7686797710711278e+02 1.0571018898899243e+02 -5.5243337084327727e+01
24 3.8206017659583978e+01 -2.1022820135505594e+02 1.1260711269986750e+02
25 -1.4918881473631544e+02 2.3762151403215309e+01 -1.2549188138812220e+02
26 1.1097059498835199e+02 1.8645503634383900e+02 1.2861559678659969e+01
27 5.0800844960383969e+01 -2.2296588092255456e+02 8.8607367714616288e+01
28 -1.7694190504410764e+02 7.6029945484553380e+01 -1.1950518150262033e+02
29 1.2614894924957088e+02 1.4694250819500266e+02 3.0893386676150566e+01
...

View File

@ -32,6 +32,8 @@ using testing::StrEq;
using utils::split_words;
const double EPSILON = 5.0e-14;
#define test_name test_info_->name()
static void create_molecule_files(const std::string &h2o_filename, const std::string &co2_filename)
@ -145,7 +147,7 @@ protected:
fclose(fp);
command(fmt::format("molecule {} {} {}", name, file, args));
remove(file.c_str());
platform::unlink(file.c_str());
}
};
@ -184,7 +186,7 @@ TEST_F(MoleculeFileTest, badargs)
TEST_FAILURE(
".*Illegal molecule command.*",
run_mol_cmd(test_name, "scale", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n"););
remove("badargs.mol");
platform::unlink("moltest_badargs.mol");
}
TEST_F(MoleculeFileTest, noatom)
@ -193,14 +195,14 @@ TEST_F(MoleculeFileTest, noatom)
run_mol_cmd(test_name, "",
"Comment\n0 atoms\n1 bonds\n\n"
" Coords\n\nBonds\n\n 1 1 2\n"););
remove("noatom.mol");
platform::unlink("moltest_noatom.mol");
}
TEST_F(MoleculeFileTest, empty)
{
TEST_FAILURE(".*ERROR: Unexpected end of molecule file.*",
run_mol_cmd(test_name, "", "Comment\n\n"););
remove("empty.mol");
platform::unlink("moltest_empty.mol");
}
TEST_F(MoleculeFileTest, nospecial)
@ -210,7 +212,7 @@ TEST_F(MoleculeFileTest, nospecial)
"Comment\n3 atoms\n\n2 bonds\n\n"
" Coords\n\n 1 1.0 1.0 1.0\n 2 1.0 1.0 0.0\n 3 1.0 0.0 1.0\n"
" Bonds\n\n 1 1 1 2\n 2 1 1 3\n"););
remove("nospecial.mol");
platform::unlink("moltest_nospecial.mol");
}
TEST_F(MoleculeFileTest, minimal)
@ -218,7 +220,7 @@ TEST_F(MoleculeFileTest, minimal)
BEGIN_CAPTURE_OUTPUT();
run_mol_cmd(test_name, "", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n"
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*Comment.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*1 atoms.*\n.*0 bonds.*"));
}
@ -230,7 +232,7 @@ TEST_F(MoleculeFileTest, notype)
command("create_box 1 box");
run_mol_cmd(test_name, "", "Comment\n1 atoms\n\n Coords\n\n 1 0.0 0.0 0.0\n");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n"
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*Comment.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*1 atoms.*\n.*0 bonds.*"));
TEST_FAILURE(".*ERROR: Create_atoms molecule must have atom types.*",
command("create_atoms 0 single 0.0 0.0 0.0 mol notype 542465"););
@ -259,7 +261,7 @@ TEST_F(MoleculeFileTest, twomols)
" Coords\n\n 1 0.0 0.0 0.0\n 2 0.0 0.0 1.0\n"
" Molecules\n\n 1 1\n 2 2\n\n Types\n\n 1 1\n 2 2\n\n");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*2 molecules.*\n"
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*Comment.*\n.*2 molecules.*\n"
".*0 fragments.*\n.*2 atoms with max type 2.*\n.*0 bonds.*"));
ASSERT_EQ(lmp->atom->nmolecule, 1);
auto mols = lmp->atom->get_molecule_by_id(test_name);
@ -273,10 +275,10 @@ TEST_F(MoleculeFileTest, twofiles)
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(
output,
ContainsRegex(".*Read molecule template twomols:.*\n.*1 molecules.*\n"
ContainsRegex(".*Read molecule template twomols:.*\n.*Water.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 2.*\n.*2 bonds with max type 1.*\n"
".*1 angles with max type 1.*\n.*0 dihedrals.*\n.*0 impropers.*\n"
".*Read molecule template twomols:.*\n.*1 molecules.*\n"
".*Read molecule template twomols:.*\n.*CO2.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 4.*\n.*2 bonds with max type 2.*\n"
".*1 angles with max type 2.*\n.*0 dihedrals.*"));
BEGIN_CAPTURE_OUTPUT();
@ -306,7 +308,7 @@ TEST_F(MoleculeFileTest, labelmap)
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(
output,
ContainsRegex(".*Read molecule template h2olabel:.*\n.*1 molecules.*\n"
ContainsRegex(".*Read molecule template h2olabel:.*\n.*Water.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 2.*\n.*2 bonds with max type 1.*\n"
".*1 angles with max type 1.*\n.*0 dihedrals.*\n.*0 impropers.*"));
BEGIN_CAPTURE_OUTPUT();
@ -314,7 +316,7 @@ TEST_F(MoleculeFileTest, labelmap)
output = END_CAPTURE_OUTPUT();
ASSERT_THAT(
output,
ContainsRegex(".*Read molecule template co2label:.*\n.*1 molecules.*\n"
ContainsRegex(".*Read molecule template co2label:.*\n.*CO2.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 4.*\n.*2 bonds with max type 2.*\n"
".*1 angles with max type 2.*\n.*0 dihedrals.*"));
BEGIN_CAPTURE_OUTPUT();
@ -328,12 +330,12 @@ TEST_F(MoleculeFileTest, labelmap)
auto second = output.substr(mark);
ASSERT_THAT(
first,
ContainsRegex(".*Read molecule template h2onum:.*\n.*1 molecules.*\n"
ContainsRegex(".*Read molecule template h2onum:.*\n.*Water.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 2.*\n.*2 bonds with max type 1.*\n"
".*1 angles with max type 1.*\n.*0 dihedrals.*\n.*0 impropers.*\n"));
ASSERT_THAT(
second,
ContainsRegex(".*Read molecule template co2num:.*\n.*1 molecules.*\n"
ContainsRegex(".*Read molecule template co2num:.*\n.*CO2.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*3 atoms with max type 4.*\n.*2 bonds with max type 2.*\n"
".*1 angles with max type 2.*\n.*0 dihedrals.*"));
ASSERT_EQ(lmp->atom->nmolecule, 4);
@ -379,7 +381,7 @@ TEST_F(MoleculeFileTest, bonds)
" 1 1 1 2\n"
" 2 2 1 3\n\n");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*1 molecules.*\n"
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*Comment.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*4 atoms.*type.*2.*\n"
".*2 bonds.*type.*2.*\n.*0 angles.*"));
@ -404,6 +406,60 @@ TEST_F(MoleculeFileTest, bonds)
END_HIDE_OUTPUT();
}
TEST_F(MoleculeFileTest, dipoles)
{
if (!LAMMPS::is_installed_pkg("DIPOLE")) GTEST_SKIP();
BEGIN_CAPTURE_OUTPUT();
command("atom_style dipole");
command("region box block 0 1 0 1 0 1");
command("create_box 2 box");
run_mol_cmd(test_name, "",
"# Dumbbell with dipole molecule file.\n\n"
"2 atoms\n\n"
"Coords\n\n1 -1.0 0.0 0.0\n2 1.0 0.0 0.0\n\n"
"Types\n\n1 1\n2 2\n\n"
"Dipoles\n\n1 1.0 0.0 0.0\n2 1.0 1.0 0.0\n\n");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Read molecule template.*\n.*Dumbbell.*\n.*1 molecules.*\n"
".*0 fragments.*\n.*2 atoms.*type.*2.*\n"));
BEGIN_CAPTURE_OUTPUT();
command("mass * 1.0");
command("create_atoms 0 single 0.5 0.5 0.5 mol dipoles 67235 rotate 90.0 0.0 0.0 1.0");
output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, ContainsRegex(".*Created 2 atoms.*"));
Molecule *mol = lmp->atom->molecules[0];
ASSERT_EQ(mol->natoms, 2);
ASSERT_EQ(lmp->atom->natoms, 2);
mol->compute_mass();
mol->compute_com();
EXPECT_NEAR(mol->masstotal, 2.0, EPSILON);
EXPECT_NEAR(mol->com[0], 0.0, EPSILON);
EXPECT_NEAR(mol->com[1], 0.0, EPSILON);
EXPECT_NEAR(mol->com[2], 0.0, EPSILON);
EXPECT_EQ(mol->comatom, 1);
ASSERT_NE(mol->mu, nullptr);
EXPECT_NEAR(mol->mu[0][0], 1.0, EPSILON);
EXPECT_NEAR(mol->mu[0][1], 0.0, EPSILON);
EXPECT_NEAR(mol->mu[0][2], 0.0, EPSILON);
EXPECT_NEAR(mol->mu[1][0], 1.0, EPSILON);
EXPECT_NEAR(mol->mu[1][1], 1.0, EPSILON);
EXPECT_NEAR(mol->mu[1][2], 0.0, EPSILON);
EXPECT_NEAR(mol->maxextent, 2.0, EPSILON);
// dipoles should be rotated by 90 degrees clockwise around the z axis
double **mu = lmp->atom->mu;
ASSERT_NE(mu, nullptr);
EXPECT_NEAR(mu[0][0], 0.0, EPSILON);
EXPECT_NEAR(mu[0][1], 1.0, EPSILON);
EXPECT_NEAR(mu[0][2], 0.0, EPSILON);
EXPECT_NEAR(mu[0][3], 1.0, EPSILON);
EXPECT_NEAR(mu[1][0], -1.0, EPSILON);
EXPECT_NEAR(mu[1][1], 1.0, EPSILON);
EXPECT_NEAR(mu[1][2], 0.0, EPSILON);
EXPECT_NEAR(mu[1][3], sqrt(2.0), EPSILON);
}
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

View File

@ -542,6 +542,41 @@ TEST(Lepton, Optimize)
out.str("");
}
TEST(Lepton, Exception)
{
Lepton::CompiledExpression function, derivative;
auto parsed = Lepton::Parser::parse("x*x");
function = parsed.createCompiledExpression();
derivative = parsed.differentiate("x").createCompiledExpression();
double x = 1.5;
EXPECT_NO_THROW(function.getVariableReference("x") = x;);
EXPECT_NO_THROW(derivative.getVariableReference("x") = x;);
EXPECT_DOUBLE_EQ(function.evaluate(), 2.25);
EXPECT_DOUBLE_EQ(derivative.evaluate(), 3.0);
parsed = Lepton::Parser::parse("x");
function = parsed.createCompiledExpression();
derivative = parsed.differentiate("x").createCompiledExpression();
x = 2.5;
EXPECT_NO_THROW(function.getVariableReference("x") = x;);
EXPECT_THROW(derivative.getVariableReference("x") = x;, Lepton::Exception);
EXPECT_DOUBLE_EQ(function.evaluate(), 2.5);
EXPECT_DOUBLE_EQ(derivative.evaluate(), 1.0);
parsed = Lepton::Parser::parse("1.0");
function = parsed.createCompiledExpression();
derivative = parsed.differentiate("x").createCompiledExpression();
x = 0.5;
EXPECT_THROW(function.getVariableReference("x") = x;, Lepton::Exception);
EXPECT_THROW(derivative.getVariableReference("x") = x;, Lepton::Exception);
EXPECT_DOUBLE_EQ(function.evaluate(), 1.0);
EXPECT_DOUBLE_EQ(derivative.evaluate(), 0.0);
}
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);