Merge remote-tracking branch 'origin/develop' into python_computes

This commit is contained in:
Richard Berger
2025-01-19 15:41:30 -07:00
52 changed files with 61757 additions and 4194 deletions

View File

@ -98,24 +98,21 @@ check_for_autogen_files(${LAMMPS_SOURCE_DIR})
#####################################################################
include(CheckIncludeFileCXX)
# set required compiler flags and compiler/CPU arch specific optimizations
# set required compiler flags, apply checks, and compiler/CPU arch specific optimizations
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# Intel classic compilers version 19 are broken and fail to compile the embedded fmtlib
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 20.0)
message(ERROR "Intel classic compiler version ${CMAKE_CXX_COMPILER_VERSION} is too old")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qrestrict")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4)
set(CMAKE_TUNE_DEFAULT "/QxCOMMON-AVX512")
else()
set(CMAKE_TUNE_DEFAULT "/QxHost")
endif()
set(CMAKE_TUNE_DEFAULT "/QxHost")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict")
if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4)
set(CMAKE_TUNE_DEFAULT "-xCOMMON-AVX512")
else()
set(CMAKE_TUNE_DEFAULT "-xHost -fp-model fast=2 -no-prec-div -qoverride-limits -diag-disable=10441 -diag-disable=11074 -diag-disable=11076 -diag-disable=2196")
endif()
set(CMAKE_TUNE_DEFAULT "-xHost -fp-model fast=2 -no-prec-div -qoverride-limits -diag-disable=10441 -diag-disable=11074 -diag-disable=11076 -diag-disable=2196")
endif()
endif()

View File

@ -58,6 +58,7 @@ OPT.
* :doc:`dt/reset (k) <fix_dt_reset>`
* :doc:`edpd/source <fix_dpd_source>`
* :doc:`efield (k) <fix_efield>`
* :doc:`efield/lepton <fix_efield_lepton>`
* :doc:`efield/tip4p <fix_efield>`
* :doc:`ehex <fix_ehex>`
* :doc:`electrode/conp (i) <fix_electrode>`

View File

@ -80,6 +80,7 @@ OPT.
* :doc:`coul/tt <pair_coul_tt>`
* :doc:`coul/wolf (ko) <pair_coul>`
* :doc:`coul/wolf/cs <pair_cs>`
* :doc:`dispersion/d3 <pair_dispersion_d3>`
* :doc:`dpd (giko) <pair_dpd>`
* :doc:`dpd/coul/slater/long (g) <pair_dpd_coul_slater_long>`
* :doc:`dpd/ext (ko) <pair_dpd_ext>`

View File

@ -994,6 +994,7 @@ Additional pair styles that are less commonly used.
* ``src/EXTRA-PAIR``: filenames -> commands
* :doc:`pair_style <pair_style>`
* ``examples/PACKAGES/dispersion``
----------

View File

@ -237,6 +237,7 @@ accelerated styles exist.
* :doc:`dt/reset <fix_dt_reset>` - reset the timestep based on velocity, forces
* :doc:`edpd/source <fix_dpd_source>` - add heat source to eDPD simulations
* :doc:`efield <fix_efield>` - impose electric field on system
* :doc:`efield/lepton <fix_efield_lepton>` - impose electric field on system using a Lepton expression for the potential
* :doc:`efield/tip4p <fix_efield>` - impose electric field on system with TIP4P molecules
* :doc:`ehex <fix_ehex>` - enhanced heat exchange algorithm
* :doc:`electrode/conp <fix_electrode>` - impose electric potential

View File

