Merge branch 'develop' into rheo
This commit is contained in:
@ -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")
|
||||
|
||||
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>`.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -151,6 +151,7 @@ asphericity
|
||||
Asq
|
||||
assignee
|
||||
assively
|
||||
associativity
|
||||
Asta
|
||||
Astart
|
||||
Astop
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
2
src/.gitignore
vendored
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -70,6 +70,8 @@
|
||||
#include "modify.h"
|
||||
#include "update.h"
|
||||
|
||||
#include "fmt/ranges.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -68,6 +68,8 @@
|
||||
#include "pair_kim.h"
|
||||
#include "variable.h"
|
||||
|
||||
#include "fmt/ranges.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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>();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>();
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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>();
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
10
src/atom.cpp
10
src/atom.cpp
@ -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)
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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++;
|
||||
|
||||
16
src/fix.h
16
src/fix.h
@ -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 *){};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
272
src/fmt/chrono.h
272
src/fmt/chrono.h
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
647
src/fmt/core.h
647
src/fmt/core.h
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
|
||||
718
src/fmt/format.h
718
src/fmt/format.h
File diff suppressed because it is too large
Load Diff
64
src/fmt/os.h
64
src/fmt/os.h
@ -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
|
||||
|
||||
@ -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};
|
||||
}
|
||||
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
117
src/fmt/ranges.h
117
src/fmt/ranges.h
@ -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
|
||||
|
||||
154
src/fmt/std.h
154
src/fmt/std.h
@ -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_
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++)
|
||||
|
||||
@ -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 *);
|
||||
|
||||
@ -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
|
||||
...
|
||||
|
||||
@ -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"
|
||||
|
||||
88
unittest/force-styles/tests/angle-lepton_nooffset.yaml
Normal file
88
unittest/force-styles/tests/angle-lepton_nooffset.yaml
Normal 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
|
||||
...
|
||||
89
unittest/force-styles/tests/bond-lepton_nooffset.yaml
Normal file
89
unittest/force-styles/tests/bond-lepton_nooffset.yaml
Normal 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
|
||||
...
|
||||
@ -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
|
||||
...
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user