@ -45,8 +45,9 @@ Description
Add a force :math:`\vec{F} = q\vec{E}` to each charged atom in the group due to an
external electric field being applied to the system. If the system
contains point-dipoles, also add a torque on the dipoles due to the
external electric field.
contains point-dipoles, also add a torque :math:`\vec{T} = \vec{p} \times \vec{E}` on the dipoles due to the
external electric field. This fix does not compute the dipole force :math:`\vec{F} = (\vec{p} \cdot \nabla) \vec{E}`,
and the :doc:`fix efield/lepton <fix_efield_lepton>` command should be used instead.
.. versionadded:: 28Mar2023
@ -68,6 +69,7 @@ For point-dipoles, equal-style variables can be used, but atom-style
variables are not currently supported, since they imply a spatial
gradient in the electric field which means additional terms with
gradients of the field are required for the force and torque on dipoles.
The :doc:`fix efield/lepton <fix_efield_lepton>` command should be used instead.
Equal-style variables can specify formulas with various mathematical
functions, and include :doc:`thermo_style <thermo_style>` command
@ -229,7 +231,7 @@ Fix style *efield/tip4p* can only be used with tip4p pair styles.
Related commands
""""""""""""""""
:doc:`fix addforce <fix_addforce>`
:doc:`fix addforce <fix_addforce>`, :doc:`fix efield/lepton <fix_efield_lepton>`
Default
"""""""

View File

@ -0,0 +1,143 @@
.. index:: fix efield/lepton
fix efield/lepton command
=========================
Syntax
""""""
.. code-block:: LAMMPS
fix ID group-ID efield/lepton V ...
* ID, group-ID are documented in the :doc:`fix <fix>` command
* style = *efield/lepton*
* V = electric potential (electric field * distance units)
* V must be a Lepton expression (see below)
* zero or more keyword/value pairs may be appended to args
* keyword = *region* or *step*
.. parsed-literal::
*region* value = region-ID
region-ID = ID of region atoms must be in to have effect
*step* value = h
h = step size for numerical differentiation (distance units)
Examples
""""""""
.. code-block:: LAMMPS
fix ex all efield/lepton "-E*x; E=1"
fix dexx all efield/lepton "-0.5*x^2" step 1
fix yukawa all efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A=1; B=1" step 1e-6
fix infp all efield/lepton "-abs(x)" step 1
variable th equal 2*PI*ramp(0,1)
fix erot all efield/lepton "-(x*cos(v_th)+y*sin(v_th))"
Description
"""""""""""
.. versionadded:: TBD
Add an electric potential :math:`V` that applies to a group of charged atoms a force :math:`\vec{F} = q \vec{E}`,
and to dipoles a force :math:`\vec{F} = (\vec{p} \cdot \nabla) \vec{E}` and torque :math:`\vec{T} = \vec{p} \times \vec{E}`,
where :math:`\vec{E} = - \nabla V`. The fix also evaluates the electrostatic energy (:math:`U_{q} = q V` and :math:`U_{p} = - \vec{p} \cdot \vec{E}`)
due to this potential when the :doc:`fix_modify energy yes <fix_modify>` command is specified (see below).
.. note::
This command should be used instead of :doc:`fix efield <fix_efield>` if you want to impose a non-uniform electric field on a system with dipoles
since the latter does not include the dipole force term. If you only have charges or if the electric field gradient is negligible,
:doc:`fix efield <fix_efield>` should be used since it is faster.
The `Lepton library <https://simtk.org/projects/lepton>`_, that the *efield/lepton* fix style interfaces with, evaluates
the expression string at run time to compute the energy, forces, and torques. It creates an analytical representation
of :math:`V` and :math:`\vec{E}`, while the gradient force is computed using a central difference scheme
.. math::
\vec{F} = \frac{|\vec{p}|}{2h} \left[ \vec{E}(\vec{x} + h \hat{p}) - \vec{E}(\vec{x} - h \hat{p}) \right] .
The Lepton expression must be either enclosed in quotes or must not contain any whitespace so that LAMMPS
recognizes it as a single keyword. More on valid Lepton expressions below. The final Lepton expression must
be a function of only :math:`x, y, z`, which refer to the current *unwrapped* coordinates of the atoms to ensure continuity.
Special care must be taken when using this fix with periodic boundary conditions or box-changing commands.
----------
.. include:: lepton_expression.rst
----------
If the *region* keyword is used, the atom must also be in the specified
geometric :doc:`region <region>` in order to be affected by the potential.
The *step* keyword is required when :doc:`atom_style dipole <atom_style>` is used and the electric field is non-uniform.
----------
Restart, fix_modify, output, run start/stop, minimize info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
No information about this fix is written to :doc:`binary restart files
<restart>`.
The :doc:`fix_modify <fix_modify>` *energy* option is supported by this
fix to add the potential energy defined above to the global potential energy
of the system as part of :doc:`thermodynamic output <thermo_style>`.
The default setting for this fix is :doc:`fix_modify energy no <fix_modify>`.
The :doc:`fix_modify <fix_modify>` *virial* option is supported by this
fix to add the contribution due to the added ***forces*** on charges and dipoles
to both the global pressure and per-atom stress of the system via the
:doc:`compute pressure <compute_pressure>` and :doc:`compute stress/atom
<compute_stress_atom>` commands. The former can be accessed by
:doc:`thermodynamic output <thermo_style>`. The default setting for
this fix is :doc:`fix_modify virial no <fix_modify>`.
The :doc:`fix_modify <fix_modify>` *respa* option is supported by this
fix. This allows to set at which level of the :doc:`r-RESPA <run_style>`
integrator the fix adding its forces. Default is the outermost level.
This fix computes a global scalar and a global 3-vector of forces,
which can be accessed by various :doc:`output commands <Howto_output>`.
The scalar is the potential energy discussed above.
The vector is the total force added to the group of atoms.
The scalar and vector values calculated by this fix are "extensive".
This fix cannot be used with the *start/stop* keywords of
the :doc:`run <run>` command.
The forces due to this fix are imposed during an energy minimization,
invoked by the :doc:`minimize <minimize>` command. You should not
specify force components with a variable that has time-dependence for
use with a minimizer, since the minimizer increments the timestep as
the iteration count during the minimization.
.. note::
If you want the electric potential energy to be included in the
total potential energy of the system (the quantity being minimized),
you MUST enable the :doc:`fix_modify <fix_modify>` *energy* option for this fix.
----------
Restrictions
""""""""""""
Fix style *efield/lepton* is part of the LEPTON package. It is only enabled if LAMMPS was built with that package.
See the :doc:`Build package <Build_package>` page for more info.
Related commands
""""""""""""""""
:doc:`fix efield <fix_efield>`
Default
"""""""
none

View File

@ -0,0 +1,158 @@
.. index:: pair_style dispersion/d3
pair_style dispersion/d3 command
================================
Syntax
""""""
.. code-block:: LAMMPS
pair_style dispersion/d3 damping functional cutoff cn_cutoff
* damping = damping function: *zero*, *zerom*, *bj*, or *bjm*
* functional = XC functional form: *pbe*, *pbe0*, ... (see list below)
* cutoff = global cutoff (distance units)
* cn_cutoff = coordination number cutoff (distance units)
Examples
""""""""
.. code-block:: LAMMPS
pair_style dispersion/d3 zero pbe 30.0 20.0
pair_coeff * * C
Description
"""""""""""
.. versionadded:: TBD
Style *dispersion/d3* computes the dispersion energy-correction used in
the DFT-D3 method of Grimme :ref:`(Grimme1) <Grimme1>`. It would
typically be used with a machine learning (ML) potential that was
trained with results from plain DFT calculations without the dispersion
correction through pair_style hybrid/overlay. ML potentials are often
combined *a posteriori* with dispersion energy-correction schemes (see
*e.g.* :ref:`(Qamar) <Qamar>` and :ref:`(Batatia) <Batatia>`).
The energy contribution :math:`E_i` for an atom :math:`i` is given by:
.. math::
E_i = \frac{1}{2} \sum_{j \neq i} \big(
s_6 \frac{C_{6,ij}}{r^6_{ij}} f_6^{damp}(r_{ij}) +
s_8 \frac{C_{8,ij}}{r^8_{ij}} f_8^{damp}(r_{ij}) \big)
where :math:`C_n` is the averaged, geometry-dependent nth-order
dispersion coefficient for atom pair :math:`ij`, :math:`r_{ij}` their
inter-nuclear distance, :math:`s_n` are XC functional-dependent scaling
factor, and :math:`f_n^{damp}` are damping functions.
.. note::
It is currently *not* possible to calculate three-body dispersion
contributions, according to, for example, the Axilrod-Teller-Muto
model.
Available damping functions are the original "zero-damping"
:ref:`(Grimme1) <Grimme1>`, Becke-Johnson damping :ref:`(Grimme2)
<Grimme2>`, and their revised forms :ref:`(Sherrill) <Sherrill>`.
Available XC functional scaling factors are listed in the table below,
and depend on the selected damping function.
+------------------+--------------------------------------------------------------------------------+
| Damping function | XC functional |
+==================+================================================================================+
| | | | slater-dirac-exchange, b-lyp, b-p, b97-d, revpbe, pbe, pbesol, rpw86-pbe, |
| | | | rpbe, tpss, b3-lyp, pbe0, hse06, revpbe38, pw6b95, tpss0, b2-plyp, pwpb95, |
| | zero | | b2gp-plyp, ptpss, hf, mpwlyp, bpbe, bh-lyp, tpssh, pwb6k, b1b95, bop, o-lyp, |
| | | | o-pbe, ssb, revssb, otpss, b3pw91, revpbe0, pbe38, mpw1b95, mpwb1k, bmk, |
| | | | cam-b3lyp, lc-wpbe, m05, m052x, m06l, m06, m062x, m06hf, hcth120 |
+------------------+--------------------------------------------------------------------------------+
| zerom | b2-plyp, b3-lyp, b97-d, b-lyp, b-p, pbe, pbe0, lc-wpbe |
+------------------+--------------------------------------------------------------------------------+
| | | | b-p, b-lyp, revpbe, rpbe, b97-d, pbe, rpw86-pbe, b3-lyp, tpss, hf, tpss0, |
| | | | pbe0, hse06, revpbe38, pw6b95, b2-plyp, dsd-blyp, dsd-blyp-fc, bop, mpwlyp, |
| | bj | | o-lyp, pbesol, bpbe, opbe, ssb, revssb, otpss, b3pw91, bh-lyp, revpbe0, |
| | | | tpssh, mpw1b95, pwb6k, b1b95, bmk, cam-b3lyp, lc-wpbe, b2gp-plyp, ptpss, |
| | | | pwpb95, hf/mixed, hf/sv, hf/minis, b3lyp/6-31gd, hcth120, pw1pw, pwgga, |
| | | | hsesol, hf3c, hf3cv, pbeh3c, pbeh-3c |
+------------------+--------------------------------------------------------------------------------+
| bjm | b2-plyp, b3-lyp, b97-d, b-lyp, b-p, pbe, pbe0, lc-wpbe |
+------------------+--------------------------------------------------------------------------------+
This style is primarily supposed to be used combined with a
machine-learned interatomic potential trained on a DFT dataset (the
selected XC functional should be chosen accordingly) via the
:doc:`pair_style hybrid <pair_hybrid>` command.
Coefficients
""""""""""""
All the required coefficients are already stored internally (in the
``src/EXTRA-PAIR/d3_parameters.h`` file). The only information to
provide are the chemical symbols of the atoms. The number of chemical
symbols given must be equal to the number of atom types used and must
match their ordering as atom types.
Mixing, shift, table, tail correction, restart, rRESPA info
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This pair style does not support mixing since all parameters are
explicit for each pair of atom types.
This pair style does not support the :doc:`pair_modify` shift, table,
and tail options.
This pair style does not write its information to :doc:`binary restart
files <restart>`.
This pair style can only be used via the *pair* keyword of the
:doc:`run_style respa <run_style>` command. It does not support the
*inner*, *middle*, *outer* keywords.
Restrictions
""""""""""""
Style *dispersion/d3* is part of the EXTRA-PAIR package. It is only
enabled if LAMMPS was built with that package. See the :doc:`Build
package <Build_package>` page for more info.
It is currently *not* possible to calculate three-body dispersion
contributions according to, for example, the Axilrod-Teller-Muto model.
Related commands
""""""""""""""""
:doc:`pair_coeff <pair_coeff>`
Default
"""""""
none
----------
.. _Grimme1:
**(Grimme1)** S. Grimme, J. Antony, S. Ehrlich, and H. Krieg, J. Chem. Phys. 132, 154104 (2010).
.. _Qamar:
**(Qamar)** M. Qamar, M. Mrovec, T. Lysogorskiy, A. Bochkarev, and R. Drautz, J. Chem. Theory Comput. 19, 5151 (2023).
.. _Batatia:
**(Batatia)** I. Batatia, *et al.*, arXiv:2401.0096 (2023).
.. _Grimme2:
**(Grimme2)** S. Grimme, S. Ehrlich and L. Goerigk, J. Comput. Chem. 32, 1456 (2011).
.. _Sherrill:
**(Sherrill)** D. G. A. Smith, L. A. Burns, K. Patkowski, and C. D. Sherrill, J. Phys. Chem. Lett., 7, 2197, (2016).

View File

@ -172,6 +172,7 @@ accelerated styles exist.
* :doc:`coul/tt <pair_coul_tt>` - damped charge-dipole Coulomb for Drude dipoles
* :doc:`coul/wolf <pair_coul>` - Coulomb via Wolf potential
* :doc:`coul/wolf/cs <pair_cs>` - Coulomb via Wolf potential with core/shell adjustments
* :doc:`dispersion/d3 <pair_dispersion_d3>` - Dispersion correction for potentials derived from DFT functionals
* :doc:`dpd <pair_dpd>` - dissipative particle dynamics (DPD)
* :doc:`dpd/coul/slater/long <pair_dpd_coul_slater_long>` - dissipative particle dynamics (DPD) with electrostatic interactions
* :doc:`dpd/ext <pair_dpd_ext>` - generalized force field for DPD

View File

@ -25,6 +25,7 @@ Ackland
acks
acolor
acos
acs
Acta
actinide
activationfunctions
@ -248,6 +249,7 @@ basename
Bashford
bashrc
Baskes
Batatia
Batra
Bayly
bb
@ -255,6 +257,7 @@ bcc
bcolor
bdiam
bdw
Becke
Beckman
Becton
Behler
@ -313,6 +316,7 @@ bitrate
bitrates
Bitzek
Bjerrum
bjm
Bkappa
blabel
Blaise
@ -1342,6 +1346,7 @@ gmres
gname
gneb
GNEB
Goerigk
Goga
Goldfarb
Gompper
@ -1707,6 +1712,7 @@ Jaramillo
Jarzynski
jatempl
javascript
jcc
jcp
jea
jec
@ -1728,6 +1734,7 @@ Jonsson
Jorgensen
jp
jparam
jpclett
jpeg
jpeglib
jpg
@ -1844,6 +1851,7 @@ Krass
Kraus
Kremer
Kress
Krieg
Kronik
ksh
kspace
@ -1916,6 +1924,7 @@ lB
lbfgs
lbl
LBtype
lc
lcbop
ld
lda
@ -2062,6 +2071,7 @@ ly
Lybrand
Lykotrafitis
lyon
lyp
Lysogorskiy
Lyulin
lz
@ -2827,12 +2837,14 @@ pathangle
pathname
pathnames
Patera
Patkowski
Patomtrans
Pattnaik
Pavese
Pavia
Paxton
pbc
pbe
pc
pcg
pchain
@ -2923,6 +2935,7 @@ ploop
PloS
plt
plumedfile
plyp
pmb
pmcmoves
pme
@ -3065,6 +3078,7 @@ qE
qeff
qelectron
qeq
Qamar
QeQ
QEq
qfactor
@ -3432,6 +3446,7 @@ Shardlow
shawn
Shen
Shenderova
Sherrill
Shi
Shiga
Shinoda
@ -4118,6 +4133,7 @@ workflows
Workum
Worley
wormlike
wpbe
Wriggers
writedata
Wuppertal
@ -4238,6 +4254,7 @@ Zemer
zenodo
Zentrum
Zepeda
zerom
zflag
Zhang
Zhao

View File

@ -0,0 +1,50 @@
# Point dipoles in a 3d box with an external potential (ignoring dipolar interactions)
units lj
atom_style hybrid sphere dipole
dimension 3
boundary s s s
region box block -2 2 -2 2 -2 2
create_box 1 box
create_atoms 1 random 100 12345 NULL
# need both mass settings due to hybrid atom style
mass 1 1.0
set group all mass 1.0
set group all diameter 0.1
set group all dipole/random 98934 0.01
pair_style none
comm_modify cutoff 3.0
velocity all create 0.0 87287 mom yes rot yes
fix 1 all nve/sphere update dipole
###############################################################################################################
## Yukawa potential
#fix 2 all efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A = 0.1; B = 5" step 1e-8
## Gradually increasing uniform field
#variable E equal ramp(0,1)
#fix 2 all efield/lepton "-v_E*(x+y+z)"
## Linear gradient field
fix 2 all efield/lepton "-1/6*x^3" step 1e-6
fix_modify 2 energy yes
###############################################################################################################
timestep 1e-3
compute erot all erotate/sphere
variable etotal equal "ke + c_erot + pe" # thermo etotal doesn't include erot
thermo_style custom step temp ke c_erot pe v_etotal
thermo 500
thermo_modify norm no
#dump 1 all custom 500 dump.dipole id x y z diameter mux muy muz fx fy fz tqx tqy tqz
run 10000

View File

@ -0,0 +1,115 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-283-g742c869534-modified)
using 1 OpenMP thread(s) per MPI task
# Point dipoles in a 3d box with an external potential (ignoring dipolar interactions)
units lj
atom_style hybrid sphere dipole
WARNING: Atom style hybrid defines both, per-type and per-atom masses; both must be set, but only per-atom masses will be used (src/atom_vec_hybrid.cpp:132)
dimension 3
boundary s s s
region box block -2 2 -2 2 -2 2
create_box 1 box
Created orthogonal box = (-2 -2 -2) to (2 2 2)
1 by 1 by 1 MPI processor grid
create_atoms 1 random 100 12345 NULL
Created 100 atoms
using lattice units in orthogonal box = (-2.0004 -2.0004 -2.0004) to (2.0004 2.0004 2.0004)
create_atoms CPU = 0.000 seconds
# need both mass settings due to hybrid atom style
mass 1 1.0
set group all mass 1.0
Setting atom values ...
100 settings made for mass
set group all diameter 0.1
Setting atom values ...
100 settings made for diameter
set group all dipole/random 98934 0.01
Setting atom values ...
100 settings made for dipole/random
pair_style none
comm_modify cutoff 3.0
velocity all create 0.0 87287 mom yes rot yes
fix 1 all nve/sphere update dipole
###############################################################################################################
## Yukawa potential
#fix 2 all efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A = 0.1; B = 5" step 1e-8
## Gradually increasing uniform field
#variable E equal ramp(0,1)
#fix 2 all efield/lepton "-v_E*(x+y+z)"
## Linear gradient field
fix 2 all efield/lepton "-1/6*x^3" step 1e-6
fix_modify 2 energy yes
###############################################################################################################
timestep 1e-3
compute erot all erotate/sphere
variable etotal equal "ke + c_erot + pe" # thermo etotal doesn't include erot
thermo_style custom step temp ke c_erot pe v_etotal
thermo 500
thermo_modify norm no
#dump 1 all custom 500 dump.dipole id x y z diameter mux muy muz fx fy fz tqx tqy tqz
run 10000
WARNING: No pairwise cutoff or binsize set. Atom sorting therefore disabled. (src/atom.cpp:2442)
Per MPI rank memory allocation (min/avg/max) = 4.273 | 4.273 | 4.273 Mbytes
Step Temp KinEng c_erot PotEng v_etotal
0 0 0 0 0.036419797 0.036419797
500 3.7159175e-06 0.00055181374 0.44262618 -0.40675701 0.036420985
1000 1.2808438e-05 0.0019020531 0.24499116 -0.21047295 0.036420259
1500 2.8343769e-05 0.0042090498 0.26504485 -0.2328336 0.036420307
2000 4.8796894e-05 0.0072463388 0.30953526 -0.28036098 0.036420618
2500 7.8933715e-05 0.011721657 0.2015076 -0.17680909 0.036420173
3000 0.00011381678 0.016901791 0.31002163 -0.29050294 0.036420476
3500 0.00015650339 0.023240753 0.27837968 -0.26520001 0.036420418
4000 0.00020429109 0.030337227 0.26201101 -0.25592795 0.036420289
4500 0.00026362339 0.039148074 0.29769952 -0.3004271 0.036420499
5000 0.00033328941 0.049493478 0.21642442 -0.22949776 0.036420131
5500 0.00040914224 0.060757622 0.28422322 -0.30856047 0.036420377
6000 0.00049425119 0.073396302 0.31767 -0.35464572 0.03642058
6500 0.00058508892 0.086885704 0.29079532 -0.34126075 0.036420276
7000 0.00069845073 0.10371993 0.25776048 -0.32506015 0.036420262
7500 0.0008215656 0.12200249 0.27033777 -0.35591972 0.036420539
8000 0.00095528125 0.14185927 0.33943527 -0.44487406 0.036420479
8500 0.0011052502 0.16412965 0.26727165 -0.39498109 0.036420218
9000 0.0012738298 0.18916373 0.31082058 -0.46356382 0.036420485
9500 0.001464197 0.21743325 0.25669856 -0.43771158 0.036420224
10000 0.0016627654 0.24692067 0.36273185 -0.57323194 0.036420578
Loop time of 0.84714 on 1 procs for 10000 steps with 100 atoms
Performance: 1019901.911 tau/day, 11804.420 timesteps/s, 1.180 Matom-step/s
62.3% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0 | 0 | 0 | 0.0 | 0.00
Neigh | 9.21e-07 | 9.21e-07 | 9.21e-07 | 0.0 | 0.00
Comm | 0.00094138 | 0.00094138 | 0.00094138 | 0.0 | 0.11
Output | 0.0001983 | 0.0001983 | 0.0001983 | 0.0 | 0.02
Modify | 0.84105 | 0.84105 | 0.84105 | 0.0 | 99.28
Other | | 0.004946 | | | 0.58
Nlocal: 100 ave 100 max 100 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 0 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 0 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 0
Ave neighs/atom = 0
Neighbor list builds = 5
Dangerous builds = 0
Total wall time: 0:00:00

View File

@ -0,0 +1,115 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-283-g742c869534-modified)
using 1 OpenMP thread(s) per MPI task
# Point dipoles in a 3d box with an external potential (ignoring dipolar interactions)
units lj
atom_style hybrid sphere dipole
WARNING: Atom style hybrid defines both, per-type and per-atom masses; both must be set, but only per-atom masses will be used (src/atom_vec_hybrid.cpp:132)
dimension 3
boundary s s s
region box block -2 2 -2 2 -2 2
create_box 1 box
Created orthogonal box = (-2 -2 -2) to (2 2 2)
1 by 2 by 2 MPI processor grid
create_atoms 1 random 100 12345 NULL
Created 100 atoms
using lattice units in orthogonal box = (-2.0004 -2.0004 -2.0004) to (2.0004 2.0004 2.0004)
create_atoms CPU = 0.000 seconds
# need both mass settings due to hybrid atom style
mass 1 1.0
set group all mass 1.0
Setting atom values ...
100 settings made for mass
set group all diameter 0.1
Setting atom values ...
100 settings made for diameter
set group all dipole/random 98934 0.01
Setting atom values ...
100 settings made for dipole/random
pair_style none
comm_modify cutoff 3.0
velocity all create 0.0 87287 mom yes rot yes
fix 1 all nve/sphere update dipole
###############################################################################################################
## Yukawa potential
#fix 2 all efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A = 0.1; B = 5" step 1e-8
## Gradually increasing uniform field
#variable E equal ramp(0,1)
#fix 2 all efield/lepton "-v_E*(x+y+z)"
## Linear gradient field
fix 2 all efield/lepton "-1/6*x^3" step 1e-6
fix_modify 2 energy yes
###############################################################################################################
timestep 1e-3
compute erot all erotate/sphere
variable etotal equal "ke + c_erot + pe" # thermo etotal doesn't include erot
thermo_style custom step temp ke c_erot pe v_etotal
thermo 500
thermo_modify norm no
#dump 1 all custom 500 dump.dipole id x y z diameter mux muy muz fx fy fz tqx tqy tqz
run 10000
WARNING: No pairwise cutoff or binsize set. Atom sorting therefore disabled. (src/atom.cpp:2442)
Per MPI rank memory allocation (min/avg/max) = 4.289 | 4.289 | 4.289 Mbytes
Step Temp KinEng c_erot PotEng v_etotal
0 0 0 0 0.036419797 0.036419797
500 3.7159175e-06 0.00055181374 0.44262618 -0.40675701 0.036420985
1000 1.2808438e-05 0.0019020531 0.24499116 -0.21047295 0.036420259
1500 2.8343769e-05 0.0042090498 0.26504485 -0.2328336 0.036420307
2000 4.8796894e-05 0.0072463388 0.30953526 -0.28036098 0.036420618
2500 7.8933715e-05 0.011721657 0.2015076 -0.17680909 0.036420173
3000 0.00011381678 0.016901791 0.31002163 -0.29050294 0.036420476
3500 0.00015650339 0.023240753 0.27837968 -0.26520001 0.036420418
4000 0.00020429109 0.030337227 0.26201101 -0.25592795 0.036420289
4500 0.00026362339 0.039148074 0.29769952 -0.3004271 0.036420499
5000 0.00033328941 0.049493478 0.21642442 -0.22949776 0.036420131
5500 0.00040914224 0.060757622 0.28422322 -0.30856047 0.036420377
6000 0.00049425119 0.073396302 0.31767 -0.35464572 0.03642058
6500 0.00058508892 0.086885704 0.29079532 -0.34126075 0.036420276
7000 0.00069845073 0.10371993 0.25776048 -0.32506015 0.036420262
7500 0.0008215656 0.12200249 0.27033777 -0.35591972 0.036420539
8000 0.00095528125 0.14185927 0.33943527 -0.44487406 0.036420479
8500 0.0011052502 0.16412965 0.26727165 -0.39498109 0.036420218
9000 0.0012738298 0.18916373 0.31082058 -0.46356382 0.036420485
9500 0.001464197 0.21743325 0.25669856 -0.43771158 0.036420224
10000 0.0016627654 0.24692067 0.36273185 -0.57323194 0.036420578
Loop time of 0.985035 on 4 procs for 10000 steps with 100 atoms
Performance: 877125.838 tau/day, 10151.919 timesteps/s, 1.015 Matom-step/s
67.7% CPU use with 4 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0 | 0 | 0 | 0.0 | 0.00
Neigh | 7.22e-07 | 8.9125e-07 | 1.031e-06 | 0.0 | 0.00
Comm | 0.09818 | 0.1024 | 0.10798 | 1.1 | 10.40
Output | 0.00021634 | 0.00028668 | 0.00044312 | 0.0 | 0.03
Modify | 0.773 | 0.81845 | 0.84055 | 3.0 | 83.09
Other | | 0.06389 | | | 6.49
Nlocal: 25 ave 30 max 23 min
Histogram: 2 1 0 0 0 0 0 0 0 1
Nghost: 75 ave 77 max 70 min
Histogram: 1 0 0 0 0 0 0 0 1 2
Neighs: 0 ave 0 max 0 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Total # of neighbors = 0
Ave neighs/atom = 0
Neighbor list builds = 5
Dangerous builds = 0
Total wall time: 0:00:00

View File

@ -0,0 +1,6 @@
To run these examples, one needs to compile LAMMPS with the ML-PACE (-DPKG_ML-PACE=ON) and the EXTRA-PAIR packages (-DPKG_EXTRA-PAIR=ON).
These examples show how to combine a short-ranged ML potential with a dispersion correction scheme. Here we combine a general-purpose ACE potential for carbon (10.1021/acs.jctc.2c01149), with two different dispersion correction schemes:
- D2 (a pure two-body potential, here tabulated)
- D3 (a many-body potential, implemented in LAMMPS).

View File

@ -0,0 +1,36 @@
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
region box block 0 10 0 10 0 10
create_box 1 box
create_atoms 1 region box
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace table linear 10000
pair_coeff * * pace potential_files/c_ace.yace C
pair_coeff * * table potential_files/d2.table D2 9.0
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair table
# calculate the e/atom for each pair style individually
variable dUpace equal c_c1/atoms
variable dUd2 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_dUpace v_dUd2
thermo 10
run 100

View File

@ -0,0 +1,36 @@
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
region box block 0 10 0 10 0 10
create_box 1 box
create_atoms 1 region box
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace dispersion/d3 bj pbe 16.0 16.0
pair_coeff * * pace potential_files/c_ace.yace C
pair_coeff * * dispersion/d3 C
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair dispersion/d3
# calculate the e/atom for each pair style individually
variable Upace equal c_c1/atoms
variable Ud3 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_Upace v_Ud3
thermo 10
run 100

View File

@ -0,0 +1,122 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-125-g095d33dafb)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:99)
using 1 OpenMP thread(s) per MPI task
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
region box block 0 10 0 10 0 10
create_box 1 box
Created orthogonal box = (0 0 0) to (10 10 10)
1 by 1 by 1 MPI processor grid
create_atoms 1 region box
Created 1000 atoms
using lattice units in orthogonal box = (0 0 0) to (10 10 10)
create_atoms CPU = 0.000 seconds
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 47.6 remap
Changing box ...
orthogonal box = (0 0 0) to (47.6 10 10)
orthogonal box = (0 0 0) to (47.6 47.6 10)
orthogonal box = (0 0 0) to (47.6 47.6 47.6)
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace table linear 10000
ACE version: 2023.11.25
Recursive evaluator is used
pair_coeff * * pace potential_files/c_ace.yace C
Loading potential_files/c_ace.yace
Total number of basis functions
C: 20 (r=1) 455 (r>1)
Mapping LAMMPS atom type #1(C) -> ACE species type #0
pair_coeff * * table potential_files/d2.table D2 9.0
Reading pair table potential file potential_files/d2.table with DATE: 2021-12-16
WARNING: 8063 of 20000 force values in table D2 are inconsistent with -dE/dr.
WARNING: Should only be flagged at inflection points (src/pair_table.cpp:466)
WARNING: 2386 of 20000 distance values in table 1e-06 with relative error
WARNING: over D2 to re-computed values (src/pair_table.cpp:474)
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair table
# calculate the e/atom for each pair style individually
variable dUpace equal c_c1/atoms
variable dUd2 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_dUpace v_dUd2
thermo 10
run 100
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 11
ghost atom cutoff = 11
binsize = 5.5, bins = 9 9 9
2 neighbor lists, perpetual/occasional/extra = 2 0 0
(1) pair pace, perpetual
attributes: full, newton on, cut 7.5
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
(2) pair table, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 3.735 | 3.735 | 3.735 Mbytes
Step Temp PotEng Press TotEng v_dUpace v_dUd2
0 200 -262.26589 -9971.6713 -236.43971 -0.2577066 -0.0045592958
10 198.01563 -261.95164 -9936.5218 -236.38171 -0.25738489 -0.004566747
20 199.80384 -261.06484 -9826.0969 -235.26399 -0.25647577 -0.0045890709
30 200.79867 -259.7549 -9655.8924 -233.82559 -0.25512792 -0.0046269853
40 194.7303 -258.36397 -9450.9508 -233.21827 -0.25368377 -0.004680203
50 197.08802 -257.40377 -9200.5727 -231.95362 -0.25265301 -0.0047507608
60 204.21755 -257.66495 -8919.2309 -231.29416 -0.25282305 -0.0048419012
70 216.81983 -260.19034 -8702.5441 -232.19221 -0.25523198 -0.0049583602
80 242.71952 -266.40641 -8617.9868 -235.06383 -0.26129243 -0.0051139831
90 294.45869 -279.46195 -8724.2954 -241.43824 -0.27411961 -0.0053423377
100 400.44323 -307.29577 -9070.6387 -255.58618 -0.30165815 -0.0056376175
Loop time of 2.66184 on 1 procs for 100 steps with 1000 atoms
Performance: 3.246 ns/day, 7.394 hours/ns, 37.568 timesteps/s, 37.568 katom-step/s
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 2.6584 | 2.6584 | 2.6584 | 0.0 | 99.87
Neigh | 0.0012861 | 0.0012861 | 0.0012861 | 0.0 | 0.05
Comm | 0.00064617 | 0.00064617 | 0.00064617 | 0.0 | 0.02
Output | 0.00024173 | 0.00024173 | 0.00024173 | 0.0 | 0.01
Modify | 0.00099328 | 0.00099328 | 0.00099328 | 0.0 | 0.04
Other | | 0.0002431 | | | 0.01
Nlocal: 1000 ave 1000 max 1000 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 2375 ave 2375 max 2375 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 26027 ave 26027 max 26027 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 17736 ave 17736 max 17736 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 26027
Ave neighs/atom = 26.027
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:02

View File

@ -0,0 +1,122 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-125-g095d33dafb)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:99)
using 1 OpenMP thread(s) per MPI task
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
region box block 0 10 0 10 0 10
create_box 1 box
Created orthogonal box = (0 0 0) to (10 10 10)
1 by 2 by 2 MPI processor grid
create_atoms 1 region box
Created 1000 atoms
using lattice units in orthogonal box = (0 0 0) to (10 10 10)
create_atoms CPU = 0.000 seconds
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 47.6 remap
Changing box ...
orthogonal box = (0 0 0) to (47.6 10 10)
orthogonal box = (0 0 0) to (47.6 47.6 10)
orthogonal box = (0 0 0) to (47.6 47.6 47.6)
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace table linear 10000
ACE version: 2023.11.25
Recursive evaluator is used
pair_coeff * * pace potential_files/c_ace.yace C
Loading potential_files/c_ace.yace
Total number of basis functions
C: 20 (r=1) 455 (r>1)
Mapping LAMMPS atom type #1(C) -> ACE species type #0
pair_coeff * * table potential_files/d2.table D2 9.0
Reading pair table potential file potential_files/d2.table with DATE: 2021-12-16
WARNING: 8063 of 20000 force values in table D2 are inconsistent with -dE/dr.
WARNING: Should only be flagged at inflection points (src/pair_table.cpp:466)
WARNING: 2386 of 20000 distance values in table 1e-06 with relative error
WARNING: over D2 to re-computed values (src/pair_table.cpp:474)
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair table
# calculate the e/atom for each pair style individually
variable dUpace equal c_c1/atoms
variable dUd2 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_dUpace v_dUd2
thermo 10
run 100
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 11
ghost atom cutoff = 11
binsize = 5.5, bins = 9 9 9
2 neighbor lists, perpetual/occasional/extra = 2 0 0
(1) pair pace, perpetual
attributes: full, newton on, cut 7.5
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
(2) pair table, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 3.655 | 3.655 | 3.655 Mbytes
Step Temp PotEng Press TotEng v_dUpace v_dUd2
0 200 -262.26589 -9971.6713 -236.43971 -0.2577066 -0.0045592958
10 198.00622 -261.95011 -9934.5046 -236.38139 -0.25738304 -0.0045670733
20 199.81545 -261.06219 -9818.4051 -235.25985 -0.25647183 -0.0045903655
30 200.85902 -259.76256 -9639.9086 -233.82546 -0.25513263 -0.0046299265
40 195.00229 -258.4153 -9425.3772 -233.23448 -0.25372979 -0.0046855071
50 198.00573 -257.57066 -9164.7658 -232.00201 -0.25281159 -0.0047590772
60 206.26759 -258.09159 -8877.0162 -231.45607 -0.25323684 -0.0048547477
70 219.81939 -261.10607 -8668.5789 -232.7206 -0.25612771 -0.0049783595
80 250.27428 -268.27862 -8601.1343 -235.96048 -0.2631332 -0.0051454143
90 308.88167 -283.24793 -8745.8792 -243.36177 -0.27785093 -0.0053969977
100 427.60692 -315.05776 -9147.2389 -259.8405 -0.30933434 -0.0057234269
Loop time of 0.69628 on 4 procs for 100 steps with 1000 atoms
Performance: 12.409 ns/day, 1.934 hours/ns, 143.620 timesteps/s, 143.620 katom-step/s
99.5% CPU use with 4 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.67839 | 0.68307 | 0.69054 | 0.6 | 98.10
Neigh | 0.00034181 | 0.00034811 | 0.00036188 | 0.0 | 0.05
Comm | 0.0045334 | 0.012031 | 0.016704 | 4.4 | 1.73
Output | 0.00015123 | 0.00017175 | 0.0002318 | 0.0 | 0.02
Modify | 0.00041346 | 0.00043062 | 0.00044327 | 0.0 | 0.06
Other | | 0.0002301 | | | 0.03
Nlocal: 250 ave 261 max 246 min
Histogram: 3 0 0 0 0 0 0 0 0 1
Nghost: 1250 ave 1254 max 1239 min
Histogram: 1 0 0 0 0 0 0 0 0 3
Neighs: 6501 ave 6778 max 6320 min
Histogram: 1 0 2 0 0 0 0 0 0 1
FullNghs: 4421.5 ave 4595 max 4332 min
Histogram: 1 2 0 0 0 0 0 0 0 1
Total # of neighbors = 26004
Ave neighs/atom = 26.004
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:00

View File

@ -0,0 +1,117 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-125-g095d33dafb)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:99)
using 1 OpenMP thread(s) per MPI task
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
region box block 0 10 0 10 0 10
create_box 1 box
Created orthogonal box = (0 0 0) to (10 10 10)
1 by 1 by 1 MPI processor grid
create_atoms 1 region box
Created 1000 atoms
using lattice units in orthogonal box = (0 0 0) to (10 10 10)
create_atoms CPU = 0.000 seconds
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 47.6 remap
Changing box ...
orthogonal box = (0 0 0) to (47.6 10 10)
orthogonal box = (0 0 0) to (47.6 47.6 10)
orthogonal box = (0 0 0) to (47.6 47.6 47.6)
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace dispersion/d3 bj pbe 16.0 16.0
ACE version: 2023.11.25
Recursive evaluator is used
pair_coeff * * pace potential_files/c_ace.yace C
Loading potential_files/c_ace.yace
Total number of basis functions
C: 20 (r=1) 455 (r>1)
Mapping LAMMPS atom type #1(C) -> ACE species type #0
pair_coeff * * dispersion/d3 C
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair dispersion/d3
# calculate the e/atom for each pair style individually
variable Upace equal c_c1/atoms
variable Ud3 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_Upace v_Ud3
thermo 10
run 100
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 18
ghost atom cutoff = 18
binsize = 9, bins = 6 6 6
2 neighbor lists, perpetual/occasional/extra = 2 0 0
(1) pair pace, perpetual
attributes: full, newton on, cut 7.5
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
(2) pair dispersion/d3, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 4.225 | 4.225 | 4.225 Mbytes
Step Temp PotEng Press TotEng v_Upace v_Ud3
0 200 -269.22784 -10163.81 -243.40166 -0.2577066 -0.011521241
10 198.05578 -268.91992 -10128.61 -243.34481 -0.25738487 -0.01153505
20 199.85092 -268.05146 -10018.116 -242.24454 -0.25647561 -0.011575851
30 201.10902 -266.77119 -9847.2946 -240.80181 -0.2551274 -0.011643795
40 195.0686 -265.42225 -9641.6992 -240.23287 -0.25368339 -0.011738855
50 197.63706 -264.51951 -9390.1455 -238.99847 -0.25265765 -0.011861864
60 205.01072 -264.86268 -9107.4427 -238.38947 -0.25284579 -0.012016888
70 217.51797 -267.50863 -8890.9916 -239.42034 -0.25529813 -0.012210496
80 244.30754 -273.91051 -8806.154 -242.36286 -0.26145652 -0.01245399
90 296.72041 -287.2518 -8913.8963 -248.93603 -0.27448382 -0.012767981
100 404.07337 -315.6103 -9266.1292 -263.43195 -0.3024416 -0.013168694
Loop time of 4.52709 on 1 procs for 100 steps with 1000 atoms
Performance: 1.909 ns/day, 12.575 hours/ns, 22.089 timesteps/s, 22.089 katom-step/s
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 4.5223 | 4.5223 | 4.5223 | 0.0 | 99.89
Neigh | 0.0023631 | 0.0023631 | 0.0023631 | 0.0 | 0.05
Comm | 0.00088624 | 0.00088624 | 0.00088624 | 0.0 | 0.02
Output | 0.00027759 | 0.00027759 | 0.00027759 | 0.0 | 0.01
Modify | 0.0010211 | 0.0010211 | 0.0010211 | 0.0 | 0.02
Other | | 0.0002737 | | | 0.01
Nlocal: 1000 ave 1000 max 1000 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 3913 ave 3913 max 3913 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 116409 ave 116409 max 116409 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 17748 ave 17748 max 17748 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 116409
Ave neighs/atom = 116.409
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:04

View File

@ -0,0 +1,117 @@
LAMMPS (19 Nov 2024 - Development - patch_19Nov2024-125-g095d33dafb)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:99)
using 1 OpenMP thread(s) per MPI task
atom_style atomic
units metal
boundary p p p
atom_modify sort 0 0.0
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
region box block 0 10 0 10 0 10
create_box 1 box
Created orthogonal box = (0 0 0) to (10 10 10)
1 by 2 by 2 MPI processor grid
create_atoms 1 region box
Created 1000 atoms
using lattice units in orthogonal box = (0 0 0) to (10 10 10)
create_atoms CPU = 0.000 seconds
variable l equal 47.6
change_box all x final 0 $l y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 $l z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 $l remap
change_box all x final 0 47.6 y final 0 47.6 z final 0 47.6 remap
Changing box ...
orthogonal box = (0 0 0) to (47.6 10 10)
orthogonal box = (0 0 0) to (47.6 47.6 10)
orthogonal box = (0 0 0) to (47.6 47.6 47.6)
region world block INF INF INF INF INF INF
### interactions
pair_style hybrid/overlay pace dispersion/d3 bj pbe 16.0 16.0
ACE version: 2023.11.25
Recursive evaluator is used
pair_coeff * * pace potential_files/c_ace.yace C
Loading potential_files/c_ace.yace
Total number of basis functions
C: 20 (r=1) 455 (r>1)
Mapping LAMMPS atom type #1(C) -> ACE species type #0
pair_coeff * * dispersion/d3 C
mass 1 12.011000
velocity all create 200 1234
compute c1 all pair pace
compute c2 all pair dispersion/d3
# calculate the e/atom for each pair style individually
variable Upace equal c_c1/atoms
variable Ud3 equal c_c2/atoms
### run
timestep 0.001
fix 1 all nvt temp 200.0 200.0 0.01
thermo_style custom step temp pe press etotal v_Upace v_Ud3
thermo 10
run 100
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 18
ghost atom cutoff = 18
binsize = 9, bins = 6 6 6
2 neighbor lists, perpetual/occasional/extra = 2 0 0
(1) pair pace, perpetual
attributes: full, newton on, cut 7.5
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
(2) pair dispersion/d3, perpetual
attributes: half, newton on
pair build: half/bin/atomonly/newton
stencil: half/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 3.732 | 3.732 | 3.732 Mbytes
Step Temp PotEng Press TotEng v_Upace v_Ud3
0 200 -269.22784 -10163.81 -243.40166 -0.2577066 -0.011521241
10 198.04813 -268.91867 -10126.59 -243.34454 -0.25738301 -0.011535654
20 199.86491 -268.04994 -10010.421 -242.24121 -0.25647167 -0.011578276
30 201.18317 -266.78129 -9831.2837 -240.80233 -0.25513213 -0.011649162
40 195.35281 -265.47802 -9616.0833 -240.25194 -0.2537296 -0.011748422
50 198.56247 -264.69401 -9354.3017 -239.05347 -0.25281709 -0.011876925
60 207.17238 -265.30194 -9065.1196 -238.54959 -0.25326251 -0.012039431
70 221.05245 -268.44583 -8856.3622 -239.90114 -0.25620278 -0.012243053
80 252.00942 -275.82142 -8789.4126 -243.27922 -0.26332044 -0.012500977
90 311.21153 -291.09334 -8935.4036 -250.90632 -0.27825852 -0.012834817
100 431.24438 -323.45003 -9344.1963 -267.76306 -0.31019084 -0.013259185
Loop time of 1.20684 on 4 procs for 100 steps with 1000 atoms
Performance: 7.159 ns/day, 3.352 hours/ns, 82.861 timesteps/s, 82.861 katom-step/s
99.4% CPU use with 4 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 1.2007 | 1.2019 | 1.2029 | 0.1 | 99.60
Neigh | 0.00060541 | 0.00062493 | 0.00064411 | 0.0 | 0.05
Comm | 0.0024344 | 0.0033552 | 0.0045996 | 1.4 | 0.28
Output | 0.00016956 | 0.00017999 | 0.00021054 | 0.0 | 0.01
Modify | 0.00046946 | 0.00048235 | 0.00049796 | 0.0 | 0.04
Other | | 0.0002449 | | | 0.02
Nlocal: 250 ave 261 max 246 min
Histogram: 3 0 0 0 0 0 0 0 0 1
Nghost: 2198 ave 2202 max 2187 min
Histogram: 1 0 0 0 0 0 0 0 0 3
Neighs: 29023.2 ave 29681 max 27646 min
Histogram: 1 0 0 0 0 0 0 1 0 2
FullNghs: 4421 ave 4595 max 4331 min
Histogram: 1 2 0 0 0 0 0 0 0 1
Total # of neighbors = 116093
Ave neighs/atom = 116.093
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:01

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

5
src/.gitignore vendored
View File

@ -95,6 +95,8 @@
/angle_lepton.h
/dihedral_lepton.cpp
/dihedral_lepton.h
/fix_efield_lepton.cpp
/fix_efield_lepton.h
/fix_wall_lepton.cpp
/fix_wall_lepton.h
/lepton_utils.cpp
@ -1219,6 +1221,9 @@
/pair_dipole_cut.h
/pair_dipole_sf.cpp
/pair_dipole_sf.h
/d3_parameters.h
/pair_dispersion_d3.h
/pair_dispersion_d3.cpp
/pair_dsmc.cpp
/pair_dsmc.h
/pair_e3b.cpp

33960
src/EXTRA-PAIR/d3_parameters.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
// clang-format off
PairStyle(dispersion/d3,PairDispersionD3);
// clang-format on
#else
#ifndef LMP_PAIR_DISPERSION_D3_H
#define LMP_PAIR_DISPERSION_D3_H
#include "pair.h"
namespace LAMMPS_NS {
class PairDispersionD3 : public Pair {
public:
PairDispersionD3(class LAMMPS *);
~PairDispersionD3() override;
void compute(int, int) override;
void settings(int, char **) override;
void coeff(int, char **) override;
void init_style() override;
double init_one(int, int) override;
int pack_forward_comm(int, int *, double *, int, int *) override;
int pack_reverse_comm(int, int, double *) override;
void unpack_forward_comm(int, int, double *) override;
void unpack_reverse_comm(int, int *, double *) override;
protected:
int nmax;
double evdwl;
double rthr; // R^2 distance to cutoff for D3_calculation
double cn_thr; // R^2 distance to cutoff for CN_calculation
std::string damping_type; // damping function type
double s6, s8, s18, rs6, rs8, rs18; // XC parameters
double a1, a2, alpha, alpha6, alpha8;
double* r2r4 = nullptr; // scale r4/r2 values of the atoms by sqrt(Z)
double* rcov = nullptr; // covalent radii
int* mxci = nullptr; // How large the grid for c6 interpolation
double** r0ab = nullptr; // cut-off radii for all element pairs
double***** c6ab = nullptr; // C6 for all element pairs
double* cn = nullptr; // Coordination numbers
double* dc6 = nullptr; // dC6i(iat) saves dE_dsp/dCN(iat)
int communicationStage; // communication stage
void allocate();
virtual void set_funcpar(std::string&);
void calc_coordination_number();
int find_atomic_number(std::string&);
std::vector<int> is_int_in_array(int*, int, int);
void read_r0ab(int*, int);
void set_limit_in_pars_array(int&, int&, int&, int&);
void read_c6ab(int*, int);
double* get_dC6(int, int, double, double);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,373 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Gabriel Alkuino (Syracuse University) - gsalkuin@syr.edu
Modified from fix_efield
------------------------------------------------------------------------- */
#include "fix_efield_lepton.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "input.h"
#include "modify.h"
#include "region.h"
#include "respa.h"
#include "update.h"
#include <array>
#include "Lepton.h"
#include "lepton_utils.h"
using namespace LAMMPS_NS;
using namespace FixConst;
#define EPSILON 1.0e-10
/* ---------------------------------------------------------------------- */
FixEfieldLepton::FixEfieldLepton(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), idregion(nullptr), region(nullptr)
{
if (domain->xperiodic || domain->yperiodic || domain->zperiodic) {
error->warning(FLERR, "Fix {} uses unwrapped coordinates", style);
}
if (narg < 4) utils::missing_cmd_args(FLERR, std::string("fix ") + style, error);
scalar_flag = 1;
global_freq = 1;
extscalar = 1;
energy_global_flag = 1;
virial_global_flag = virial_peratom_flag = 1;
respa_level_support = 1;
ilevel_respa = 0;
// optional args
int iarg = 4;
while (iarg < narg) {
if (strcmp(arg[iarg], "region") == 0) {
if (iarg + 2 > narg)
utils::missing_cmd_args(FLERR, std::string("fix ") + style + " region", error);
region = domain->get_region_by_id(arg[iarg + 1]);
if (!region) error->all(FLERR, "Region {} for fix {} does not exist", arg[iarg + 1], style);
idregion = utils::strdup(arg[iarg + 1]);
iarg += 2;
} else if (strcmp(arg[iarg], "step") == 0) {
if (iarg + 2 > narg)
utils::missing_cmd_args(FLERR, std::string("fix ") + style + "step", error);
h = utils::numeric(FLERR, arg[iarg+1], false, lmp);
iarg += 2;
} else {
error->all(FLERR, "Unknown keyword for fix {} command: {}", style, arg[iarg]);
}
}
// check validity of Lepton expression
// remove whitespace and quotes from expression string and then
// check if the expression can be parsed without error
expr = LeptonUtils::condense(arg[3]);
try {
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp));
auto phi = parsed.createCompiledExpression();
} catch (std::exception &e) {
error->all(FLERR, e.what());
}
force_flag = 0;
fsum[0] = fsum[1] = fsum[2] = fsum[3] = 0.0;
}
/* ---------------------------------------------------------------------- */
FixEfieldLepton::~FixEfieldLepton()
{
delete[] idregion;
}
/* ---------------------------------------------------------------------- */
int FixEfieldLepton::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixEfieldLepton::init()
{
if (!atom->q_flag && !atom->mu_flag)
error->all(FLERR, "Fix {} requires atom attribute q or mu", style);
if (atom->mu_flag && !atom->torque_flag)
error->all(FLERR, "Dipoles must be finite-sized to rotate", style);
// set index and check validity of region
if (idregion) {
region = domain->get_region_by_id(idregion);
if (!region) error->all(FLERR, "Region {} for fix {} does not exist", idregion, style);
}
if (utils::strmatch(update->integrate_style, "^respa")) {
ilevel_respa = (dynamic_cast<Respa *>(update->integrate))->nlevels - 1;
if (respa_level >= 0) ilevel_respa = MIN(respa_level, ilevel_respa);
}
// unit conversion factors and restrictions (see issue #1377)
char *unit_style = update->unit_style;
qe2f = force->qe2f;
mue2e = qe2f;
if (strcmp(unit_style, "electron") == 0 || strcmp(unit_style, "micro") == 0 || strcmp(unit_style, "nano") == 0) {
error->all(FLERR, "Fix {} does not support {} units", style, unit_style);
}
}
/* ---------------------------------------------------------------------- */
void FixEfieldLepton::setup(int vflag)
{
if (utils::strmatch(update->integrate_style, "^respa")) {
auto respa = dynamic_cast<Respa *>(update->integrate);
respa->copy_flevel_f(ilevel_respa);
post_force_respa(vflag, ilevel_respa, 0);
respa->copy_f_flevel(ilevel_respa);
} else {
post_force(vflag);
}
}
/* ---------------------------------------------------------------------- */
void FixEfieldLepton::min_setup(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
Apply F = qE,
F = (mu . D) E,
T = mu x E
------------------------------------------------------------------------- */
void FixEfieldLepton::post_force(int vflag)
{
double **f = atom->f;
double **x = atom->x;
int *mask = atom->mask;
imageint *image = atom->image;
int nlocal = atom->nlocal;
auto parsed = Lepton::Parser::parse(LeptonUtils::substitute(expr, lmp)).optimize();
Lepton::CompiledExpression phi;
auto dphi_x = parsed.differentiate("x").createCompiledExpression();
auto dphi_y = parsed.differentiate("y").createCompiledExpression();
auto dphi_z = parsed.differentiate("z").createCompiledExpression();
std::array<Lepton::CompiledExpression*, 3> dphis = {&dphi_x, &dphi_y, &dphi_z};
// array of vectors of ptrs to Lepton variable references
std::array<std::vector<double *>, 3> var_ref_ptrs{};
// fill ptr-vectors with Lepton refs as needed
const char* DIM_NAMES[] = {"x", "y", "z"};
if (atom->q_flag){
phi = parsed.createCompiledExpression();
for (size_t d = 0; d < 3; d++) {
try {
double *ptr = &(phi.getVariableReference(DIM_NAMES[d]));
var_ref_ptrs[d].push_back(ptr);
} catch (Lepton::Exception &) {
// do nothing
}
}
}
bool e_uniform = true;
for (size_t j = 0; j < 3; j++)
for (size_t d = 0; d < 3; d++) {
try {
double *ptr = &((*dphis[j]).getVariableReference(DIM_NAMES[d]));
var_ref_ptrs[d].push_back(ptr);
e_uniform = false;
}
catch (Lepton::Exception &) {
// do nothing
}
}
if (!e_uniform && atom->mu_flag && h < 0) {
error->all(FLERR, "Fix {} requires keyword `step' for dipoles in a non-uniform electric field", style);
}
// virial setup
v_init(vflag);
// update region if necessary
if (region) region->prematch();
// fsum[0] = "potential energy" for added force
// fsum[123] = extra force added to atoms
fsum[0] = fsum[1] = fsum[2] = fsum[3] = 0.0;
force_flag = 0;
double ex, ey, ez;
double fx, fy, fz;
double v[6], unwrap[3], dstep[3];
double xf, yf, zf, xb, yb, zb;
double exf, eyf, ezf, exb, eyb, ezb;
double mu_norm, h_mu;
double *q = atom->q;
double **mu = atom->mu;
double **t = atom->torque;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (region && !region->match(x[i][0], x[i][1], x[i][2])) continue;
fx = fy = fz = 0.0;
domain->unmap(x[i], image[i], unwrap);
// put unwrapped coords into Lepton variable refs
for (size_t d = 0; d < 3; d++) {
for (auto & var_ref_ptr : var_ref_ptrs[d]) {
*var_ref_ptr = unwrap[d];
}
}
// evaluate e-field, used by q and mu
ex = -dphi_x.evaluate();
ey = -dphi_y.evaluate();
ez = -dphi_z.evaluate();
// charges
// force = q E
if (atom->q_flag) {
fx = qe2f * q[i] * ex;
fy = qe2f * q[i] * ey;
fz = qe2f * q[i] * ez;
// potential energy = q phi
fsum[0] += qe2f * q[i] * phi.evaluate();
}
if (atom->mu_flag) {
// dipoles
mu_norm = sqrt(mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]);
if (mu_norm > EPSILON) {
// torque = mu cross E
t[i][0] += mue2e * (ez * mu[i][1] - ey * mu[i][2]);
t[i][1] += mue2e * (ex * mu[i][2] - ez * mu[i][0]);
t[i][2] += mue2e * (ey * mu[i][0] - ex * mu[i][1]);
// potential energy = - mu dot E
fsum[0] -= mue2e * (mu[i][0] * ex + mu[i][1] * ey + mu[i][2] * ez);
// force = (mu dot D) E for non-uniform E
// using central difference method
if (!e_uniform) {
h_mu = h / mu_norm;
dstep[0] = h_mu * mu[i][0];
dstep[1] = h_mu * mu[i][1];
dstep[2] = h_mu * mu[i][2];
// one step forwards, two steps back ;)
for (size_t d = 0; d < 3; d++) {
for (auto & var_ref_ptr : var_ref_ptrs[d]) {
*var_ref_ptr += dstep[d];
}
}
exf = -dphi_x.evaluate();
eyf = -dphi_y.evaluate();
ezf = -dphi_z.evaluate();
for (size_t d = 0; d < 3; d++) {
for (auto & var_ref_ptr : var_ref_ptrs[d]) {
*var_ref_ptr -= 2*dstep[d];
}
}
exb = -dphi_x.evaluate();
eyb = -dphi_y.evaluate();
ezb = -dphi_z.evaluate();
fx += qe2f * (exf - exb) / 2.0 / h_mu;
fy += qe2f * (eyf - eyb) / 2.0 / h_mu;
fz += qe2f * (ezf - ezb) / 2.0 / h_mu;
}
}
}
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
fsum[1] += fx;
fsum[2] += fy;
fsum[3] += fz;
if (evflag) {
v[0] = fx * unwrap[0];
v[1] = fy * unwrap[1];
v[2] = fz * unwrap[2];
v[3] = fx * unwrap[1];
v[4] = fx * unwrap[2];
v[5] = fy * unwrap[2];
v_tally(i, v);
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixEfieldLepton::post_force_respa(int vflag, int ilevel, int /*iloop*/)
{
if (ilevel == ilevel_respa) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixEfieldLepton::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
return energy added by fix
------------------------------------------------------------------------- */
double FixEfieldLepton::compute_scalar()
{
if (force_flag == 0) {
MPI_Allreduce(fsum, fsum_all, 4, MPI_DOUBLE, MPI_SUM, world);
force_flag = 1;
}
return fsum_all[0];
}
/* ----------------------------------------------------------------------
return total extra force due to fix
------------------------------------------------------------------------- */
double FixEfieldLepton::compute_vector(int n)
{
if (force_flag == 0) {
MPI_Allreduce(fsum, fsum_all, 4, MPI_DOUBLE, MPI_SUM, world);
force_flag = 1;
}
return fsum_all[n + 1];
}

View File

@ -0,0 +1,60 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Gabriel Alkuino (Syracuse University) - gsalkuin@syr.edu
Modified from fix_efield
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(efield/lepton,FixEfieldLepton);
// clang-format on
#else
#ifndef LMP_FIX_EFIELD_LEPTON_H
#define LMP_FIX_EFIELD_LEPTON_H
#include "fix.h"
namespace LAMMPS_NS {
class FixEfieldLepton : public Fix {
public:
FixEfieldLepton(class LAMMPS *, int, char **);
~FixEfieldLepton() override;
int setmask() override;
void init() override;
void setup(int) override;
void min_setup(int) override;
void post_force(int) override;
void post_force_respa(int, int, int) override;
void min_post_force(int) override;
double compute_scalar() override;
double compute_vector(int) override;
protected:
char *idregion;
class Region *region;
int ilevel_respa;
std::string expr;
int force_flag;
double h = -1.0;
double qe2f, mue2e;
double fsum[4], fsum_all[4];
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -17,7 +17,6 @@
#include "format.h" // std_string_view
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T> struct is_reference_wrapper : std::false_type {};
@ -72,19 +71,13 @@ class dynamic_arg_list {
* It can be implicitly converted into `fmt::basic_format_args` for passing
* into type-erased formatting functions such as `fmt::vformat`.
*/
template <typename Context>
class dynamic_format_arg_store
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround a GCC template argument substitution bug.
: public basic_format_args<Context>
#endif
{
template <typename Context> class dynamic_format_arg_store {
private:
using char_type = typename Context::char_type;
template <typename T> struct need_copy {
static constexpr detail::type mapped_type =
detail::mapped_type_constant<T, Context>::value;
detail::mapped_type_constant<T, char_type>::value;
enum {
value = !(detail::is_reference_wrapper<T>::value ||
@ -97,7 +90,7 @@ class dynamic_format_arg_store
};
template <typename T>
using stored_type = conditional_t<
using stored_t = conditional_t<
std::is_convertible<T, std::basic_string<char_type>>::value &&
!detail::is_reference_wrapper<T>::value,
std::basic_string<char_type>, T>;
@ -112,41 +105,37 @@ class dynamic_format_arg_store
friend class basic_format_args<Context>;
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));
}
auto data() const -> const basic_format_arg<Context>* {
return named_info_.empty() ? data_.data() : data_.data() + 1;
}
template <typename T> void emplace_arg(const T& arg) {
data_.emplace_back(detail::make_arg<Context>(arg));
data_.emplace_back(arg);
}
template <typename T>
void emplace_arg(const detail::named_arg<char_type, T>& arg) {
if (named_info_.empty()) {
constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
data_.insert(data_.begin(), {zero_ptr, 0});
}
data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
if (named_info_.empty())
data_.insert(data_.begin(), basic_format_arg<Context>(nullptr, 0));
data_.emplace_back(detail::unwrap(arg.value));
auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
data->pop_back();
};
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
guard{&data_, pop_one};
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
data_[0] = {named_info_.data(), named_info_.size()};
guard.release();
}
public:
constexpr dynamic_format_arg_store() = default;
operator basic_format_args<Context>() const {
return basic_format_args<Context>(data(), static_cast<int>(data_.size()),
!named_info_.empty());
}
/**
* Adds an argument into the dynamic store for later passing to a formatting
* function.
@ -164,7 +153,7 @@ class dynamic_format_arg_store
*/
template <typename T> void push_back(const T& arg) {
if (detail::const_check(need_copy<T>::value))
emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
emplace_arg(dynamic_args_.push<stored_t<T>>(arg));
else
emplace_arg(detail::unwrap(arg));
}
@ -200,7 +189,7 @@ class dynamic_format_arg_store
dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
if (detail::const_check(need_copy<T>::value)) {
emplace_arg(
fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
fmt::arg(arg_name, dynamic_args_.push<stored_t<T>>(arg.value)));
} else {
emplace_arg(fmt::arg(arg_name, arg.value));
}
@ -210,17 +199,20 @@ class dynamic_format_arg_store
void clear() {
data_.clear();
named_info_.clear();
dynamic_args_ = detail::dynamic_arg_list();
dynamic_args_ = {};
}
/// Reserves space to store at least `new_cap` arguments including
/// `new_cap_named` named arguments.
void reserve(size_t new_cap, size_t new_cap_named) {
FMT_ASSERT(new_cap >= new_cap_named,
"Set of arguments includes set of named arguments");
"set of arguments includes set of named arguments");
data_.reserve(new_cap);
named_info_.reserve(new_cap_named);
}
/// Returns the number of elements in the store.
size_t size() const noexcept { return data_.size(); }
};
FMT_END_NAMESPACE

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -330,7 +330,7 @@ FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept
namespace detail {
template <typename Char> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
FMT_CONSTEXPR ansi_color_escape(color_type text_color,
const char* esc) noexcept {
// If we have a terminal color, we need to output another escape code
// sequence.
@ -412,13 +412,13 @@ template <typename Char> struct ansi_color_escape {
};
template <typename Char>
FMT_CONSTEXPR auto make_foreground_color(detail::color_type foreground) noexcept
FMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept
-> ansi_color_escape<Char> {
return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
}
template <typename Char>
FMT_CONSTEXPR auto make_background_color(detail::color_type background) noexcept
FMT_CONSTEXPR auto make_background_color(color_type background) noexcept
-> ansi_color_escape<Char> {
return ansi_color_escape<Char>(background, "\x1b[48;2;");
}
@ -434,36 +434,35 @@ template <typename Char> inline void reset_color(buffer<Char>& buffer) {
buffer.append(reset_color.begin(), reset_color.end());
}
template <typename T> struct styled_arg : detail::view {
template <typename T> struct styled_arg : view {
const T& value;
text_style style;
styled_arg(const T& v, text_style s) : value(v), style(s) {}
};
template <typename Char>
void vformat_to(
buffer<Char>& buf, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffered_context<type_identity_t<Char>>> args) {
void vformat_to(buffer<Char>& buf, const text_style& ts,
basic_string_view<Char> fmt,
basic_format_args<buffered_context<Char>> args) {
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
auto emphasis = make_emphasis<Char>(ts.get_emphasis());
buf.append(emphasis.begin(), emphasis.end());
}
if (ts.has_foreground()) {
has_style = true;
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
auto foreground = make_foreground_color<Char>(ts.get_foreground());
buf.append(foreground.begin(), foreground.end());
}
if (ts.has_background()) {
has_style = true;
auto background = detail::make_background_color<Char>(ts.get_background());
auto background = make_background_color<Char>(ts.get_background());
buf.append(background.begin(), background.end());
}
detail::vformat_to(buf, format_str, args, {});
if (has_style) detail::reset_color<Char>(buf);
vformat_to(buf, fmt, args);
if (has_style) reset_color<Char>(buf);
}
} // namespace detail
inline void vprint(FILE* f, const text_style& ts, string_view fmt,
@ -485,7 +484,7 @@ inline void vprint(FILE* f, const text_style& ts, string_view fmt,
template <typename... T>
void print(FILE* f, const text_style& ts, format_string<T...> fmt,
T&&... args) {
vprint(f, ts, fmt, fmt::make_format_args(args...));
vprint(f, ts, fmt.str, vargs<T...>{{args...}});
}
/**
@ -524,7 +523,7 @@ inline auto vformat(const text_style& ts, string_view fmt, format_args args)
template <typename... T>
inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
-> std::string {
return fmt::vformat(ts, fmt, fmt::make_format_args(args...));
return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});
}
/// Formats a string with the given text_style and writes the output to `out`.
@ -551,7 +550,7 @@ template <typename OutputIt, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
inline auto format_to(OutputIt out, const text_style& ts,
format_string<T...> fmt, T&&... args) -> OutputIt {
return vformat_to(out, ts, fmt, fmt::make_format_args(args...));
return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});
}
template <typename T, typename Char>
@ -560,31 +559,30 @@ struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const
-> decltype(ctx.out()) {
const auto& ts = arg.style;
const auto& value = arg.value;
auto out = ctx.out();
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
out = std::copy(emphasis.begin(), emphasis.end(), out);
out = detail::copy<Char>(emphasis.begin(), emphasis.end(), out);
}
if (ts.has_foreground()) {
has_style = true;
auto foreground =
detail::make_foreground_color<Char>(ts.get_foreground());
out = std::copy(foreground.begin(), foreground.end(), out);
out = detail::copy<Char>(foreground.begin(), foreground.end(), out);
}
if (ts.has_background()) {
has_style = true;
auto background =
detail::make_background_color<Char>(ts.get_background());
out = std::copy(background.begin(), background.end(), out);
out = detail::copy<Char>(background.begin(), background.end(), out);
}
out = formatter<T, Char>::format(value, ctx);
out = formatter<T, Char>::format(arg.value, ctx);
if (has_style) {
auto reset_color = string_view("\x1b[0m");
out = std::copy(reset_color.begin(), reset_color.end(), out);
out = detail::copy<Char>(reset_color.begin(), reset_color.end(), out);
}
return out;
}

View File

@ -21,12 +21,6 @@ FMT_EXPORT class compiled_string {};
namespace detail {
template <typename T, typename InputIt>
FMT_CONSTEXPR inline auto copy(InputIt begin, InputIt end, counting_iterator it)
-> counting_iterator {
return it + (end - begin);
}
template <typename S>
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
@ -42,17 +36,16 @@ struct is_compiled_string : std::is_base_of<compiled_string, S> {};
* std::string s = fmt::format(FMT_COMPILE("{}"), 42);
*/
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string, explicit)
# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string)
#else
# define FMT_COMPILE(s) FMT_STRING(s)
#endif
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <typename Char, size_t N,
fmt::detail_exported::fixed_string<Char, N> Str>
template <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>
struct udl_compiled_string : compiled_string {
using char_type = Char;
explicit constexpr operator basic_string_view<char_type>() const {
constexpr explicit operator basic_string_view<char_type>() const {
return {Str.data, N - 1};
}
};
@ -77,6 +70,29 @@ constexpr const auto& get([[maybe_unused]] const T& first,
return detail::get<N - 1>(rest...);
}
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <int N, typename T, typename... Args, typename Char>
constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
if constexpr (is_static_named_arg<T>()) {
if (name == T::name) return N;
}
if constexpr (sizeof...(Args) > 0)
return get_arg_index_by_name<N + 1, Args...>(name);
(void)name; // Workaround an MSVC bug about "unused" parameter.
return -1;
}
# endif
template <typename... Args, typename Char>
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
if constexpr (sizeof...(Args) > 0)
return get_arg_index_by_name<0, Args...>(name);
# endif
(void)name;
return -1;
}
template <typename Char, typename... Args>
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
type_list<Args...>) {
@ -149,8 +165,9 @@ template <typename Char, typename T, int N> struct field {
if constexpr (std::is_convertible<T, basic_string_view<Char>>::value) {
auto s = basic_string_view<Char>(arg);
return copy<Char>(s.begin(), s.end(), out);
} else {
return write<Char>(out, arg);
}
return write<Char>(out, arg);
}
};
@ -275,6 +292,7 @@ constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
}
template <typename Char> struct arg_id_handler {
arg_id_kind kind;
arg_ref<Char> arg_id;
constexpr int on_auto() {
@ -282,25 +300,28 @@ template <typename Char> struct arg_id_handler {
return 0;
}
constexpr int on_index(int id) {
kind = arg_id_kind::index;
arg_id = arg_ref<Char>(id);
return 0;
}
constexpr int on_name(basic_string_view<Char> id) {
kind = arg_id_kind::name;
arg_id = arg_ref<Char>(id);
return 0;
}
};
template <typename Char> struct parse_arg_id_result {
arg_id_kind kind;
arg_ref<Char> arg_id;
const Char* arg_id_end;
};
template <int ID, typename Char>
constexpr auto parse_arg_id(const Char* begin, const Char* end) {
auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
auto handler = arg_id_handler<Char>{arg_id_kind::none, arg_ref<Char>{}};
auto arg_id_end = parse_arg_id(begin, end, handler);
return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
return parse_arg_id_result<Char>{handler.kind, handler.arg_id, arg_id_end};
}
template <typename T, typename Enable = void> struct field_type {
@ -363,18 +384,18 @@ constexpr auto compile_format_string(S fmt) {
constexpr char_type c =
arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
static_assert(c == '}' || c == ':', "missing '}' in format string");
if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) {
if constexpr (arg_id_result.kind == arg_id_kind::index) {
static_assert(
ID == manual_indexing_id || ID == 0,
"cannot switch from automatic to manual argument indexing");
constexpr auto arg_index = arg_id_result.arg_id.val.index;
constexpr auto arg_index = arg_id_result.arg_id.index;
return parse_replacement_field_then_tail<get_type<arg_index, Args>,
Args, arg_id_end_pos,
arg_index, manual_indexing_id>(
fmt);
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
} else if constexpr (arg_id_result.kind == arg_id_kind::name) {
constexpr auto arg_index =
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
get_arg_index_by_name(arg_id_result.arg_id.name, Args{});
if constexpr (arg_index >= 0) {
constexpr auto next_id =
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
@ -383,8 +404,7 @@ constexpr auto compile_format_string(S fmt) {
arg_index, next_id>(fmt);
} else if constexpr (c == '}') {
return parse_tail<Args, arg_id_end_pos + 1, ID>(
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
fmt);
runtime_named_field<char_type>{arg_id_result.arg_id.name}, fmt);
} else if constexpr (c == ':') {
return unknown_format(); // no type info for specs parsing
}
@ -496,15 +516,17 @@ template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
-> size_t {
return fmt::format_to(detail::counting_iterator(), fmt, args...).count();
auto buf = detail::counting_buffer<>();
fmt::format_to(appender(buf), fmt, args...);
return buf.count();
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
void print(std::FILE* f, const S& fmt, const Args&... args) {
memory_buffer buffer;
fmt::format_to(std::back_inserter(buffer), fmt, args...);
detail::print(f, {buffer.data(), buffer.size()});
auto buf = memory_buffer();
fmt::format_to(appender(buf), fmt, args...);
detail::print(f, {buf.data(), buf.size()});
}
template <typename S, typename... Args,
@ -515,7 +537,7 @@ void print(const S& fmt, const Args&... args) {
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
inline namespace literals {
template <detail_exported::fixed_string Str> constexpr auto operator""_cf() {
template <detail::fixed_string Str> constexpr auto operator""_cf() {
using char_t = remove_cvref_t<decltype(Str.data[0])>;
return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
Str>();

View File

@ -14,10 +14,6 @@
# include <climits>
# include <cmath>
# include <exception>
# if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
# include <locale>
# endif
#endif
#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)
@ -26,16 +22,22 @@
#include "format.h"
#if FMT_USE_LOCALE
# include <locale>
#endif
#ifndef FMT_FUNC
# define FMT_FUNC
#endif
FMT_BEGIN_NAMESPACE
namespace detail {
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
// Use unchecked std::fprintf to avoid triggering another assertion when
// writing to stderr fails
std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
// Chosen instead of std::abort to satisfy Clang in CUDA mode during device
// code pass.
std::terminate();
// writing to stderr fails.
fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
abort();
}
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
@ -61,86 +63,95 @@ FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
FMT_ASSERT(out.size() <= inline_buffer_size, "");
}
FMT_FUNC void report_error(format_func func, int error_code,
const char* message) noexcept {
FMT_FUNC void do_report_error(format_func func, int error_code,
const char* message) noexcept {
memory_buffer full_message;
func(full_message, error_code, message);
// Don't use fwrite_fully because the latter may throw.
// Don't use fwrite_all because the latter may throw.
if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0)
std::fputc('\n', stderr);
}
// A wrapper around fwrite that throws on error.
inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) {
inline void fwrite_all(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")));
}
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
#if FMT_USE_LOCALE
using std::locale;
using std::numpunct;
using std::use_facet;
template <typename Locale>
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
static_assert(std::is_same<Locale, std::locale>::value, "");
static_assert(std::is_same<Locale, locale>::value, "");
}
#else
struct locale {};
template <typename Char> struct numpunct {
auto grouping() const -> std::string { return "\03"; }
auto thousands_sep() const -> Char { return ','; }
auto decimal_point() const -> Char { return '.'; }
};
template <typename Facet> Facet use_facet(locale) { return {}; }
#endif // FMT_USE_LOCALE
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();
static_assert(std::is_same<Locale, locale>::value, "");
#if FMT_USE_LOCALE
if (locale_) return *static_cast<const locale*>(locale_);
#endif
return locale();
}
template <typename Char>
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>());
auto&& facet = use_facet<numpunct<Char>>(loc.get<locale>());
auto grouping = facet.grouping();
auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();
return {std::move(grouping), thousands_sep};
}
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();
return use_facet<numpunct<Char>>(loc.get<locale>()).decimal_point();
}
#else
template <typename Char>
FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result<Char> {
return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR};
}
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
return '.';
}
#endif
#if FMT_USE_LOCALE
FMT_FUNC auto write_loc(appender out, loc_value value,
const format_specs& specs, locale_ref loc) -> bool {
#ifdef FMT_STATIC_THOUSANDS_SEPARATOR
value.visit(loc_writer<>{
out, specs, std::string(1, FMT_STATIC_THOUSANDS_SEPARATOR), "\3", "."});
return true;
#else
auto locale = loc.get<std::locale>();
// We cannot use the num_put<char> facet because it may produce output in
// a wrong encoding.
using facet = format_facet<std::locale>;
if (std::has_facet<facet>(locale))
return std::use_facet<facet>(locale).put(out, value, specs);
return use_facet<facet>(locale).put(out, value, specs);
return facet(locale).put(out, value, specs);
#endif
}
#endif
} // namespace detail
FMT_FUNC void report_error(const char* message) {
#if FMT_USE_EXCEPTIONS
// Use FMT_THROW instead of throw to avoid bogus unreachable code warnings
// from MSVC.
FMT_THROW(format_error(message));
#else
fputs(message, stderr);
abort();
#endif
}
template <typename Locale> typename Locale::id format_facet<Locale>::id;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
auto& numpunct = std::use_facet<std::numpunct<char>>(loc);
grouping_ = numpunct.grouping();
if (!grouping_.empty()) separator_ = std::string(1, numpunct.thousands_sep());
auto& np = detail::use_facet<detail::numpunct<char>>(loc);
grouping_ = np.grouping();
if (!grouping_.empty()) separator_ = std::string(1, np.thousands_sep());
}
#if FMT_USE_LOCALE
template <>
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
appender out, loc_value val, const format_specs& specs) const -> bool {
@ -1425,7 +1436,7 @@ FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
FMT_FUNC void report_system_error(int error_code,
const char* message) noexcept {
report_error(format_system_error, error_code, message);
do_report_error(format_system_error, error_code, message);
}
FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
@ -1438,6 +1449,15 @@ FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
namespace detail {
FMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
locale_ref loc) {
auto out = appender(buf);
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
return args.get(0).visit(default_arg_formatter<char>{out});
parse_format_string(
fmt, format_handler<char>{parse_context<char>(fmt), {out, args, loc}});
}
template <typename T> struct span {
T* data;
size_t size;
@ -1508,6 +1528,7 @@ template <typename F> class glibc_file : public file_base<F> {
void init_buffer() {
if (this->file_->_IO_write_ptr) return;
// Force buffer initialization by placing and removing a char in a buffer.
assume(this->file_->_IO_write_ptr >= this->file_->_IO_write_end);
putc_unlocked(0, this->file_);
--this->file_->_IO_write_ptr;
}
@ -1615,7 +1636,7 @@ template <typename F> class fallback_file : public file_base<F> {
};
#ifndef FMT_USE_FALLBACK_FILE
# define FMT_USE_FALLBACK_FILE 1
# define FMT_USE_FALLBACK_FILE 0
#endif
template <typename F,
@ -1692,7 +1713,7 @@ FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args,
auto buffer = memory_buffer();
detail::vformat_to(buffer, fmt, args);
if (newline) buffer.push_back('\n');
fwrite_fully(buffer.data(), buffer.size(), f);
fwrite_all(buffer.data(), buffer.size(), f);
}
#endif
@ -1704,7 +1725,7 @@ FMT_FUNC void print(std::FILE* f, string_view text) {
if (write_console(fd, text)) return;
}
#endif
fwrite_fully(text.data(), text.size(), f);
fwrite_all(text.data(), text.size(), f);
}
} // namespace detail

File diff suppressed because it is too large Load Diff

View File

@ -118,7 +118,7 @@ FMT_API void format_windows_error(buffer<char>& out, int error_code,
const char* message) noexcept;
}
FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
FMT_API std::system_error vwindows_error(int error_code, string_view fmt,
format_args args);
/**
@ -146,10 +146,10 @@ FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
* "cannot open file '{}'", filename);
* }
*/
template <typename... Args>
std::system_error windows_error(int error_code, string_view message,
const Args&... args) {
return vwindows_error(error_code, message, fmt::make_format_args(args...));
template <typename... T>
auto windows_error(int error_code, string_view message, const T&... args)
-> std::system_error {
return vwindows_error(error_code, message, vargs<T...>{{args...}});
}
// Reports a Windows error without throwing an exception.
@ -164,8 +164,8 @@ inline auto system_category() noexcept -> const std::error_category& {
// std::system is not available on some platforms such as iOS (#2248).
#ifdef __OSX__
template <typename S, typename... Args, typename Char = char_t<S>>
void say(const S& format_str, Args&&... args) {
std::system(format("say \"{}\"", format(format_str, args...)).c_str());
void say(const S& fmt, Args&&... args) {
std::system(format("say \"{}\"", format(fmt, args...)).c_str());
}
#endif
@ -176,24 +176,24 @@ class buffered_file {
friend class file;
explicit buffered_file(FILE* f) : file_(f) {}
inline explicit buffered_file(FILE* f) : file_(f) {}
public:
buffered_file(const buffered_file&) = delete;
void operator=(const buffered_file&) = delete;
// Constructs a buffered_file object which doesn't represent any file.
buffered_file() noexcept : file_(nullptr) {}
inline buffered_file() noexcept : file_(nullptr) {}
// Destroys the object closing the file it represents if any.
FMT_API ~buffered_file() noexcept;
public:
buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
other.file_ = nullptr;
}
auto operator=(buffered_file&& other) -> buffered_file& {
inline auto operator=(buffered_file&& other) -> buffered_file& {
close();
file_ = other.file_;
other.file_ = nullptr;
@ -207,13 +207,13 @@ class buffered_file {
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
auto get() const noexcept -> FILE* { return file_; }
inline auto get() const noexcept -> FILE* { return file_; }
FMT_API auto descriptor() const -> int;
template <typename... T>
inline void print(string_view fmt, const T&... args) {
const auto& vargs = fmt::make_format_args(args...);
fmt::vargs<T...> vargs = {{args...}};
detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)
: fmt::vprint(file_, fmt, vargs);
}
@ -248,7 +248,7 @@ class FMT_API file {
};
// Constructs a file object which doesn't represent any file.
file() noexcept : fd_(-1) {}
inline file() noexcept : fd_(-1) {}
// Opens a file and constructs a file object representing this file.
file(cstring_view path, int oflag);
@ -257,10 +257,10 @@ class FMT_API file {
file(const file&) = delete;
void operator=(const file&) = delete;
file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
// Move assignment is not noexcept because close may throw.
auto operator=(file&& other) -> file& {
inline auto operator=(file&& other) -> file& {
close();
fd_ = other.fd_;
other.fd_ = -1;
@ -271,7 +271,7 @@ class FMT_API file {
~file() noexcept;
// Returns the file descriptor.
auto descriptor() const noexcept -> int { return fd_; }
inline auto descriptor() const noexcept -> int { return fd_; }
// Closes the file.
void close();
@ -324,9 +324,9 @@ auto getpagesize() -> long;
namespace detail {
struct buffer_size {
buffer_size() = default;
constexpr buffer_size() = default;
size_t value = 0;
auto operator=(size_t val) const -> buffer_size {
FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {
auto bs = buffer_size();
bs.value = val;
return bs;
@ -337,7 +337,7 @@ struct ostream_params {
int oflag = file::WRONLY | file::CREATE | file::TRUNC;
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
ostream_params() {}
constexpr ostream_params() {}
template <typename... T>
ostream_params(T... params, int new_oflag) : ostream_params(params...) {
@ -358,59 +358,47 @@ struct ostream_params {
# endif
};
class file_buffer final : public buffer<char> {
} // namespace detail
FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size();
/// A fast buffered output stream for writing from a single thread. Writing from
/// multiple threads without external synchronization may result in a data race.
class FMT_API ostream : private detail::buffer<char> {
private:
file file_;
FMT_API static void grow(buffer<char>& buf, size_t);
ostream(cstring_view path, const detail::ostream_params& params);
static void grow(buffer<char>& buf, size_t);
public:
FMT_API file_buffer(cstring_view path, const ostream_params& params);
FMT_API file_buffer(file_buffer&& other) noexcept;
FMT_API ~file_buffer();
ostream(ostream&& other) noexcept;
~ostream();
void flush() {
operator writer() {
detail::buffer<char>& buf = *this;
return buf;
}
inline void flush() {
if (size() == 0) return;
file_.write(data(), size() * sizeof(data()[0]));
clear();
}
void close() {
flush();
file_.close();
}
};
} // namespace detail
constexpr auto buffer_size = detail::buffer_size();
/// A fast output stream for writing from a single thread. Writing from
/// multiple threads without external synchronization may result in a data race.
class FMT_API ostream {
private:
FMT_MSC_WARNING(suppress : 4251)
detail::file_buffer buffer_;
ostream(cstring_view path, const detail::ostream_params& params)
: buffer_(path, params) {}
public:
ostream(ostream&& other) : buffer_(std::move(other.buffer_)) {}
~ostream();
void flush() { buffer_.flush(); }
template <typename... T>
friend auto output_file(cstring_view path, T... params) -> ostream;
void close() { buffer_.close(); }
inline void close() {
flush();
file_.close();
}
/// Formats `args` according to specifications in `fmt` and writes the
/// output to the file.
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
vformat_to(appender(buffer_), fmt, fmt::make_format_args(args...));
vformat_to(appender(*this), fmt.str, vargs<T...>{{args...}});
}
};

View File

@ -22,6 +22,14 @@
#include "chrono.h" // formatbuf
#ifdef _MSVC_STL_UPDATE
# define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE
#elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5
# define FMT_MSVC_STL_UPDATE _MSVC_LANG
#else
# define FMT_MSVC_STL_UPDATE 0
#endif
FMT_BEGIN_NAMESPACE
namespace detail {
@ -35,53 +43,18 @@ class file_access {
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
};
#if FMT_MSC_VERSION
#if FMT_MSVC_STL_UPDATE
template class file_access<file_access_tag, std::filebuf,
&std::filebuf::_Myfile>;
auto get_file(std::filebuf&) -> FILE*;
#endif
inline auto write_ostream_unicode(std::ostream& os, fmt::string_view data)
-> bool {
FILE* f = nullptr;
#if FMT_MSC_VERSION && FMT_USE_RTTI
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
f = get_file(*buf);
else
return false;
#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
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;
#else
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 auto write_ostream_unicode(std::wostream&,
fmt::basic_string_view<wchar_t>) -> bool {
return false;
}
// Write the content of buf to os.
// It is a separate function rather than a part of vprint to simplify testing.
template <typename Char>
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
const Char* buf_data = buf.data();
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
using unsigned_streamsize = make_unsigned_t<std::streamsize>;
unsigned_streamsize size = buf.size();
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
do {
@ -92,21 +65,9 @@ void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
} while (size != 0);
}
template <typename Char, typename T>
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)
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;
};
} // namespace detail
// Formats an object of type T that has an overloaded ostream operator<<.
@ -117,7 +78,11 @@ struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
template <typename T, typename Context>
auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) {
auto buffer = basic_memory_buffer<Char>();
detail::format_value(buffer, value);
auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);
auto&& output = std::basic_ostream<Char>(&formatbuf);
output.imbue(std::locale::classic()); // The default is always unlocalized.
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
return formatter<basic_string_view<Char>, Char>::format(
{buffer.data(), buffer.size()}, ctx);
}
@ -148,24 +113,30 @@ constexpr auto streamed(const T& value) -> detail::streamed_view<T> {
return {value};
}
namespace detail {
inline void vprint_directly(std::ostream& os, string_view format_str,
format_args args) {
inline void vprint(std::ostream& os, string_view fmt, format_args args) {
auto buffer = memory_buffer();
detail::vformat_to(buffer, format_str, args);
detail::write_buffer(os, buffer);
}
} // namespace detail
FMT_EXPORT template <typename Char>
void vprint(std::basic_ostream<Char>& os,
basic_string_view<type_identity_t<Char>> format_str,
typename detail::vformat_args<Char>::type args) {
auto buffer = basic_memory_buffer<Char>();
detail::vformat_to(buffer, format_str, args);
if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return;
detail::vformat_to(buffer, fmt, args);
FILE* f = nullptr;
#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
f = detail::get_file(*buf);
#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
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();
#endif
#ifdef _WIN32
if (f) {
int fd = _fileno(f);
if (_isatty(fd)) {
os.flush();
if (detail::write_console(fd, {buffer.data(), buffer.size()})) return;
}
}
#endif
detail::ignore_unused(f);
detail::write_buffer(os, buffer);
}
@ -178,19 +149,11 @@ void vprint(std::basic_ostream<Char>& os,
*/
FMT_EXPORT template <typename... T>
void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
const auto& vargs = fmt::make_format_args(args...);
if (detail::use_utf8())
vprint(os, fmt, vargs);
else
detail::vprint_directly(os, fmt, vargs);
}
FMT_EXPORT
template <typename... Args>
void print(std::wostream& os,
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
Args&&... args) {
vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
fmt::vargs<T...> vargs = {{args...}};
if (detail::use_utf8) return vprint(os, fmt.str, vargs);
auto buffer = memory_buffer();
detail::vformat_to(buffer, fmt.str, vargs);
detail::write_buffer(os, buffer);
}
FMT_EXPORT template <typename... T>
@ -198,14 +161,6 @@ void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
fmt::print(os, "{}\n", fmt::format(fmt, std::forward<T>(args)...));
}
FMT_EXPORT
template <typename... Args>
void println(std::wostream& os,
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
Args&&... args) {
print(os, L"{}\n", fmt::format(fmt, std::forward<Args>(args)...));
}
FMT_END_NAMESPACE
#endif // FMT_OSTREAM_H_

View File

@ -33,8 +33,9 @@ template <typename Char> class basic_printf_context {
public:
using char_type = Char;
using parse_context_type = basic_format_parse_context<Char>;
using parse_context_type = parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>;
enum { builtin_types = 1 };
/// Constructs a `printf_context` object. References to the arguments are
/// stored in the context object so make sure they have appropriate lifetimes.
@ -54,6 +55,23 @@ template <typename Char> class basic_printf_context {
namespace detail {
// Return the result via the out param to workaround gcc bug 77539.
template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
for (out = first; out != last; ++out) {
if (*out == value) return true;
}
return false;
}
template <>
inline auto find<false, char>(const char* first, const char* last, char value,
const char*& out) -> bool {
out =
static_cast<const char*>(memchr(first, value, to_unsigned(last - first)));
return out != nullptr;
}
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned> struct int_checker {
@ -61,7 +79,7 @@ template <bool IsSigned> struct int_checker {
unsigned max = to_unsigned(max_value<int>());
return value <= max;
}
static auto fits_in_int(bool) -> bool { return true; }
inline static auto fits_in_int(bool) -> bool { return true; }
};
template <> struct int_checker<true> {
@ -69,7 +87,7 @@ template <> struct int_checker<true> {
return value >= (std::numeric_limits<int>::min)() &&
value <= max_value<int>();
}
static auto fits_in_int(int) -> bool { return true; }
inline static auto fits_in_int(int) -> bool { return true; }
};
struct printf_precision_handler {
@ -127,25 +145,19 @@ template <typename T, typename Context> class arg_converter {
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
if (const_check(sizeof(target_type) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
auto n = static_cast<int>(static_cast<target_type>(value));
arg_ = detail::make_arg<Context>(n);
} else {
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
auto n = static_cast<unsigned>(static_cast<unsigned_type>(value));
arg_ = detail::make_arg<Context>(n);
}
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
if (is_signed)
arg_ = static_cast<int>(static_cast<target_type>(value));
else
arg_ = static_cast<unsigned>(static_cast<unsigned_type>(value));
} else {
if (is_signed) {
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
auto n = static_cast<long long>(value);
arg_ = detail::make_arg<Context>(n);
} else {
auto n = static_cast<typename make_unsigned_or_bool<U>::type>(value);
arg_ = detail::make_arg<Context>(n);
}
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
if (is_signed)
arg_ = static_cast<long long>(value);
else
arg_ = static_cast<typename make_unsigned_or_bool<U>::type>(value);
}
}
@ -172,8 +184,7 @@ template <typename Context> class char_converter {
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
void operator()(T value) {
auto c = static_cast<typename Context::char_type>(value);
arg_ = detail::make_arg<Context>(c);
arg_ = static_cast<typename Context::char_type>(value);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
@ -194,13 +205,13 @@ class printf_width_handler {
format_specs& specs_;
public:
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
auto operator()(T value) -> unsigned {
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
if (detail::is_negative(value)) {
specs_.align = align::left;
specs_.set_align(align::left);
width = 0 - width;
}
unsigned int_max = to_unsigned(max_value<int>());
@ -234,69 +245,74 @@ class printf_arg_formatter : public arg_formatter<Char> {
void write_null_pointer(bool is_string = false) {
auto s = this->specs;
s.type = presentation_type::none;
s.set_type(presentation_type::none);
write_bytes<Char>(this->out, is_string ? "(null)" : "(nil)", s);
}
template <typename T> void write(T value) {
detail::write<Char>(this->out, value, this->specs, this->locale);
}
public:
printf_arg_formatter(basic_appender<Char> iter, format_specs& s,
context_type& ctx)
: base(make_arg_formatter(iter, s)), context_(ctx) {}
void operator()(monostate value) { base::operator()(value); }
void operator()(monostate value) { write(value); }
template <typename T, FMT_ENABLE_IF(detail::is_integral<T>::value)>
void operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and Char so use
// std::is_same instead.
if (!std::is_same<T, Char>::value) {
base::operator()(value);
write(value);
return;
}
format_specs s = this->specs;
if (s.type != presentation_type::none && s.type != presentation_type::chr) {
if (s.type() != presentation_type::none &&
s.type() != presentation_type::chr) {
return (*this)(static_cast<int>(value));
}
s.sign = sign::none;
s.alt = false;
s.fill = ' '; // Ignore '0' flag for char types.
s.set_sign(sign::none);
s.clear_alt();
s.set_fill(' '); // Ignore '0' flag for char types.
// align::numeric needs to be overwritten here since the '0' flag is
// ignored for non-numeric types
if (s.align == align::none || s.align == align::numeric)
s.align = align::right;
write<Char>(this->out, static_cast<Char>(value), s);
if (s.align() == align::none || s.align() == align::numeric)
s.set_align(align::right);
detail::write<Char>(this->out, static_cast<Char>(value), s);
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
void operator()(T value) {
base::operator()(value);
write(value);
}
void operator()(const char* value) {
if (value)
base::operator()(value);
write(value);
else
write_null_pointer(this->specs.type != presentation_type::pointer);
write_null_pointer(this->specs.type() != presentation_type::pointer);
}
void operator()(const wchar_t* value) {
if (value)
base::operator()(value);
write(value);
else
write_null_pointer(this->specs.type != presentation_type::pointer);
write_null_pointer(this->specs.type() != presentation_type::pointer);
}
void operator()(basic_string_view<Char> value) { base::operator()(value); }
void operator()(basic_string_view<Char> value) { write(value); }
void operator()(const void* value) {
if (value)
base::operator()(value);
write(value);
else
write_null_pointer();
}
void operator()(typename basic_format_arg<context_type>::handle handle) {
auto parse_ctx = basic_format_parse_context<Char>({});
auto parse_ctx = parse_context<Char>({});
handle.format(parse_ctx, context_);
}
};
@ -305,23 +321,14 @@ template <typename Char>
void parse_flags(format_specs& specs, const Char*& it, const Char* end) {
for (; it != end; ++it) {
switch (*it) {
case '-':
specs.align = align::left;
break;
case '+':
specs.sign = sign::plus;
break;
case '0':
specs.fill = '0';
break;
case '-': specs.set_align(align::left); break;
case '+': specs.set_sign(sign::plus); break;
case '0': specs.set_fill('0'); break;
case ' ':
if (specs.sign != sign::plus) specs.sign = sign::space;
if (specs.sign() != sign::plus) specs.set_sign(sign::space);
break;
case '#':
specs.alt = true;
break;
default:
return;
case '#': specs.set_alt(); break;
default: return;
}
}
}
@ -339,7 +346,7 @@ auto parse_header(const Char*& it, const Char* end, format_specs& specs,
++it;
arg_index = value != -1 ? value : max_value<int>();
} else {
if (c == '0') specs.fill = '0';
if (c == '0') specs.set_fill('0');
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
@ -369,43 +376,22 @@ inline auto parse_printf_presentation_type(char c, type t, bool& upper)
using pt = presentation_type;
constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
switch (c) {
case 'd':
return in(t, integral_set) ? pt::dec : pt::none;
case 'o':
return in(t, integral_set) ? pt::oct : pt::none;
case 'X':
upper = true;
FMT_FALLTHROUGH;
case 'x':
return in(t, integral_set) ? pt::hex : pt::none;
case 'E':
upper = true;
FMT_FALLTHROUGH;
case 'e':
return in(t, float_set) ? pt::exp : pt::none;
case 'F':
upper = true;
FMT_FALLTHROUGH;
case 'f':
return in(t, float_set) ? pt::fixed : pt::none;
case 'G':
upper = true;
FMT_FALLTHROUGH;
case 'g':
return in(t, float_set) ? pt::general : pt::none;
case 'A':
upper = true;
FMT_FALLTHROUGH;
case 'a':
return in(t, float_set) ? pt::hexfloat : pt::none;
case 'c':
return in(t, integral_set) ? pt::chr : pt::none;
case 's':
return in(t, string_set | cstring_set) ? pt::string : pt::none;
case 'p':
return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;
default:
return pt::none;
case 'd': return in(t, integral_set) ? pt::dec : pt::none;
case 'o': return in(t, integral_set) ? pt::oct : pt::none;
case 'X': upper = true; FMT_FALLTHROUGH;
case 'x': return in(t, integral_set) ? pt::hex : pt::none;
case 'E': upper = true; FMT_FALLTHROUGH;
case 'e': return in(t, float_set) ? pt::exp : pt::none;
case 'F': upper = true; FMT_FALLTHROUGH;
case 'f': return in(t, float_set) ? pt::fixed : pt::none;
case 'G': upper = true; FMT_FALLTHROUGH;
case 'g': return in(t, float_set) ? pt::general : pt::none;
case 'A': upper = true; FMT_FALLTHROUGH;
case 'a': return in(t, float_set) ? pt::hexfloat : pt::none;
case 'c': return in(t, integral_set) ? pt::chr : pt::none;
case 's': return in(t, string_set | cstring_set) ? pt::string : pt::none;
case 'p': return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;
default: return pt::none;
}
}
@ -415,7 +401,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
using iterator = basic_appender<Char>;
auto out = iterator(buf);
auto context = basic_printf_context<Char>(out, args);
auto parse_ctx = basic_format_parse_context<Char>(format);
auto parse_ctx = parse_context<Char>(format);
// Returns the argument with specified index or, if arg_index is -1, the next
// argument.
@ -444,7 +430,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
write(out, basic_string_view<Char>(start, to_unsigned(it - 1 - start)));
auto specs = format_specs();
specs.align = align::right;
specs.set_align(align::right);
// Parse argument index, flags and width.
int arg_index = parse_header(it, end, specs, get_arg);
@ -468,9 +454,9 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
auto arg = get_arg(arg_index);
// For d, i, o, u, x, and X conversion specifiers, if a precision is
// specified, the '0' flag is ignored
if (specs.precision >= 0 && arg.is_integral()) {
if (specs.precision >= 0 && is_integral_type(arg.type())) {
// Ignore '0' for non-numeric types or if '-' present.
specs.fill = ' ';
specs.set_fill(' ');
}
if (specs.precision >= 0 && arg.type() == type::cstring_type) {
auto str = arg.visit(get_cstring<Char>());
@ -478,15 +464,16 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
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);
arg = sv;
}
if (specs.alt && arg.visit(is_zero_int())) specs.alt = false;
if (specs.fill.template get<Char>() == '0') {
if (arg.is_arithmetic() && specs.align != align::left)
specs.align = align::numeric;
else
specs.fill = ' '; // Ignore '0' flag for non-numeric types or if '-'
// flag is also present.
if (specs.alt() && arg.visit(is_zero_int())) specs.clear_alt();
if (specs.fill_unit<Char>() == '0') {
if (is_arithmetic_type(arg.type()) && specs.align() != align::left) {
specs.set_align(align::numeric);
} else {
// Ignore '0' flag for non-numeric types or if '-' flag is also present.
specs.set_fill(' ');
}
}
// Parse length and convert the argument to the required type.
@ -511,44 +498,34 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
convert_arg<long>(arg, t);
}
break;
case 'j':
convert_arg<intmax_t>(arg, t);
break;
case 'z':
convert_arg<size_t>(arg, t);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, t);
break;
case 'j': convert_arg<intmax_t>(arg, t); break;
case 'z': convert_arg<size_t>(arg, t); break;
case 't': convert_arg<std::ptrdiff_t>(arg, t); break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, c);
default: --it; convert_arg<void>(arg, c);
}
// Parse type.
if (it == end) report_error("invalid format string");
char type = static_cast<char>(*it++);
if (arg.is_integral()) {
if (is_integral_type(arg.type())) {
// Normalize type.
switch (type) {
case 'i':
case 'u':
type = 'd';
break;
case 'u': type = 'd'; break;
case 'c':
arg.visit(char_converter<basic_printf_context<Char>>(arg));
break;
}
}
bool upper = false;
specs.type = parse_printf_presentation_type(type, arg.type(), upper);
if (specs.type == presentation_type::none)
specs.set_type(parse_printf_presentation_type(type, arg.type(), upper));
if (specs.type() == presentation_type::none)
report_error("invalid format specifier");
specs.upper = upper;
if (upper) specs.set_upper();
start = it;
@ -583,7 +560,7 @@ inline auto vsprintf(basic_string_view<Char> fmt,
-> std::basic_string<Char> {
auto buf = basic_memory_buffer<Char>();
detail::vprintf(buf, fmt, args);
return to_string(buf);
return {buf.data(), buf.size()};
}
/**
@ -594,7 +571,7 @@ inline auto vsprintf(basic_string_view<Char> fmt,
*
* std::string message = fmt::sprintf("The answer is %d", 42);
*/
template <typename S, typename... T, typename Char = char_t<S>>
template <typename S, typename... T, typename Char = detail::char_t<S>>
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
return vsprintf(detail::to_string_view(fmt),
fmt::make_format_args<basic_printf_context<Char>>(args...));
@ -619,7 +596,7 @@ inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
*
* fmt::fprintf(stderr, "Don't %s!", "panic");
*/
template <typename S, typename... T, typename Char = char_t<S>>
template <typename S, typename... T, typename Char = detail::char_t<S>>
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
return vfprintf(f, detail::to_string_view(fmt),
make_printf_args<Char>(args...));

View File

@ -44,18 +44,6 @@ template <typename T> class is_set {
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
};
template <typename... Ts> struct conditional_helper {};
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
# define FMT_DECLTYPE_RETURN(val) \
->decltype(val) { return val; } \
static_assert( \
true, "") // This makes it so that a semicolon is required after the
// macro, which helps clang-format handle the formatting.
// C array overload
template <typename T, std::size_t N>
auto range_begin(const T (&arr)[N]) -> const T* {
@ -76,9 +64,13 @@ struct has_member_fn_begin_end_t<T, void_t<decltype(*std::declval<T>().begin()),
// Member function overloads.
template <typename T>
auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin());
auto range_begin(T&& rng) -> decltype(static_cast<T&&>(rng).begin()) {
return static_cast<T&&>(rng).begin();
}
template <typename T>
auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end());
auto range_end(T&& rng) -> decltype(static_cast<T&&>(rng).end()) {
return static_cast<T&&>(rng).end();
}
// ADL overloads. Only participate in overload resolution if member functions
// are not found.
@ -115,17 +107,16 @@ struct has_mutable_begin_end<
// SFINAE properly unless there are distinct types
int>> : std::true_type {};
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
template <typename T>
struct is_range_<T, void>
: std::integral_constant<bool, (has_const_begin_end<T>::value ||
has_mutable_begin_end<T>::value)> {};
# undef FMT_DECLTYPE_RETURN
#endif
// tuple_size and tuple_element check.
template <typename T> class is_tuple_like_ {
template <typename U>
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
template <typename U, typename V = typename std::remove_cv<U>::type>
static auto check(U* p) -> decltype(std::tuple_size<V>::value, 0);
template <typename> static void check(...);
public:
@ -266,12 +257,12 @@ template <range_format K>
using range_format_constant = std::integral_constant<range_format, K>;
// These are not generic lambdas for compatibility with C++11.
template <typename ParseContext> struct parse_empty_specs {
template <typename Char> struct parse_empty_specs {
template <typename Formatter> FMT_CONSTEXPR void operator()(Formatter& f) {
f.parse(ctx);
detail::maybe_set_debug_format(f, true);
}
ParseContext& ctx;
parse_context<Char>& ctx;
};
template <typename FormatContext> struct format_tuple_element {
using char_type = typename FormatContext::char_type;
@ -327,11 +318,17 @@ struct formatter<Tuple, Char,
closing_bracket_ = close;
}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
auto it = ctx.begin();
if (it != ctx.end() && *it != '}') report_error("invalid format specifier");
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
auto end = ctx.end();
if (it != end && detail::to_ascii(*it) == 'n') {
++it;
set_brackets({}, {});
set_separator({});
}
if (it != end && *it != '}') report_error("invalid format specifier");
ctx.advance_to(it);
detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});
return it;
}
@ -352,38 +349,17 @@ template <typename T, typename Char> struct is_range {
};
namespace detail {
template <typename Context> struct range_mapper {
using mapper = arg_mapper<Context>;
template <typename T,
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, Context>::value)>
static auto map(T&& value) -> T&& {
return static_cast<T&&>(value);
}
template <typename T,
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, Context>::value)>
static auto map(T&& value)
-> decltype(mapper().map(static_cast<T&&>(value))) {
return mapper().map(static_cast<T&&>(value));
}
};
template <typename Char, typename Element>
using range_formatter_type =
formatter<remove_cvref_t<decltype(range_mapper<buffered_context<Char>>{}
.map(std::declval<Element>()))>,
Char>;
using range_formatter_type = formatter<remove_cvref_t<Element>, Char>;
template <typename R>
using maybe_const_range =
conditional_t<has_const_begin_end<R>::value, const R, R>;
// Workaround a bug in MSVC 2015 and earlier.
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
template <typename R, typename Char>
struct is_formattable_delayed
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
#endif
} // namespace detail
template <typename...> struct conjunction : std::true_type {};
@ -415,7 +391,7 @@ struct range_formatter<
auto buf = basic_memory_buffer<Char>();
for (; it != end; ++it) buf.push_back(*it);
auto specs = format_specs();
specs.type = presentation_type::debug;
specs.set_type(presentation_type::debug);
return detail::write<Char>(
out, basic_string_view<Char>(buf.data(), buf.size()), specs);
}
@ -443,8 +419,7 @@ struct range_formatter<
closing_bracket_ = close;
}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
auto it = ctx.begin();
auto end = ctx.end();
detail::maybe_set_debug_format(underlying_, true);
@ -486,7 +461,6 @@ struct range_formatter<
template <typename R, typename FormatContext>
auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {
auto mapper = detail::range_mapper<buffered_context<Char>>();
auto out = ctx.out();
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
@ -498,7 +472,7 @@ struct range_formatter<
if (i > 0) out = detail::copy<Char>(separator_, out);
ctx.advance_to(out);
auto&& item = *it; // Need an lvalue
out = underlying_.format(mapper.map(item), ctx);
out = underlying_.format(item, ctx);
++i;
}
out = detail::copy<Char>(closing_bracket_, out);
@ -521,13 +495,8 @@ struct formatter<
range_format_kind<R, Char>::value != range_format::disabled &&
range_format_kind<R, Char>::value != range_format::map &&
range_format_kind<R, Char>::value != range_format::string &&
range_format_kind<R, Char>::value != range_format::debug_string>
// Workaround a bug in MSVC 2015 and earlier.
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
,
detail::is_formattable_delayed<R, Char>
#endif
>::value>> {
range_format_kind<R, Char>::value != range_format::debug_string>,
detail::is_formattable_delayed<R, Char>>::value>> {
private:
using range_type = detail::maybe_const_range<R>;
range_formatter<detail::uncvref_type<range_type>, Char> range_formatter_;
@ -543,8 +512,7 @@ struct formatter<
detail::string_literal<Char, '}'>{});
}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return range_formatter_.parse(ctx);
}
@ -571,8 +539,7 @@ struct formatter<
public:
FMT_CONSTEXPR formatter() {}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
auto it = ctx.begin();
auto end = ctx.end();
if (it != end) {
@ -586,7 +553,7 @@ struct formatter<
}
ctx.advance_to(it);
}
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});
return it;
}
@ -596,12 +563,11 @@ struct formatter<
basic_string_view<Char> open = detail::string_literal<Char, '{'>{};
if (!no_delimiters_) out = detail::copy<Char>(open, out);
int i = 0;
auto mapper = detail::range_mapper<buffered_context<Char>>();
basic_string_view<Char> sep = detail::string_literal<Char, ',', ' '>{};
for (auto&& value : map) {
if (i > 0) out = detail::copy<Char>(sep, out);
ctx.advance_to(out);
detail::for_each2(formatters_, mapper.map(value),
detail::for_each2(formatters_, value,
detail::format_tuple_element<FormatContext>{
0, ctx, detail::string_literal<Char, ':', ' '>{}});
++i;
@ -631,8 +597,7 @@ struct formatter<
formatter<string_type, Char> underlying_;
public:
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return underlying_.parse(ctx);
}
@ -673,22 +638,22 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
#endif
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
using view_ref = conditional_t<std::is_copy_constructible<It>::value,
const join_view<It, Sentinel, Char>&,
join_view<It, Sentinel, Char>&&>;
using view = conditional_t<std::is_copy_constructible<It>::value,
const join_view<It, Sentinel, Char>,
join_view<It, Sentinel, Char>>;
public:
using nonlocking = void;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return value_formatter_.parse(ctx);
}
template <typename FormatContext>
auto format(view_ref& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto it = std::forward<view_ref>(value).begin;
auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) {
using iter =
conditional_t<std::is_copy_constructible<view>::value, It, It&>;
iter it = value.begin;
auto out = ctx.out();
if (it == value.end) return out;
out = value_formatter_.format(*it, ctx);
@ -703,39 +668,11 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
}
};
/// 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 {std::move(begin), end, sep};
}
/**
* Returns a view that formats `range` with elements separated by `sep`.
*
* **Example**:
*
* auto v = std::vector<int>{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
*/
template <typename Range>
auto join(Range&& r, string_view sep)
-> join_view<decltype(detail::range_begin(r)),
decltype(detail::range_end(r))> {
return {detail::range_begin(r), detail::range_end(r), sep};
}
template <typename Char, typename... T> struct tuple_join_view : detail::view {
const std::tuple<T...>& tuple;
template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
const Tuple& tuple;
basic_string_view<Char> sep;
tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
tuple_join_view(const Tuple& t, basic_string_view<Char> s)
: tuple(t), sep{s} {}
};
@ -746,37 +683,36 @@ template <typename Char, typename... T> struct tuple_join_view : detail::view {
# define FMT_TUPLE_JOIN_SPECIFIERS 0
#endif
template <typename Char, typename... T>
struct formatter<tuple_join_view<Char, T...>, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
template <typename Char, typename Tuple>
struct formatter<tuple_join_view<Char, Tuple>, Char,
enable_if_t<is_tuple_like<Tuple>::value>> {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return do_parse(ctx, std::tuple_size<Tuple>());
}
template <typename FormatContext>
auto format(const tuple_join_view<Char, T...>& value,
auto format(const tuple_join_view<Char, Tuple>& value,
FormatContext& ctx) const -> typename FormatContext::iterator {
return do_format(value, ctx,
std::integral_constant<size_t, sizeof...(T)>());
return do_format(value, ctx, std::tuple_size<Tuple>());
}
private:
std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
decltype(detail::tuple::get_formatters<Tuple, Char>(
detail::tuple_index_sequence<Tuple>())) formatters_;
template <typename ParseContext>
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
std::integral_constant<size_t, 0>)
-> decltype(ctx.begin()) {
-> const Char* {
return ctx.begin();
}
template <typename ParseContext, size_t N>
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
template <size_t N>
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
std::integral_constant<size_t, N>)
-> decltype(ctx.begin()) {
-> const Char* {
auto end = ctx.begin();
#if FMT_TUPLE_JOIN_SPECIFIERS
end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
if (N > 1) {
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
if (end != end1)
@ -787,18 +723,20 @@ struct formatter<tuple_join_view<Char, T...>, Char> {
}
template <typename FormatContext>
auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx,
auto do_format(const tuple_join_view<Char, Tuple>&, FormatContext& ctx,
std::integral_constant<size_t, 0>) const ->
typename FormatContext::iterator {
return ctx.out();
}
template <typename FormatContext, size_t N>
auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx,
auto do_format(const tuple_join_view<Char, Tuple>& value, FormatContext& ctx,
std::integral_constant<size_t, N>) const ->
typename FormatContext::iterator {
auto out = std::get<sizeof...(T) - N>(formatters_)
.format(std::get<sizeof...(T) - N>(value.tuple), ctx);
using std::get;
auto out =
std::get<std::tuple_size<Tuple>::value - N>(formatters_)
.format(get<std::tuple_size<Tuple>::value - N>(value.tuple), ctx);
if (N <= 1) return out;
out = detail::copy<Char>(value.sep, out);
ctx.advance_to(out);
@ -846,6 +784,34 @@ struct formatter<
FMT_BEGIN_EXPORT
/// 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 {std::move(begin), end, sep};
}
/**
* Returns a view that formats `range` with elements separated by `sep`.
*
* **Example**:
*
* auto v = std::vector<int>{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
*/
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
auto join(Range&& r, string_view sep)
-> join_view<decltype(detail::range_begin(r)),
decltype(detail::range_end(r))> {
return {detail::range_begin(r), detail::range_end(r), sep};
}
/**
* Returns an object that formats `std::tuple` with elements separated by `sep`.
*
@ -855,9 +821,9 @@ FMT_BEGIN_EXPORT
* fmt::print("{}", fmt::join(t, ", "));
* // Output: 1, a
*/
template <typename... T>
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
-> tuple_join_view<char, T...> {
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
FMT_CONSTEXPR auto join(const Tuple& tuple, string_view sep)
-> tuple_join_view<char, Tuple> {
return {tuple, sep};
}

View File

@ -17,6 +17,7 @@
# include <complex>
# include <cstdlib>
# include <exception>
# include <functional>
# include <memory>
# include <thread>
# include <type_traits>
@ -26,7 +27,8 @@
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
# if FMT_CPLUSPLUS >= 201703L
# if FMT_HAS_INCLUDE(<filesystem>)
# if FMT_HAS_INCLUDE(<filesystem>) && \
(!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0)
# include <filesystem>
# endif
# if FMT_HAS_INCLUDE(<variant>)
@ -122,14 +124,16 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
public:
FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it == end) return it;
it = detail::parse_align(it, end, specs_);
if (it == end) return it;
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
Char c = *it;
if ((c >= '0' && c <= '9') || c == '{')
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
if (it != end && *it == '?') {
debug_ = true;
++it;
@ -145,8 +149,8 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
!path_type_ ? p.native()
: p.generic_string<std::filesystem::path::value_type>();
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx);
if (!debug_) {
auto s = detail::get_path_string<Char>(p, path_string);
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
@ -180,7 +184,8 @@ FMT_END_NAMESPACE
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <std::size_t N, typename Char>
struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
struct formatter<std::bitset<N>, Char>
: nested_formatter<basic_string_view<Char>, Char> {
private:
// Functor because C++11 doesn't support generic lambdas.
struct writer {
@ -200,7 +205,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
template <typename FormatContext>
auto format(const std::bitset<N>& bs, FormatContext& ctx) const
-> decltype(ctx.out()) {
return write_padded(ctx, writer{bs});
return this->write_padded(ctx, writer{bs});
}
};
@ -233,7 +238,7 @@ struct formatter<std::optional<T>, Char,
FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
public:
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
maybe_set_debug_format(underlying_, true);
return underlying_.parse(ctx);
}
@ -277,10 +282,10 @@ FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename T, typename E, typename Char>
struct formatter<std::expected<T, E>, Char,
std::enable_if_t<is_formattable<T, Char>::value &&
std::enable_if_t<(std::is_void<T>::value ||
is_formattable<T, Char>::value) &&
is_formattable<E, Char>::value>> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin();
}
@ -291,7 +296,8 @@ struct formatter<std::expected<T, E>, Char,
if (value.has_value()) {
out = detail::write<Char>(out, "expected(");
out = detail::write_escaped_alternative<Char>(out, *value);
if constexpr (!std::is_void<T>::value)
out = detail::write_escaped_alternative<Char>(out, *value);
} else {
out = detail::write<Char>(out, "unexpected(");
out = detail::write_escaped_alternative<Char>(out, value.error());
@ -307,9 +313,7 @@ FMT_END_NAMESPACE
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <> struct formatter<std::source_location> {
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
return ctx.begin();
}
FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const std::source_location& loc, FormatContext& ctx) const
@ -365,8 +369,7 @@ template <typename T, typename C> struct is_variant_formattable {
FMT_EXPORT
template <typename Char> struct formatter<std::monostate, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin();
}
@ -383,8 +386,7 @@ struct formatter<
Variant, Char,
std::enable_if_t<std::conjunction_v<
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin();
}
@ -413,20 +415,37 @@ FMT_END_NAMESPACE
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename Char> struct formatter<std::error_code, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
template <> struct formatter<std::error_code> {
private:
format_specs specs_;
detail::arg_ref<char> width_ref_;
public:
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
auto it = ctx.begin(), end = ctx.end();
if (it == end) return it;
it = detail::parse_align(it, end, specs_);
if (it == end) return it;
char c = *it;
if ((c >= '0' && c <= '9') || c == '{')
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
return it;
}
template <typename FormatContext>
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write_bytes<Char>(out, ec.category().name(), format_specs());
out = detail::write<Char>(out, Char(':'));
out = detail::write<Char>(out, ec.value());
return out;
FMT_CONSTEXPR20 auto format(const std::error_code& ec,
FormatContext& ctx) const -> decltype(ctx.out()) {
auto specs = specs_;
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx);
memory_buffer buf;
buf.append(string_view(ec.category().name()));
buf.push_back(':');
detail::write<char>(appender(buf), ec.value());
return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()),
specs);
}
};
@ -506,8 +525,7 @@ template <typename Char>
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
> {
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin();
}
@ -528,8 +546,7 @@ struct formatter<
bool with_typename_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
auto it = ctx.begin();
auto end = ctx.end();
if (it == end || *it == '}') return it;
@ -643,7 +660,7 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
if (c.real() != 0) {
*out++ = Char('(');
out = detail::write<Char>(out, c.real(), specs, ctx.locale());
specs.sign = sign::plus;
specs.set_sign(sign::plus);
out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
if (!detail::isfinite(c.imag())) *out++ = Char(' ');
*out++ = Char('i');
@ -657,8 +674,7 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
}
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
detail::type_constant<T, Char>::value);
@ -668,12 +684,11 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
auto format(const std::complex<T>& c, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto specs = specs_;
if (specs.width_ref.kind != detail::arg_id_kind::none ||
specs.precision_ref.kind != detail::arg_id_kind::none) {
detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>(
specs.precision, specs.precision_ref, ctx);
if (specs.dynamic()) {
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
specs.precision_ref, ctx);
}
if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());
@ -681,12 +696,12 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
auto outer_specs = format_specs();
outer_specs.width = specs.width;
outer_specs.fill = specs.fill;
outer_specs.align = specs.align;
outer_specs.copy_fill_from(specs);
outer_specs.set_align(specs.align());
specs.width = 0;
specs.fill = {};
specs.align = align::none;
specs.set_fill({});
specs.set_align(align::none);
do_format(c, specs, ctx, basic_appender<Char>(buf));
return detail::write<Char>(ctx.out(),
@ -695,5 +710,17 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
}
};
FMT_EXPORT
template <typename T, typename Char>
struct formatter<std::reference_wrapper<T>, Char,
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
: formatter<remove_cvref_t<T>, Char> {
template <typename FormatContext>
auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);
}
};
FMT_END_NAMESPACE
#endif // FMT_STD_H_

View File

@ -10,11 +10,12 @@
#include "color.h"
#include "format.h"
#include "ostream.h"
#include "ranges.h"
#ifndef FMT_MODULE
# include <cwchar>
# if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
# if FMT_USE_LOCALE
# include <locale>
# endif
#endif
@ -34,7 +35,8 @@ struct format_string_char<
};
template <typename S>
struct format_string_char<S, enable_if_t<is_compile_string<S>::value>> {
struct format_string_char<
S, enable_if_t<std::is_base_of<detail::compile_string, S>::value>> {
using type = typename S::char_type;
};
@ -43,7 +45,7 @@ using format_string_char_t = typename format_string_char<S>::type;
inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
const format_specs& specs, locale_ref loc) -> bool {
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
#if FMT_USE_LOCALE
auto& numpunct =
std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
auto separator = std::wstring();
@ -58,30 +60,64 @@ inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
FMT_BEGIN_EXPORT
using wstring_view = basic_string_view<wchar_t>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
using wformat_parse_context = parse_context<wchar_t>;
using wformat_context = buffered_context<wchar_t>;
using wformat_args = basic_format_args<wformat_context>;
using wmemory_buffer = basic_memory_buffer<wchar_t>;
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround broken conversion on older gcc.
template <typename... Args> using wformat_string = wstring_view;
inline auto runtime(wstring_view s) -> wstring_view { return s; }
#else
template <typename... Args>
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
template <typename Char, typename... T> struct basic_fstring {
private:
basic_string_view<Char> str_;
static constexpr int num_static_named_args =
detail::count_static_named_args<T...>();
using checker = detail::format_string_checker<
Char, static_cast<int>(sizeof...(T)), num_static_named_args,
num_static_named_args != detail::count_named_args<T...>()>;
using arg_pack = detail::arg_pack<T...>;
public:
using t = basic_fstring;
template <typename S,
FMT_ENABLE_IF(
std::is_convertible<const S&, basic_string_view<Char>>::value)>
FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) {
if (FMT_USE_CONSTEVAL)
detail::parse_format_string<Char>(s, checker(s, arg_pack()));
}
template <typename S,
FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
std::is_same<typename S::char_type, Char>::value)>
FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) {
FMT_CONSTEXPR auto sv = basic_string_view<Char>(S());
FMT_CONSTEXPR int ignore =
(parse_format_string(sv, checker(sv, arg_pack())), 0);
detail::ignore_unused(ignore);
}
basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}
operator basic_string_view<Char>() const { return str_; }
auto get() const -> basic_string_view<Char> { return str_; }
};
template <typename Char, typename... T>
using basic_format_string = basic_fstring<Char, T...>;
template <typename... T>
using wformat_string = typename basic_format_string<wchar_t, T...>::t;
inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
return {{s}};
}
#endif
template <> struct is_char<wchar_t> : std::true_type {};
template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {};
#ifdef __cpp_char8_t
template <>
struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled()> {};
template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
#endif
template <typename... T>
@ -90,14 +126,13 @@ constexpr auto make_wformat_args(T&... args)
return fmt::make_format_args<wformat_context>(args...);
}
#if !FMT_USE_NONTYPE_TEMPLATE_ARGS
inline namespace literals {
#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
constexpr auto operator""_a(const wchar_t* s, size_t)
-> detail::udl_arg<wchar_t> {
inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg<wchar_t> {
return {s};
}
#endif
} // namespace literals
#endif
template <typename It, typename Sentinel>
auto join(It begin, Sentinel end, wstring_view sep)
@ -105,9 +140,9 @@ auto join(It begin, Sentinel end, wstring_view sep)
return {begin, end, sep};
}
template <typename Range>
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
auto join(Range&& range, wstring_view sep)
-> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>,
-> join_view<decltype(std::begin(range)), decltype(std::end(range)),
wchar_t> {
return join(std::begin(range), std::end(range), sep);
}
@ -118,19 +153,19 @@ 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...> {
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
-> tuple_join_view<wchar_t, Tuple> {
return {tuple, sep};
}
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
auto vformat(basic_string_view<Char> format_str,
auto vformat(basic_string_view<Char> fmt,
typename detail::vformat_args<Char>::type args)
-> std::basic_string<Char> {
auto buf = basic_memory_buffer<Char>();
detail::vformat_to(buf, format_str, args);
return to_string(buf);
detail::vformat_to(buf, fmt, args);
return {buf.data(), buf.size()};
}
template <typename... T>
@ -151,8 +186,8 @@ template <typename S, typename... T,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
!std::is_same<Char, wchar_t>::value)>
auto format(const S& format_str, T&&... args) -> std::basic_string<Char> {
return vformat(detail::to_string_view(format_str),
auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
return vformat(detail::to_string_view(fmt),
fmt::make_format_args<buffered_context<Char>>(args...));
}
@ -160,31 +195,33 @@ template <typename Locale, typename S,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat(const Locale& loc, const S& format_str,
inline auto vformat(const Locale& loc, const S& fmt,
typename detail::vformat_args<Char>::type args)
-> std::basic_string<Char> {
return detail::vformat(loc, detail::to_string_view(format_str), args);
auto buf = basic_memory_buffer<Char>();
detail::vformat_to(buf, detail::to_string_view(fmt), args,
detail::locale_ref(loc));
return {buf.data(), buf.size()};
}
template <typename Locale, typename S, typename... T,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format(const Locale& loc, const S& format_str, T&&... args)
inline auto format(const Locale& loc, const S& fmt, T&&... args)
-> std::basic_string<Char> {
return detail::vformat(
loc, detail::to_string_view(format_str),
fmt::make_format_args<buffered_context<Char>>(args...));
return vformat(loc, detail::to_string_view(fmt),
fmt::make_format_args<buffered_context<Char>>(args...));
}
template <typename OutputIt, typename S,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
auto vformat_to(OutputIt out, const S& format_str,
auto vformat_to(OutputIt out, const S& fmt,
typename detail::vformat_args<Char>::type args) -> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, detail::to_string_view(format_str), args);
detail::vformat_to(buf, detail::to_string_view(fmt), args);
return detail::get_iterator(buf, out);
}
@ -203,37 +240,35 @@ template <typename Locale, typename S, typename OutputIt, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to(OutputIt out, const Locale& loc, const S& format_str,
inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
typename detail::vformat_args<Char>::type args)
-> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
vformat_to(buf, detail::to_string_view(format_str), args,
detail::locale_ref(loc));
vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
return detail::get_iterator(buf, out);
}
template <typename OutputIt, typename Locale, typename S, typename... T,
template <typename Locale, typename OutputIt, typename S, typename... T,
typename Char = detail::format_string_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,
inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
T&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, loc, detail::to_string_view(format_str),
return vformat_to(out, loc, detail::to_string_view(fmt),
fmt::make_format_args<buffered_context<Char>>(args...));
}
template <typename OutputIt, typename Char, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to_n(OutputIt out, size_t n,
basic_string_view<Char> format_str,
inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
typename detail::vformat_args<Char>::type args)
-> format_to_n_result<OutputIt> {
using traits = detail::fixed_buffer_traits;
auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
detail::vformat_to(buf, format_str, args);
detail::vformat_to(buf, fmt, args);
return {buf.out(), buf.count()};
}
@ -291,7 +326,7 @@ inline auto vformat(const text_style& ts, wstring_view fmt, wformat_args args)
-> std::wstring {
auto buf = wmemory_buffer();
detail::vformat_to(buf, ts, fmt, args);
return fmt::to_string(buf);
return {buf.data(), buf.size()};
}
template <typename... T>
@ -312,6 +347,22 @@ FMT_DEPRECATED void print(const text_style& ts, wformat_string<T...> fmt,
return print(stdout, ts, fmt, args...);
}
inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
auto buffer = basic_memory_buffer<wchar_t>();
detail::vformat_to(buffer, fmt, args);
detail::write_buffer(os, buffer);
}
template <typename... T>
void print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
}
template <typename... T>
void println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
print(os, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
}
/// Converts `value` to `std::wstring` using the default format for type `T`.
template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
return format(FMT_STRING(L"{}"), value);

View File

@ -16,7 +16,8 @@ template FMT_API auto dragonbox::to_decimal(float x) noexcept
template FMT_API auto dragonbox::to_decimal(double x) noexcept
-> dragonbox::decimal_fp<double>;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
#if FMT_USE_LOCALE
// DEPRECATED! locale_ref in the detail namespace
template FMT_API locale_ref::locale_ref(const std::locale& loc);
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
#endif
@ -27,8 +28,10 @@ template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<char>;
template FMT_API auto decimal_point_impl(locale_ref) -> char;
// DEPRECATED!
template FMT_API void buffer<char>::append(const char*, const char*);
// DEPRECATED!
template FMT_API void vformat_to(buffer<char>&, string_view,
typename vformat_args<>::type, locale_ref);

View File

@ -161,7 +161,7 @@ void detail::format_windows_error(detail::buffer<char>& out, int error_code,
}
void report_windows_error(int error_code, const char* message) noexcept {
report_error(detail::format_windows_error, error_code, message);
do_report_error(detail::format_windows_error, error_code, message);
}
#endif // _WIN32
@ -375,30 +375,25 @@ long getpagesize() {
}
# endif
namespace detail {
void file_buffer::grow(buffer<char>& buf, size_t) {
if (buf.size() == buf.capacity()) static_cast<file_buffer&>(buf).flush();
void ostream::grow(buffer<char>& buf, size_t) {
if (buf.size() == buf.capacity()) static_cast<ostream&>(buf).flush();
}
file_buffer::file_buffer(cstring_view path, const ostream_params& params)
ostream::ostream(cstring_view path, const detail::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) noexcept
ostream::ostream(ostream&& other) noexcept
: buffer<char>(grow, other.data(), other.size(), other.capacity()),
file_(std::move(other.file_)) {
other.clear();
other.set(nullptr, 0);
}
file_buffer::~file_buffer() {
ostream::~ostream() {
flush();
delete[] data();
}
} // namespace detail
ostream::~ostream() = default;
#endif // FMT_USE_FCNTL
FMT_END_NAMESPACE

View File

@ -269,8 +269,8 @@ void Info::command(int narg, char **arg)
if (out == nullptr) return;
fputs("\nInfo-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info\n",out);
std::time_t now = std::time(nullptr);
fmt::print(out,"Printed on {:%a %b %d %H:%M:%S %Y}\n", fmt::localtime(now));
std::tm now = fmt::localtime(std::time(nullptr));
fmt::print(out,"Printed on {}", std::asctime(&now));
if (flags & CONFIG) {
fmt::print(out,"\nLAMMPS version: {} / {}\n", lmp->version, lmp->num_ver);
@ -290,6 +290,7 @@ void Info::command(int narg, char **arg)
fmt::print(out,"\nCompiler: {} with {}\nC++ standard: {}\n",
platform::compiler_info(),platform::openmp_standard(),platform::cxx_standard());
fputs(get_fmt_info().c_str(), out);
fputs("\nActive compile time flags:\n\n",out);
if (has_gzip_support()) fputs("-DLAMMPS_GZIP\n",out);
@ -1361,6 +1362,18 @@ std::string Info::get_fft_info()
/* ---------------------------------------------------------------------- */
static constexpr int fmt_ver_major = FMT_VERSION / 10000;
static constexpr int fmt_ver_minor = (FMT_VERSION % 10000) / 100;
static constexpr int fmt_ver_patch = FMT_VERSION % 100;
std::string Info::get_fmt_info()
{
return fmt::format("Embedded fmt library version: {}.{}.{}\n",
fmt_ver_major, fmt_ver_minor, fmt_ver_patch);
}
/* ---------------------------------------------------------------------- */
void Info::get_memory_info(double *meminfo)
{
double bytes = 0;

View File

@ -49,6 +49,7 @@ class Info : public Command {
static bool has_accelerator_feature(const std::string &, const std::string &,
const std::string &);
static std::string get_fft_info();
static std::string get_fmt_info();
static bool has_gpu_device();
static std::string get_gpu_device_info();
static std::string get_accelerator_info(const std::string &pkg = "");

View File

@ -1457,10 +1457,11 @@ void LAMMPS::print_config(FILE *fp)
fmt::print(fp,"Compiler: {} with {}\nC++ standard: {}\n",
platform::compiler_info(),platform::openmp_standard(),
platform::cxx_standard());
fputs(Info::get_fmt_info().c_str(),fp);
int major,minor;
std::string infobuf = platform::mpi_info(major,minor);
fmt::print(fp,"MPI v{}.{}: {}\n\n",major,minor,infobuf);
fmt::print(fp,"\nMPI v{}.{}: {}\n\n",major,minor,infobuf);
fmt::print(fp,"Accelerator configuration:\n\n{}\n",
Info::get_accelerator_info());

View File

@ -16,6 +16,7 @@
#include "comm.h"
#include "error.h"
#include "fmt/chrono.h"
#include "tokenizer.h"
#include <cstring>
#include <ctime>
@ -231,18 +232,25 @@ void Timer::modify_params(int narg, char **arg)
} else if (strcmp(arg[iarg], "timeout") == 0) {
++iarg;
if (iarg < narg) {
_timeout = utils::timespec2seconds(arg[iarg]);
} else
error->all(FLERR, "Illegal timer command");
try {
_timeout = utils::timespec2seconds(arg[iarg]);
} catch (TokenizerException &) {
error->all(FLERR, "Illegal timeout time: {}", arg[iarg]);
}
} else {
utils::missing_cmd_args(FLERR, "timer timeout", error);
}
} else if (strcmp(arg[iarg], "every") == 0) {
++iarg;
if (iarg < narg) {
_checkfreq = utils::inumeric(FLERR, arg[iarg], false, lmp);
if (_checkfreq <= 0) error->all(FLERR, "Illegal timer command");
} else
error->all(FLERR, "Illegal timer command");
} else
error->all(FLERR, "Illegal timer command");
if (_checkfreq <= 0) error->all(FLERR, "Illegal timer every frequency: {}", arg[iarg]);
} else {
utils::missing_cmd_args(FLERR, "timer every", error);
}
} else {
error->all(FLERR, "Unknown timer keyword {}", arg[iarg]);
}
++iarg;
}

View File

@ -1744,13 +1744,9 @@ double utils::timespec2seconds(const std::string &timespec)
ValueTokenizer values(timespec, ":");
try {
for (i = 0; i < 3; i++) {
if (!values.has_next()) break;
vals[i] = values.next_double();
}
} catch (TokenizerException &) {
return -1.0;
for (i = 0; i < 3; i++) {
if (!values.has_next()) break;
vals[i] = values.next_double();
}
if (i == 3)

View File

@ -0,0 +1,78 @@
---
lammps_version: 29 Aug 2024
tags: generated
date_generated: Tue Nov 12 08:53:18 2024
epsilon: 2e-13
skip_tests:
prerequisites: ! |
atom full
fix efield
pre_commands: ! ""
post_commands: ! |
region half block 0 EDGE EDGE EDGE EDGE EDGE
fix move all nve
fix test solute efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A=1; B=1"
input_file: in.fourmol
natoms: 29
global_scalar: 1.6704454516566274
run_pos: ! |2
1 -2.7045174040786113e-01 2.4911873718363386e+00 -1.6695654631491835e-01
2 3.1004221019407835e-01 2.9612623619618166e+00 -8.5467074498303619e-01
3 -7.0398277208953364e-01 1.2305442007296870e+00 -6.2777337959095758e-01
4 -1.5818277418447926e+00 1.4837528245352911e+00 -1.2538808796681880e+00
5 -9.0729118448236790e-01 9.2661863916543652e-01 3.9958383542336978e-01
6 2.4837968642651539e-01 2.8318965710323424e-01 -1.2316675533799510e+00
7 3.4143233737928985e-01 -2.2652080889821399e-02 -2.5292246648830696e+00
8 1.1742106633496632e+00 -4.8857819177533296e-01 -6.3774855832878818e-01
9 1.3804619006746952e+00 -2.5282186304504617e-01 2.8361638661486044e-01
10 2.0510714422715428e+00 -1.4603992238436605e+00 -9.8323613298241641e-01
11 1.7878067664442001e+00 -1.9921902225913919e+00 -1.8890639278278800e+00
12 3.0062962291402449e+00 -4.9013271581056822e-01 -1.6231874104184338e+00
13 4.0515414154880354e+00 -8.9202039400328714e-01 -1.6400010189207204e+00
14 2.6066986955414859e+00 -4.1789289874186603e-01 -2.6634027530740045e+00
15 2.9695346087268195e+00 5.5422728642528218e-01 -1.2342046800948778e+00
16 2.6747089246970055e+00 -2.4124172919180635e+00 -2.3435358040545039e-02
17 2.2153515161424591e+00 -2.0897925974376559e+00 1.1963115055447653e+00
18 2.1369701703995672e+00 3.0158507413483879e+00 -3.5179348337128169e+00
19 1.5355837136075503e+00 2.6255292355356850e+00 -4.2353987779858899e+00
20 2.7727573005675157e+00 3.6923910449606199e+00 -3.9330842459130921e+00
21 4.9040128073216458e+00 -4.0752348172972228e+00 -3.6210314709902178e+00
22 4.3582355554441330e+00 -4.2126119427287785e+00 -4.4612844196314905e+00
23 5.7439382849308398e+00 -3.5821957939275575e+00 -3.8766361295936442e+00
24 2.0689243582420707e+00 3.1513346907257525e+00 3.1550389754825381e+00
25 1.3045351331495809e+00 3.2665125705836533e+00 2.5111855257438469e+00
26 2.5809237402711407e+00 4.0117602605482343e+00 3.2212060529090203e+00
27 -1.9611343130355228e+00 -4.3563411931353464e+00 2.1098293115521636e+00
28 -2.7473562684513140e+00 -4.0200819932378886e+00 1.5830052163433823e+00
29 -1.3126000191359133e+00 -3.5962518039481126e+00 2.2746342468736911e+00
run_vel: ! |2
1 8.1748902719248895e-03 1.6488825063890555e-02 4.7920575746796803e-03
2 5.4511084007743318e-03 5.2051261388670498e-03 -1.4434422725438370e-03
3 -8.2274804663814219e-03 -1.2934351097927732e-02 -4.0974640813287184e-03
4 -3.7810439919825625e-03 -6.5599673887508873e-03 -1.1281975069807595e-03
5 -1.1114610957297140e-02 -9.7941960094448405e-03 -2.8000606969231651e-03
6 -3.9614471141667384e-02 4.6885125158393097e-02 3.6916688468892268e-02
7 9.0823633550694307e-04 -1.0137209973964618e-02 -5.1576821598862101e-02
8 7.7662077312228937e-03 -3.3034358179113549e-03 3.4641870510036560e-02
9 1.9711566942801151e-03 3.6632927647716452e-03 1.5119486507285342e-02
10 2.9189761590759169e-02 -2.9234948386605512e-02 -1.5014329233453094e-02
11 -4.7800378310285741e-03 -3.7519133265433713e-03 -2.3499734597008941e-03
12 2.2651912734175032e-03 -3.4688766322378106e-04 -3.0617028612628929e-03
13 2.7541524307768692e-03 5.8168212242409026e-03 -7.9509320189794788e-04
14 3.5269195768251409e-03 -5.7943367272026312e-03 -3.9501557653067150e-03
15 -1.8489707819649144e-03 -5.8542853523402688e-03 6.2913780244787517e-03
16 1.8687298458400135e-02 -1.3267695591612149e-02 -4.5638131306342533e-02
17 -1.2902476276599238e-02 9.7586450769834993e-03 3.7292773489970149e-02
18 -8.0065797284243809e-04 -8.6270476160336701e-04 -1.4483040521307380e-03
19 1.2452390811276265e-03 -2.5061097157054544e-03 7.2998631050251199e-03
20 3.5930060220586732e-03 3.6938860299406654e-03 3.2322732694668697e-03
21 -1.4689220345082588e-03 -2.7352130061578030e-04 7.0581623990333337e-04
22 -7.0694199253619090e-03 -4.2577148926459460e-03 2.8079117595322244e-04
23 6.0446963119181341e-03 -1.4000131615895693e-03 2.5819754845648850e-03
24 3.1926367864219455e-04 -9.9445665025542493e-04 1.4999996888246658e-04
25 1.3789754587624503e-04 -4.4335894897561037e-03 -8.1808136628206090e-04
26 2.0485904035354775e-03 2.7813358632583834e-03 4.3245727149805969e-03
27 4.5604120337294426e-04 -1.0305523013893942e-03 2.1188058337867958e-04
28 -6.2544520861285771e-03 1.4127711177082084e-03 -1.8429821885090839e-03
29 6.4110631550796319e-04 3.1273432723457764e-03 3.7253671103666878e-03
...

View File

@ -0,0 +1,78 @@
---
lammps_version: 29 Aug 2024
tags: generated
date_generated: Tue Nov 12 08:53:32 2024
epsilon: 2e-13
skip_tests:
prerequisites: ! |
atom full
fix efield
pre_commands: ! ""
post_commands: ! |
region half block 0 EDGE EDGE EDGE EDGE EDGE
fix move all nve
fix test solute efield/lepton "A*exp(-B*r)/r; r=abs(sqrt(x^2+y^2+z^2)); A=1; B=1" region half
input_file: in.fourmol
natoms: 29
global_scalar: 1.6224257709052041
run_pos: ! |2
1 -2.7045550227503484e-01 2.4912161552650542e+00 -1.6695870672991683e-01
2 3.1004259198805995e-01 2.9612627263370541e+00 -8.5467109039916112e-01
3 -7.0398509489328243e-01 1.2305505728672561e+00 -6.2777617667397034e-01
4 -1.5818160259170788e+00 1.4837409852928742e+00 -1.2538708748776086e+00
5 -9.0719735527200218e-01 9.2652068440082169e-01 3.9954204708150570e-01
6 2.4837966543189102e-01 2.8318973351568738e-01 -1.2316676191454061e+00
7 3.4143233915513954e-01 -2.2652082568946554e-02 -2.5292246658165061e+00
8 1.1742106609334979e+00 -4.8857818923052260e-01 -6.3774855737315483e-01
9 1.3804619006758012e+00 -2.5282186302388332e-01 2.8361638664582128e-01
10 2.0510714422251031e+00 -1.4603992237831411e+00 -9.8323613295984091e-01
11 1.7878067664437562e+00 -1.9921902225910537e+00 -1.8890639278278771e+00
12 3.0062962291411979e+00 -4.9013271581129958e-01 -1.6231874104189474e+00
13 4.0515414154880700e+00 -8.9202039400332667e-01 -1.6400010189207255e+00
14 2.6066986955415903e+00 -4.1789289874193392e-01 -2.6634027530740991e+00
15 2.9695346087273786e+00 5.5422728642511987e-01 -1.2342046800950848e+00
16 2.6747089246973057e+00 -2.4124172919184503e+00 -2.3435358040670606e-02
17 2.2153515161430364e+00 -2.0897925974384783e+00 1.1963115055450686e+00
18 2.1369701703991302e+00 3.0158507413490390e+00 -3.5179348337124896e+00
19 1.5355837136075265e+00 2.6255292355357338e+00 -4.2353987779858606e+00
20 2.7727573005674877e+00 3.6923910449606310e+00 -3.9330842459130633e+00
21 4.9040128073216458e+00 -4.0752348172972228e+00 -3.6210314709902178e+00
22 4.3582355554441330e+00 -4.2126119427287785e+00 -4.4612844196314905e+00
23 5.7439382849308398e+00 -3.5821957939275575e+00 -3.8766361295936442e+00
24 2.0689243582419663e+00 3.1513346907264923e+00 3.1550389754824169e+00
25 1.3045351331492137e+00 3.2665125705841698e+00 2.5111855257432798e+00
26 2.5809237402711096e+00 4.0117602605482601e+00 3.2212060529089785e+00
27 -1.9611343130355403e+00 -4.3563411931354130e+00 2.1098293115521884e+00
28 -2.7473562684513166e+00 -4.0200819932378939e+00 1.5830052163433843e+00
29 -1.3126000191359157e+00 -3.5962518039481259e+00 2.2746342468736964e+00
run_vel: ! |2
1 8.1707610252536762e-03 1.6516729522797459e-02 4.7898444127747793e-03
2 5.4518750405498674e-03 5.2058557730251687e-03 -1.4441331386370641e-03
3 -8.2289377254294322e-03 -1.2927459179389453e-02 -4.1002423460516626e-03
4 -3.7700883579582412e-03 -6.5718761179186279e-03 -1.1180449896675260e-03
5 -1.1021377362739846e-02 -9.8914014766124762e-03 -2.8411972311159365e-03
6 -3.9614514600574871e-02 4.6885283311817079e-02 3.6916556408268048e-02
7 9.0823995329068752e-04 -1.0137213428025349e-02 -5.1576824114592634e-02
8 7.7662014866174776e-03 -3.3034295723750589e-03 3.4641871541434638e-02
9 1.9711566911953310e-03 3.6632928332818136e-03 1.5119486593282045e-02
10 2.9189761435066477e-02 -2.9234948184549876e-02 -1.5014329155936850e-02
11 -4.7800378317950521e-03 -3.7519133256272356e-03 -2.3499734593625606e-03
12 2.2651912749160931e-03 -3.4688766464208300e-04 -3.0617028620660344e-03
13 2.7541524308356854e-03 5.8168212241007178e-03 -7.9509320188147147e-04
14 3.5269195770455336e-03 -5.7943367273509527e-03 -3.9501557655038776e-03
15 -1.8489707807796338e-03 -5.8542853526596435e-03 6.2913780240085072e-03
16 1.8687298458816809e-02 -1.3267695592172753e-02 -4.5638131306663686e-02
17 -1.2902476275417624e-02 9.7586450753110940e-03 3.7292773490567067e-02
18 -8.0065797374504898e-04 -8.6270476028742454e-04 -1.4483040514595652e-03
19 1.2452390810788788e-03 -2.5061097156065682e-03 7.2998631050903854e-03
20 3.5930060220034791e-03 3.6938860299639783e-03 3.2322732695251408e-03
21 -1.4689220345081530e-03 -2.7352130061585414e-04 7.0581623990322755e-04
22 -7.0694199253619021e-03 -4.2577148926459503e-03 2.8079117595321425e-04
23 6.0446963119181419e-03 -1.4000131615895712e-03 2.5819754845648798e-03
24 3.1926367843162763e-04 -9.9445664874966543e-04 1.4999996864545090e-04
25 1.3789754514824566e-04 -4.4335894886887352e-03 -8.1808136740210897e-04
26 2.0485904034778955e-03 2.7813358633230435e-03 4.3245727148973397e-03
27 4.5604120333659156e-04 -1.0305523015253445e-03 2.1188058342984497e-04
28 -6.2544520861335402e-03 1.4127711176935673e-03 -1.8429821885043371e-03
29 6.4110631550259628e-04 3.1273432723195943e-03 3.7253671103774067e-03
...

View File

@ -0,0 +1,154 @@
---
lammps_version: 19 Nov 2024
date_generated: Wed Dec 11 15:29:39 2024
epsilon: 1e-7
skip_tests:
prerequisites: ! |
pair dispersion/d3
pre_commands: ! ""
post_commands: ! ""
input_file: in.manybody
pair_style: dispersion/d3 zero pbe 12.0 12.0
pair_coeff: ! |
* * Si Si Si Si Si Si Si Si
extract: ! ""
natoms: 64
init_vdwl: -9.262365244070887
init_coul: 0
init_stress: ! |-
-1.8070680161672350e+00 -1.8151671910236220e+00 -1.9214651805560712e+00 -4.1552461721989307e-02 -7.1708481048125128e-01 -1.3638435843456306e-01
init_forces: ! |2
1 4.5901744149339814e-04 -5.8645004258887296e-03 -2.6408414442435817e-03
2 4.1982212100397494e-02 7.7916988680959785e-03 4.1558505642265483e-03
3 -1.0599537919974110e-03 -1.5284351857714875e-03 1.3250226437598804e-03
4 1.2952849248980391e-02 -1.2730397232186651e-02 6.4718612421368858e-03
5 1.9307066949767124e-03 3.1031437654175332e-03 3.5451961708816851e-03
6 6.0636534612296018e-03 -3.4538157294514024e-02 -1.5549038123319472e-02
7 -5.5478612773693318e-03 9.7600792842619001e-03 -2.1450928859339292e-02
8 1.7128887807534021e-05 -1.3865910298862735e-04 8.9170060304616253e-04
9 -5.8527207660040638e-02 8.5011601463707259e-02 7.9837310973084497e-02
10 -9.9174557760647319e-03 1.3163286906290764e-02 1.2367199083459195e-02
11 -2.0922976098149738e-02 1.7815876096333588e-02 -3.2459912594439561e-02
12 9.4039240797013243e-02 3.7466484052249387e-02 -9.4966824523796730e-03
13 -4.3611820846840114e-02 -7.5650463287387754e-02 4.1545920229193796e-02
14 1.3914347992697577e-02 -9.8186446053987742e-03 -1.5039026985332828e-02
15 9.8798529628413748e-02 -9.6939234786348333e-02 -3.5897115916559530e-02
16 -1.8828449808127548e-02 1.0084992417269656e-02 -1.6621409840469250e-02
17 1.8867454988099414e-02 -3.3410341395584034e-02 5.8649656805337354e-02
18 -5.7757243295743490e-03 3.7525865932555918e-03 -1.7465564682291646e-02
19 7.3146350339646261e-03 -5.0979152089016683e-03 -5.7918362966919833e-03
20 1.2526948607359642e-01 3.4964179836823706e-02 -4.0345565678621194e-02
21 -7.9108983611317768e-02 -7.4234491850519224e-02 7.8298798433197120e-02
22 3.3256958035759267e-02 -3.5876634662328263e-03 -5.5658445807261810e-03
23 -9.4983041888941230e-02 -1.6190744700903256e-01 6.5979264480813399e-02
24 -3.9837469539795965e-02 2.5364084079376788e-02 -2.8343465953968475e-02
25 -7.3424056398832139e-03 -1.1672660207324508e-02 -4.2413533423389452e-03
26 7.1482435767536698e-02 7.9794866672039319e-02 -1.2051822893472583e-01
27 -1.2443813900029382e-02 -4.4129788887813590e-03 -4.9977235842165457e-03
28 -5.0454676878239251e-03 -4.8367643826771898e-03 -9.7359590852317181e-03
29 5.0973790709941257e-02 -3.5296812997722318e-02 -1.5607922729704526e-02
30 6.9152527680774289e-02 -1.5810831557831798e-03 3.8412598766233222e-02
31 2.4462930027397904e-02 -3.5045454052408158e-02 -1.9154039485981871e-02
32 2.9037764598216036e-02 -6.8595457693026449e-03 -3.2736895722578810e-03
33 -2.3571014326886783e-02 7.4043101437256172e-03 -2.8705289218120600e-02
34 -1.4606618211317998e-02 -9.1068965341847558e-04 -8.5624377570787912e-03
35 -3.2510043401035402e-02 -2.8006234725365901e-02 -4.6845303279608771e-02
36 6.2991561249353990e-03 2.3238393607814253e-02 -5.8116057369683007e-03
37 2.6891579366883651e-02 -1.3896976671852732e-02 3.1371675512071220e-02
38 2.0868635140715318e-02 5.0357172404813764e-03 -5.3296214134632008e-03
39 -8.0127916540111269e-02 -3.7084303697709070e-02 1.2218320413943409e-01
40 -3.9584086191698675e-02 1.4186027994256518e-02 -1.1786983662869569e-02
41 -2.4078556290238202e-02 2.3979806392354495e-02 3.9808779679712705e-02
42 1.2092253594807115e-01 7.0237820528219294e-02 -6.7634093701619297e-02
43 -4.7905857363210326e-02 1.7234517679973846e-01 6.1081728342102619e-02
44 -8.9268222669576444e-02 1.0935256558697629e-01 4.9391188655423857e-02
45 -1.0932468625449131e-02 -1.1437973186082834e-02 2.2070666035756106e-02
46 -3.6031863627779687e-02 2.6734739238025461e-02 -3.3611450612771009e-02
47 1.4499510792417522e-03 -1.4213296744594713e-02 -2.3112799817407201e-04
48 -1.3767091755648294e-02 -3.0136222933599762e-03 1.3113656065372467e-02
49 -9.7091851340953099e-03 3.6127847173236860e-02 1.4509648044635070e-02
50 8.4557962865172906e-02 -1.0736631874343017e-01 9.9597088988686328e-02
51 -1.0386138512718579e-02 -2.0257306348498042e-02 -3.3076970024004795e-02
52 -4.6611247598798901e-02 6.5689772901113247e-02 1.9370639130365311e-02
53 -5.5610674070546090e-03 -1.4027210037762585e-02 8.7210863818644770e-03
54 -4.3167807623476724e-02 5.3419018792160038e-02 -1.5968205606008208e-02
55 2.1005445106472131e-03 1.5540888545067990e-02 3.0653660856435228e-02
56 -2.0590128088026315e-04 -4.1762635041913861e-03 1.7714423656329605e-02
57 1.0284475505097292e-02 4.9815307763691908e-03 1.2436353033202291e-02
58 -1.0342665676627626e-01 -1.9280058551284476e-02 -7.4866501808988087e-02
59 -2.3544588605186314e-03 3.6121601861319316e-03 -4.6871794758065605e-03
60 -5.4150711425366791e-03 5.8612714396504555e-02 1.4839344681837788e-02
61 2.7954413433097583e-03 -5.0942788256137531e-02 7.2754423172912289e-03
62 1.1252409114510897e-01 -8.8720719849435095e-02 5.4683231090040328e-02
63 -3.1773161308752101e-02 3.6061405691521872e-02 -3.8399113596128895e-02
64 -1.4722975703463983e-02 -2.6147363460941667e-02 -2.1059016257148011e-01
run_vdwl: -9.262826276539041
run_coul: 0
run_stress: ! |-
-1.8014717148220629e+00 -1.8087390477796537e+00 -1.9142638698777830e+00 -3.9974176411585433e-02 -7.1417886625446692e-01 -1.3759726065342742e-01
run_forces: ! |2
1 4.7667962871302064e-04 -5.8467702639815730e-03 -2.6991867530137183e-03
2 4.1869408756196061e-02 8.4979875396755736e-03 3.4984717617200642e-03
3 -9.9160928389676294e-04 -1.4869879157543243e-03 1.2223462368121266e-03
4 1.3147106326425097e-02 -1.2926544726456277e-02 6.7789603977131685e-03
5 1.9770775501047611e-03 3.1765296749256397e-03 3.5629842559820419e-03
6 5.7506960260337615e-03 -3.4699407409212034e-02 -1.5506043496333955e-02
7 -5.3406567846472110e-03 9.4551314732373871e-03 -2.0752905880674206e-02
8 8.7145147942647994e-05 -2.8842758704853994e-05 8.0207322231987555e-04
9 -5.8415508752920696e-02 8.4979266050254798e-02 7.9622715923589979e-02
10 -9.9578406934257829e-03 1.3145690562371913e-02 1.2350278008781093e-02
11 -2.0970548283900613e-02 1.7641558319062160e-02 -3.3050100269910745e-02
12 9.5891788559756261e-02 3.8024542707650773e-02 -9.8061835139289615e-03
13 -4.4952222762277574e-02 -7.6842596098760999e-02 4.2613909344851382e-02
14 1.4295961622308551e-02 -1.0328974985624625e-02 -1.5428512528767140e-02
15 9.9943438550046268e-02 -9.7907452664271769e-02 -3.6257259204378979e-02
16 -1.8390119036246416e-02 9.7159754168328807e-03 -1.6211888959160415e-02
17 1.8981263199444591e-02 -3.3819017834561864e-02 5.9290153986863804e-02
18 -5.6513870204191862e-03 3.7641108672139441e-03 -1.7558647302488333e-02
19 7.4901241599460017e-03 -4.9270563654430326e-03 -5.9132694173721096e-03
20 1.2404887106966292e-01 3.4634285214608047e-02 -4.0135253428616791e-02
21 -7.8277898329671802e-02 -7.3279299061393410e-02 7.8010388051092297e-02
22 3.3238064217578078e-02 -3.5092881119841469e-03 -5.5130499477600743e-03
23 -9.5777464822891442e-02 -1.6270801792262735e-01 6.6577987317167353e-02
24 -4.0548984401360968e-02 2.6001318442684454e-02 -2.8710977737247827e-02
25 -7.2079783062206065e-03 -1.1551923840558299e-02 -3.9390884564980888e-03
26 7.2339414723388659e-02 7.9165643731302623e-02 -1.2169899193410784e-01
27 -1.2311213312665015e-02 -4.3068558457195986e-03 -4.9048891116894693e-03
28 -5.1134183157394847e-03 -4.9743298126113068e-03 -9.7660849586977162e-03
29 5.0646655331378507e-02 -3.5366362323187593e-02 -1.5821692482521729e-02
30 6.8872718311900991e-02 -2.6404119526525157e-04 3.9973810783156115e-02
31 2.4365821183292665e-02 -3.5211120751695441e-02 -1.9277907381276990e-02
32 2.9047476664616767e-02 -6.6602395038829866e-03 -3.0527687942334758e-03
33 -2.3100260653796608e-02 7.7806328399545937e-03 -2.8840665484158416e-02
34 -1.4082353103513787e-02 -1.2664441856360465e-03 -8.7897343645731985e-03
35 -3.2837748489127933e-02 -2.8259033656815206e-02 -4.7109045095865137e-02
36 6.3043838001276449e-03 2.2728472774255215e-02 -5.6021644246419438e-03
37 2.6212204671836617e-02 -1.3029975577260208e-02 3.1750286315189745e-02
38 2.0139944452979241e-02 4.3293211501602355e-03 -6.1649221447719615e-03
39 -7.8960492305738997e-02 -3.6406244109795260e-02 1.2184493007508632e-01
40 -3.9632145471438944e-02 1.3535049580284708e-02 -1.1321798778509602e-02
41 -2.4388307313721387e-02 2.3366329734192243e-02 3.8928089351917827e-02
42 1.1996964485176551e-01 6.9851097891208414e-02 -6.7069887050515309e-02
43 -4.8078980444857013e-02 1.7214309658435833e-01 6.1467794064474092e-02
44 -9.0284549171230966e-02 1.1015441455508669e-01 5.0331470960535987e-02
45 -1.0780088763184573e-02 -1.1270483165899507e-02 2.2080179323856999e-02
46 -3.6837588895857240e-02 2.7230340603483512e-02 -3.4349458862779035e-02
47 1.9027883772889591e-03 -1.3952420713065544e-02 -8.4498460237889667e-04
48 -1.3553909303709658e-02 -3.5297267658357221e-03 1.3635814385361164e-02
49 -9.5576836243609284e-03 3.6186064167046728e-02 1.4320944955278008e-02
50 8.5217870416684924e-02 -1.0799325876848664e-01 1.0051859972722318e-01
51 -1.0113063844638476e-02 -2.0226413912563735e-02 -3.3234528235788117e-02
52 -4.6943693418830201e-02 6.5649633286230746e-02 1.9270389814905101e-02
53 -5.4874429583722370e-03 -1.4030397163369601e-02 8.5032803055005886e-03
54 -4.2513762116223583e-02 5.3134910658803179e-02 -1.5583625460937492e-02
55 2.2355623057473926e-03 1.5758808140961804e-02 3.0512038204829561e-02
56 2.6470325258791221e-04 -3.6590607960638329e-03 1.7588493428989670e-02
57 1.0304091828730023e-02 5.7001837939965440e-03 1.2617318628876883e-02
58 -1.0367740879426791e-01 -1.9270956079747929e-02 -7.4383753891338625e-02
59 -2.4598814101855909e-03 3.6232140177768373e-03 -4.7141806905685686e-03
60 -5.0750993133886020e-03 5.8880547694201937e-02 1.4800121801422891e-02
61 2.7189102310242325e-03 -5.1306885606950549e-02 7.3310325318400645e-03
62 1.1256471955447235e-01 -8.8211823429294622e-02 5.4263270982756615e-02
63 -3.2228752477428985e-02 3.6691295193452315e-02 -3.8707049961896577e-02
64 -1.5804472791823187e-02 -2.5887199342793252e-02 -2.1134763354069236e-01
...

View File

@ -1073,7 +1073,7 @@ TEST(Utils, timespec2seconds_mmfraction)
TEST(Utils, timespec2seconds_invalid)
{
ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:aa:45"), -1.0);
ASSERT_THROW(utils::timespec2seconds("2:aa:45"), TokenizerException);
}
TEST(Utils, date2num)