Merge pull request #4181 from gplummer317/ctip

Charge Transfer Interatomic Potential (CTIP) pair style and qeq fix
This commit is contained in:
Axel Kohlmeyer
2024-10-02 19:26:09 -04:00
committed by GitHub
25 changed files with 21550 additions and 32 deletions

View File

@ -178,6 +178,7 @@ OPT.
* :doc:`python/move <fix_python_move>` * :doc:`python/move <fix_python_move>`
* :doc:`qbmsst <fix_qbmsst>` * :doc:`qbmsst <fix_qbmsst>`
* :doc:`qeq/comb (o) <fix_qeq_comb>` * :doc:`qeq/comb (o) <fix_qeq_comb>`
* :doc:`qeq/ctip <fix_qeq>`
* :doc:`qeq/dynamic <fix_qeq>` * :doc:`qeq/dynamic <fix_qeq>`
* :doc:`qeq/fire <fix_qeq>` * :doc:`qeq/fire <fix_qeq>`
* :doc:`qeq/point <fix_qeq>` * :doc:`qeq/point <fix_qeq>`

View File

@ -59,6 +59,7 @@ OPT.
* :doc:`comb (o) <pair_comb>` * :doc:`comb (o) <pair_comb>`
* :doc:`comb3 <pair_comb>` * :doc:`comb3 <pair_comb>`
* :doc:`cosine/squared <pair_cosine_squared>` * :doc:`cosine/squared <pair_cosine_squared>`
* :doc:`coul/ctip <pair_coul>`
* :doc:`coul/cut (gko) <pair_coul>` * :doc:`coul/cut (gko) <pair_coul>`
* :doc:`coul/cut/dielectric <pair_dielectric>` * :doc:`coul/cut/dielectric <pair_dielectric>`
* :doc:`coul/cut/global (o) <pair_coul>` * :doc:`coul/cut/global (o) <pair_coul>`

View File

@ -357,6 +357,7 @@ accelerated styles exist.
* :doc:`python/move <fix_python_move>` - move particles using a Python function during a simulation run * :doc:`python/move <fix_python_move>` - move particles using a Python function during a simulation run
* :doc:`qbmsst <fix_qbmsst>` - quantum bath multi-scale shock technique time integrator * :doc:`qbmsst <fix_qbmsst>` - quantum bath multi-scale shock technique time integrator
* :doc:`qeq/comb <fix_qeq_comb>` - charge equilibration for COMB potential * :doc:`qeq/comb <fix_qeq_comb>` - charge equilibration for COMB potential
* :doc:`qeq/ctip <fix_qeq>` - charge equilibration for CTIP potential
* :doc:`qeq/dynamic <fix_qeq>` - charge equilibration via dynamic method * :doc:`qeq/dynamic <fix_qeq>` - charge equilibration via dynamic method
* :doc:`qeq/fire <fix_qeq>` - charge equilibration via FIRE minimizer * :doc:`qeq/fire <fix_qeq>` - charge equilibration via FIRE minimizer
* :doc:`qeq/point <fix_qeq>` - charge equilibration via point method * :doc:`qeq/point <fix_qeq>` - charge equilibration via point method

View File

@ -1,6 +1,7 @@
.. index:: fix qeq/point .. index:: fix qeq/point
.. index:: fix qeq/shielded .. index:: fix qeq/shielded
.. index:: fix qeq/slater .. index:: fix qeq/slater
.. index:: fix qeq/ctip
.. index:: fix qeq/dynamic .. index:: fix qeq/dynamic
.. index:: fix qeq/fire .. index:: fix qeq/fire
@ -13,6 +14,9 @@ fix qeq/shielded command
fix qeq/slater command fix qeq/slater command
====================== ======================
fix qeq/ctip command
====================
fix qeq/dynamic command fix qeq/dynamic command
======================= =======================
@ -27,18 +31,20 @@ Syntax
fix ID group-ID style Nevery cutoff tolerance maxiter qfile keyword ... fix ID group-ID style Nevery cutoff tolerance maxiter qfile keyword ...
* ID, group-ID are documented in :doc:`fix <fix>` command * ID, group-ID are documented in :doc:`fix <fix>` command
* style = *qeq/point* or *qeq/shielded* or *qeq/slater* or *qeq/dynamic* or *qeq/fire* * style = *qeq/point* or *qeq/shielded* or *qeq/slater* or *qeq/ctip* or *qeq/dynamic* or *qeq/fire*
* Nevery = perform charge equilibration every this many steps * Nevery = perform charge equilibration every this many steps
* cutoff = global cutoff for charge-charge interactions (distance unit) * cutoff = global cutoff for charge-charge interactions (distance unit)
* tolerance = precision to which charges will be equilibrated * tolerance = precision to which charges will be equilibrated
* maxiter = maximum iterations to perform charge equilibration * maxiter = maximum iterations to perform charge equilibration
* qfile = a filename with QEq parameters or *coul/streitz* or *reaxff* * qfile = a filename with QEq parameters or *coul/streitz* or *coul/ctip* or *reaxff*
* zero or more keyword/value pairs may be appended * zero or more keyword/value pairs may be appended
* keyword = *alpha* or *qdamp* or *qstep* or *warn* * keyword = *alpha* or *cdamp* or *maxrepeat* or *qdamp* or *qstep* or *warn*
.. parsed-literal:: .. parsed-literal::
*alpha* value = Slater type orbital exponent (qeq/slater only) *alpha* value = Slater type orbital exponent (qeq/slater only)
*cdamp* value = damping parameter for Coulomb interactions (qeq/ctip only)
*maxrepeat* value = number of equilibration cycles allowed to ensure no atoms cross charge bounds (qeq/ctip only)
*qdamp* value = damping factor for damped dynamics charge solver (qeq/dynamic and qeq/fire only) *qdamp* value = damping factor for damped dynamics charge solver (qeq/dynamic and qeq/fire only)
*qstep* value = time step size for damped dynamics charge solver (qeq/dynamic and qeq/fire only) *qstep* value = time step size for damped dynamics charge solver (qeq/dynamic and qeq/fire only)
*warn* value = do (=yes) or do not (=no) print a warning when the maximum number of iterations is reached *warn* value = do (=yes) or do not (=no) print a warning when the maximum number of iterations is reached
@ -51,6 +57,7 @@ Examples
fix 1 all qeq/point 1 10 1.0e-6 200 param.qeq1 fix 1 all qeq/point 1 10 1.0e-6 200 param.qeq1
fix 1 qeq qeq/shielded 1 8 1.0e-6 100 param.qeq2 fix 1 qeq qeq/shielded 1 8 1.0e-6 100 param.qeq2
fix 1 all qeq/slater 5 10 1.0e-6 100 params alpha 0.2 fix 1 all qeq/slater 5 10 1.0e-6 100 params alpha 0.2
fix 1 all qeq/ctip 1 12 1.0e-8 100 coul/ctip cdamp 0.30 maxrepeat 10
fix 1 qeq qeq/dynamic 1 12 1.0e-3 100 my_qeq fix 1 qeq qeq/dynamic 1 12 1.0e-3 100 my_qeq
fix 1 all qeq/fire 1 10 1.0e-3 100 my_qeq qdamp 0.2 qstep 0.1 fix 1 all qeq/fire 1 10 1.0e-3 100 my_qeq qdamp 0.2 qstep 0.1
@ -103,7 +110,7 @@ equalizes the derivative of energy with respect to charge of all the
atoms) by adjusting the partial charge on individual atoms based on atoms) by adjusting the partial charge on individual atoms based on
interactions with their neighbors within *cutoff*\ . It requires a few interactions with their neighbors within *cutoff*\ . It requires a few
parameters in the appropriate units for each atom type which are read parameters in the appropriate units for each atom type which are read
from a file specified by *qfile*\ . The file has the following format from a file specified by *qfile*\ . The file has the following format:
.. parsed-literal:: .. parsed-literal::
@ -112,20 +119,32 @@ from a file specified by *qfile*\ . The file has the following format
... ...
Ntype chi eta gamma zeta qcore Ntype chi eta gamma zeta qcore
except for fix style *qeq/ctip* where the format is:
.. parsed-literal::
1 chi eta gamma zeta qcore qmin qmax omega
2 chi eta gamma zeta qcore qmin qmax omega
...
Ntype chi eta gamma zeta qcore qmin qmax omega
There have to be parameters given for every atom type. Wildcard entries There have to be parameters given for every atom type. Wildcard entries
are possible using the same type range syntax as for "coeff" commands are possible using the same type range syntax as for "coeff" commands
(i.e., n\*m, n\*, \*m, \*). Later entries will overwrite previous ones. (i.e., n\*m, n\*, \*m, \*). Later entries will overwrite previous ones.
Empty lines or any text following the pound sign (#) are ignored. Empty lines or any text following the pound sign (#) are ignored. Each
Each line starts with the atom type followed by five parameters. line starts with the atom type followed by eight parameters. Only a
Only a subset of the parameters is used by each QEq style as described subset of the parameters is used by each QEq style as described below,
below, thus the others can be set to 0.0 if desired, but all five thus the others can be set to 0.0 if desired, but all eight entries per
entries per line are required. line are required.
* *chi* = electronegativity in energy units * *chi* = electronegativity in energy units
* *eta* = self-Coulomb potential in energy units * *eta* = self-Coulomb potential in energy units
* *gamma* = shielded Coulomb constant defined by :ref:`ReaxFF force field <vanDuin>` in distance units * *gamma* = shielded Coulomb constant defined by :ref:`ReaxFF force field <vanDuin>` in distance units
* *zeta* = Slater type orbital exponent defined by the :ref:`Streitz-Mintmire <Streitz1>` potential in reverse distance units * *zeta* = Slater type orbital exponent defined by the :ref:`Streitz-Mintmire <Streitz1>` potential in reverse distance units
* *qcore* = charge of the nucleus defined by the :ref:`Streitz-Mintmire potential <Streitz1>` potential in charge units * *qcore* = charge of the nucleus defined by the :ref:`Streitz-Mintmire potential <Streitz1>` potential in charge units
* *qmin* = lower bound on the allowed charge defined by the :ref:`CTIP <CTIP1>` potential in charge units
* *qmax* = upper bound on the allowed charge defined by the :ref:`CTIP <CTIP1>` potential in charge units
* *omega* = penalty parameter used to enforce charge bounds defined by the :ref:`CTIP <CTIP1>` potential in energy units
The fix qeq styles will print a warning if the charges are not The fix qeq styles will print a warning if the charges are not
equilibrated within *tolerance* by *maxiter* steps, unless the equilibrated within *tolerance* by *maxiter* steps, unless the
@ -171,6 +190,22 @@ on atoms via the matrix inversion method. A tolerance of 1.0e-6 is
usually a good number. Keyword *alpha* can be used to change the Slater usually a good number. Keyword *alpha* can be used to change the Slater
type orbital exponent. type orbital exponent.
.. versionadded:: TBD
The *qeq/ctip* style describes partial charges on atoms in the same way
as style *qeq/shielded* but also enables the definition of charge
bounds. Only the *chi*, *eta*, *gamma*, *qmin*, *qmax*, and *omega*
parameters from the *qfile* file are used. When using the string
*coul/ctip* as filename, these parameters are extracted directly from an
active *coul/ctip* pair style. This style solves partial charges on
atoms via the matrix inversion method. Keyword *cdamp* can be used to
change the damping parameter used to calculate Coulomb interactions.
Keyword *maxrepeat* can be used to adjust the number of equilibration
cycles allowed to ensure no atoms have crossed the charge bounds. A
value of 10 is usually a good choice. A tolerance between 1.0e-6 and
1.0e-8 is usually a good choice but should be checked in conjunction
with the timestep for adequate energy conservation during dynamic runs.
The *qeq/dynamic* style describes partial charges on atoms as point The *qeq/dynamic* style describes partial charges on atoms as point
charges that interact through 1/r, but the extended Lagrangian method is charges that interact through 1/r, but the extended Lagrangian method is
used to solve partial charges on atoms. Only the *chi* and *eta* used to solve partial charges on atoms. Only the *chi* and *eta*
@ -186,7 +221,7 @@ minimization algorithm to solve for equilibrium charges. Keyword
*qdamp* can be used to change the damping factor, while keyword *qstep* *qdamp* can be used to change the damping factor, while keyword *qstep*
can be used to change the time step size. can be used to change the time step size.
Note that *qeq/point*, *qeq/shielded*, and *qeq/slater* describe Note that *qeq/point*, *qeq/shielded*, *qeq/slater*, and *qeq/ctip* describe
different charge models, whereas the matrix inversion method and the different charge models, whereas the matrix inversion method and the
extended Lagrangian method (\ *qeq/dynamic* and *qeq/fire*\ ) are extended Lagrangian method (\ *qeq/dynamic* and *qeq/fire*\ ) are
different solvers. different solvers.
@ -266,6 +301,11 @@ Chemistry, 95, 3358-3363 (1991).
**(Streitz-Mintmire)** F. H. Streitz, J. W. Mintmire, Physical Review B, 50, **(Streitz-Mintmire)** F. H. Streitz, J. W. Mintmire, Physical Review B, 50,
16, 11996 (1994) 16, 11996 (1994)
.. _CTIP1:
**(CTIP)** G. Plummer, J. P. Tavenner, M. I. Mendelev, Z. Wu, J. W. Lawson,
in preparation
.. _vanDuin: .. _vanDuin:
**(ReaxFF)** A. C. T. van Duin, S. Dasgupta, F. Lorant, W. A. Goddard III, J **(ReaxFF)** A. C. T. van Duin, S. Dasgupta, F. Lorant, W. A. Goddard III, J

View File

@ -4,6 +4,7 @@
.. index:: pair_style coul/cut/omp .. index:: pair_style coul/cut/omp
.. index:: pair_style coul/cut/global .. index:: pair_style coul/cut/global
.. index:: pair_style coul/cut/global/omp .. index:: pair_style coul/cut/global/omp
.. index:: pair_style coul/ctip
.. index:: pair_style coul/debye .. index:: pair_style coul/debye
.. index:: pair_style coul/debye/gpu .. index:: pair_style coul/debye/gpu
.. index:: pair_style coul/debye/kk .. index:: pair_style coul/debye/kk
@ -38,6 +39,9 @@ pair_style coul/cut/global command
Accelerator Variants: *coul/cut/omp* Accelerator Variants: *coul/cut/omp*
pair_style coul/ctip command
============================
pair_style coul/debye command pair_style coul/debye command
============================= =============================
@ -79,7 +83,6 @@ pair_style tip4p/long command
Accelerator Variants: *tip4p/long/omp* Accelerator Variants: *tip4p/long/omp*
Syntax Syntax
"""""" """"""
@ -87,6 +90,7 @@ Syntax
pair_style coul/cut cutoff pair_style coul/cut cutoff
pair_style coul/cut/global cutoff pair_style coul/cut/global cutoff
pair_style coul/ctip alpha cutoff
pair_style coul/debye kappa cutoff pair_style coul/debye kappa cutoff
pair_style coul/dsf alpha cutoff pair_style coul/dsf alpha cutoff
pair_style coul/exclude cutoff pair_style coul/exclude cutoff
@ -116,6 +120,9 @@ Examples
pair_coeff * * pair_coeff * *
pair_coeff 2 2 3.5 pair_coeff 2 2 3.5
pair_style coul/ctip 0.30 12.0
pair_coeff * * NiO.ctip Ni O
pair_style coul/debye 1.4 3.0 pair_style coul/debye 1.4 3.0
pair_coeff * * pair_coeff * *
pair_coeff 2 2 3.5 pair_coeff 2 2 3.5
@ -173,6 +180,32 @@ coulomb styles in :doc:`hybrid pair styles <pair_hybrid>`.
---------- ----------
.. versionadded:: TBD
Style *coul/ctip* computes the Coulomb interations as described in
:ref:`Plummer <Plummer1>`. It uses the the damped shifted model as in
style *coul/dsf* but is further extended to the second derivative of
the potential and incorporates empirical charge shielding meant to
approximate the more expensive Coulomb integrals used in style *coul/streitz*.
More details can be found in the referenced paper. Like the style *coul/streitz*,
style *coul/ctip* is a variable charge potential and must be hybridized
with a short-range potential via the :doc:`pair_style hybrid/overlay <pair_hybrid>`
command. Charge equilibration must be performed with the :doc:`fix qeq/ctip
<fix_qeq>` command. For example:
.. code-block:: LAMMPS
pair_style hybrid/overlay eam/fs coul/ctip 0.30 12.0
pair_coeff * * eam/fs NiO.eam.fs Ni O
pair_coeff * * coul/ctip NiO.ctip Ni O
fix 1 all qeq/ctip 1 12.0 1.0e-8 100 coul/ctip cdamp 0.30 maxrepeat 10
See the examples/ctip directory for an example input script using the CTIP
potential. An Ni-O CTIP and EAM/FS parametrization are included for use with
the example.
----------
Style *coul/debye* adds an additional exp() damping factor to the Style *coul/debye* adds an additional exp() damping factor to the
Coulombic term, given by Coulombic term, given by
@ -399,16 +432,18 @@ Restrictions
"""""""""""" """"""""""""
The *coul/long*, *coul/msm*, *coul/streitz*, and *tip4p/long* styles are The *coul/long*, *coul/msm*, *coul/streitz*, and *tip4p/long* styles are
part of the KSPACE package. The *coul/cut/global*, *coul/exclude* styles are part of the KSPACE package. The *coul/cut/global*, *coul/exclude*, and
part of the EXTRA-PAIR package. The *tip4p/cut* style is part of the MOLECULE *coul/ctip* styles are part of the EXTRA-PAIR package. The *tip4p/cut*
package. A pair style is only enabled if LAMMPS was built with its style is part of the MOLECULE package. A pair style is only enabled if
corresponding package. See the :doc:`Build package <Build_package>` LAMMPS was built with its corresponding package. See the
doc page for more info. :doc:`Build package <Build_package>` page for more info.
Related commands Related commands
"""""""""""""""" """"""""""""""""
:doc:`pair_coeff <pair_coeff>`, :doc:`pair_style, hybrid/overlay <pair_hybrid>`, :doc:`kspace_style <kspace_style>` :doc:`pair_coeff <pair_coeff>`,
:doc:`pair_style hybrid/overlay <pair_hybrid>`,
:doc:`kspace_style <kspace_style>`
Default Default
""""""" """""""
@ -432,6 +467,11 @@ Phys, 110, 8254 (1999).
**(Streitz)** F. H. Streitz, J. W. Mintmire, Phys Rev B, 50, 11996-12003 **(Streitz)** F. H. Streitz, J. W. Mintmire, Phys Rev B, 50, 11996-12003
(1994). (1994).
.. _Plummer1:
**(Plummer)** G. Plummer, J. P. Tavenner, M. I. Mendelev, Z. Wu, J. W. Lawson,
in preparation
.. _Jorgensen3: .. _Jorgensen3:
**(Jorgensen)** Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem **(Jorgensen)** Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem

View File

@ -151,6 +151,7 @@ accelerated styles exist.
* :doc:`comb <pair_comb>` - charge-optimized many-body (COMB) potential * :doc:`comb <pair_comb>` - charge-optimized many-body (COMB) potential
* :doc:`comb3 <pair_comb>` - charge-optimized many-body (COMB3) potential * :doc:`comb3 <pair_comb>` - charge-optimized many-body (COMB3) potential
* :doc:`cosine/squared <pair_cosine_squared>` - Cooke-Kremer-Deserno membrane model potential * :doc:`cosine/squared <pair_cosine_squared>` - Cooke-Kremer-Deserno membrane model potential
* :doc:`coul/ctip <pair_coul>` - Charge Transfer Interatomic (Coulomb) Potential
* :doc:`coul/cut <pair_coul>` - cutoff Coulomb potential * :doc:`coul/cut <pair_coul>` - cutoff Coulomb potential
* :doc:`coul/cut/dielectric <pair_dielectric>` - * :doc:`coul/cut/dielectric <pair_dielectric>` -
* :doc:`coul/cut/global <pair_coul>` - cutoff Coulomb potential * :doc:`coul/cut/global <pair_coul>` - cutoff Coulomb potential

1
examples/streitz/NiO.ctip Symbolic link
View File

@ -0,0 +1 @@
../../potentials/NiO.ctip

1
examples/streitz/NiO.eam.fs Symbolic link
View File

@ -0,0 +1 @@
../../potentials/NiO.eam.fs

1745
examples/streitz/data.ctip Normal file

File diff suppressed because it is too large Load Diff

43
examples/streitz/in.ctip Normal file
View File

@ -0,0 +1,43 @@
#CTIP potential for NiO
#Contributing author: Gabriel Plummer (NASA)
#Initialize
units metal
atom_style charge
dimension 3
boundary p p p
#Create Structure
read_data data.ctip
#Define Charges
group type1 type 1
compute charge1 type1 property/atom q
compute q1 type1 reduce ave c_charge1
group type2 type 2
compute charge2 type2 property/atom q
compute q2 type2 reduce ave c_charge2
#Define Potential
pair_style hybrid/overlay eam/fs coul/ctip 0.30 12.0
pair_coeff * * eam/fs NiO.eam.fs Ni O
pair_coeff * * coul/ctip NiO.ctip Ni O
fix qeq all qeq/ctip 1 12.0 1.0e-8 100 coul/ctip cdamp 0.30 maxrepeat 10
#Setup
timestep 0.001
thermo 100
thermo_style custom step temp pe lx ly lz pxx pyy pzz c_q1 c_q2
#Minimization
fix relax all box/relax iso 0
minimize 1e-10 1e-10 100000 100000
unfix relax
#Dynamics
reset_timestep 0
variable T equal 1000
variable rnd equal round(random(0,999,${T}))
velocity all create ${T} ${rnd} mom yes rot yes
fix npt all npt temp ${T} ${T} 0.1 iso 0 0 1
run 1000

View File

@ -0,0 +1,186 @@
LAMMPS (29 Aug 2024 - Development - patch_29Aug2024-269-g5a12c762f3-modified)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98)
using 1 OpenMP thread(s) per MPI task
#CTIP potential for NiO
#Contributing author: Gabriel Plummer (NASA)
#Initialize
units metal
atom_style charge
dimension 3
boundary p p p
#Create Structure
read_data data.ctip
Reading data file ...
orthogonal box = (0 0 0) to (24.719478 24.719478 24.719478)
1 by 1 by 1 MPI processor grid
reading atoms ...
1728 atoms
read_data CPU = 0.004 seconds
#Define Charges
group type1 type 1
864 atoms in group type1
compute charge1 type1 property/atom q
compute q1 type1 reduce ave c_charge1
group type2 type 2
864 atoms in group type2
compute charge2 type2 property/atom q
compute q2 type2 reduce ave c_charge2
#Define Potential
pair_style hybrid/overlay eam/fs coul/ctip 0.30 12.0
pair_coeff * * eam/fs NiO.eam.fs Ni O
Reading eam/fs potential file NiO.eam.fs with DATE: 2024-04-29
pair_coeff * * coul/ctip NiO.ctip Ni O
Reading coul/ctip potential file NiO.ctip with DATE: 2024-09-11
fix qeq all qeq/ctip 1 12.0 1.0e-8 100 coul/ctip cdamp 0.30 maxrepeat 10
#Setup
timestep 0.001
thermo 100
thermo_style custom step temp pe lx ly lz pxx pyy pzz c_q1 c_q2
#Minimization
fix relax all box/relax iso 0
minimize 1e-10 1e-10 100000 100000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419
@Article{Gissinger24,
author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor},
title = {Type Label Framework for Bonded Force Fields in LAMMPS},
journal = {J. Phys. Chem. B},
year = 2024,
volume = 128,
number = 13,
pages = {3282-3297}
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 14
ghost atom cutoff = 14
binsize = 7, bins = 4 4 4
3 neighbor lists, perpetual/occasional/extra = 3 0 0
(1) pair eam/fs, perpetual, trim from (2)
attributes: half, newton on, cut 8
pair build: trim
stencil: none
bin: none
(2) pair coul/ctip, perpetual, half/full from (3)
attributes: half, newton on
pair build: halffull/newton
stencil: none
bin: none
(3) fix qeq/ctip, perpetual
attributes: full, newton on
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
WARNING: Energy due to 1 extra global DOFs will be included in minimizer energies
(src/min.cpp:219)
Per MPI rank memory allocation (min/avg/max) = 55.22 | 55.22 | 55.22 Mbytes
Step Temp PotEng Lx Ly Lz Pxx Pyy Pzz c_q1 c_q2
0 0 -9633.183 24.719478 24.719478 24.719478 -1491.273 -1491.273 -1491.273 1.2374666 -1.2374666
6 0 -9633.1929 24.707505 24.707505 24.707505 0.0050470506 0.0050470504 0.0050470502 1.2410908 -1.2410908
Loop time of 1.04745 on 1 procs for 6 steps with 1728 atoms
99.8% CPU use with 1 MPI tasks x 1 OpenMP threads
Minimization stats:
Stopping criterion = energy tolerance
Energy initial, next-to-last, final =
-9633.18301850704 -9633.19294329023 -9633.19294333485
Force two-norm initial, final = 42.177998 0.00014264694
Force max component initial, final = 42.177998 0.00014260857
Final line search alpha, max atom move = 0.0079490417 1.1336014e-06
Iterations, force evaluations = 6 8
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.3534 | 0.3534 | 0.3534 | 0.0 | 33.74
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.0004205 | 0.0004205 | 0.0004205 | 0.0 | 0.04
Output | 0 | 0 | 0 | 0.0 | 0.00
Modify | 0.69216 | 0.69216 | 0.69216 | 0.0 | 66.08
Other | | 0.001461 | | | 0.14
Nlocal: 1728 ave 1728 max 1728 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 13897 ave 13897 max 13897 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 216000 ave 216000 max 216000 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 2.34317e+06 ave 2.34317e+06 max 2.34317e+06 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 2343168
Ave neighs/atom = 1356
Neighbor list builds = 0
Dangerous builds = 0
unfix relax
#Dynamics
reset_timestep 0
variable T equal 1000
variable rnd equal round(random(0,999,${T}))
variable rnd equal round(random(0,999,1000))
velocity all create ${T} ${rnd} mom yes rot yes
velocity all create 1000 ${rnd} mom yes rot yes
velocity all create 1000 233 mom yes rot yes
fix npt all npt temp ${T} ${T} 0.1 iso 0 0 1
fix npt all npt temp 1000 ${T} 0.1 iso 0 0 1
fix npt all npt temp 1000 1000 0.1 iso 0 0 1
run 1000
Per MPI rank memory allocation (min/avg/max) = 54.35 | 54.35 | 54.35 Mbytes
Step Temp PotEng Lx Ly Lz Pxx Pyy Pzz c_q1 c_q2
0 1000 -9633.1929 24.707505 24.707505 24.707505 15934.991 15754.787 15735.602 1.2410908 -1.2410908
100 600.77874 -9528.0602 24.816519 24.816519 24.816519 -16709.313 -15443.072 -17750.832 1.2181988 -1.2181988
200 578.84295 -9490.9794 24.812627 24.812627 24.812627 -5879.8769 -4851.4601 -6722.107 1.2254363 -1.2254363
300 694.7973 -9478.5512 24.764285 24.764285 24.764285 14639.415 13827.989 13766.766 1.2372201 -1.2372201
400 803.93731 -9462.2542 24.866629 24.866629 24.866629 -4644.2854 -6017.2884 -7744.2567 1.2086229 -1.2086229
500 893.70492 -9441.0072 24.891756 24.891756 24.891756 -5784.2232 -8219.1644 -4187.392 1.2001224 -1.2001224
600 947.21728 -9416.7532 24.863623 24.863623 24.863623 11265.076 12952.469 11331.883 1.2115124 -1.2115124
700 1040.4874 -9409.8397 24.933859 24.933859 24.933859 -6570.5927 -8532.7457 -3284.7317 1.1902794 -1.1902794
800 1037.9366 -9398.4828 24.935138 24.935138 24.935138 -4681.8676 -2576.4998 -7160.562 1.1880324 -1.1880324
900 1049.4211 -9411.115 24.899733 24.899733 24.899733 3250.2695 8121.9271 5945.0542 1.2024086 -1.2024086
1000 964.18789 -9412.4405 24.926442 24.926442 24.926442 -7652.603 -5142.9259 -8351.8835 1.1908935 -1.1908935
Loop time of 183.932 on 1 procs for 1000 steps with 1728 atoms
Performance: 0.470 ns/day, 51.092 hours/ns, 5.437 timesteps/s, 9.395 katom-step/s
99.7% CPU use with 1 MPI tasks x 1 OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 37.347 | 37.347 | 37.347 | 0.0 | 20.30
Neigh | 0.22667 | 0.22667 | 0.22667 | 0.0 | 0.12
Comm | 0.052514 | 0.052514 | 0.052514 | 0.0 | 0.03
Output | 0.00053967 | 0.00053967 | 0.00053967 | 0.0 | 0.00
Modify | 146.29 | 146.29 | 146.29 | 0.0 | 79.53
Other | | 0.01552 | | | 0.01
Nlocal: 1728 ave 1728 max 1728 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 13901 ave 13901 max 13901 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 210388 ave 210388 max 210388 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 2.23448e+06 ave 2.23448e+06 max 2.23448e+06 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 2234476
Ave neighs/atom = 1293.0995
Neighbor list builds = 5
Dangerous builds = 0
Total wall time: 0:03:05

View File

@ -0,0 +1,186 @@
LAMMPS (29 Aug 2024 - Development - patch_29Aug2024-269-g5a12c762f3-modified)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98)
using 1 OpenMP thread(s) per MPI task
#CTIP potential for NiO
#Contributing author: Gabriel Plummer (NASA)
#Initialize
units metal
atom_style charge
dimension 3
boundary p p p
#Create Structure
read_data data.ctip
Reading data file ...
orthogonal box = (0 0 0) to (24.719478 24.719478 24.719478)
1 by 2 by 2 MPI processor grid
reading atoms ...
1728 atoms
read_data CPU = 0.007 seconds
#Define Charges
group type1 type 1
864 atoms in group type1
compute charge1 type1 property/atom q
compute q1 type1 reduce ave c_charge1
group type2 type 2
864 atoms in group type2
compute charge2 type2 property/atom q
compute q2 type2 reduce ave c_charge2
#Define Potential
pair_style hybrid/overlay eam/fs coul/ctip 0.30 12.0
pair_coeff * * eam/fs NiO.eam.fs Ni O
Reading eam/fs potential file NiO.eam.fs with DATE: 2024-04-29
pair_coeff * * coul/ctip NiO.ctip Ni O
Reading coul/ctip potential file NiO.ctip with DATE: 2024-09-11
fix qeq all qeq/ctip 1 12.0 1.0e-8 100 coul/ctip cdamp 0.30 maxrepeat 10
#Setup
timestep 0.001
thermo 100
thermo_style custom step temp pe lx ly lz pxx pyy pzz c_q1 c_q2
#Minimization
fix relax all box/relax iso 0
minimize 1e-10 1e-10 100000 100000
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Your simulation uses code contributions which should be cited:
- Type Label Framework: https://doi.org/10.1021/acs.jpcb.3c08419
@Article{Gissinger24,
author = {Jacob R. Gissinger, Ilia Nikiforov, Yaser Afshar, Brendon Waters, Moon-ki Choi, Daniel S. Karls, Alexander Stukowski, Wonpil Im, Hendrik Heinz, Axel Kohlmeyer, and Ellad B. Tadmor},
title = {Type Label Framework for Bonded Force Fields in LAMMPS},
journal = {J. Phys. Chem. B},
year = 2024,
volume = 128,
number = 13,
pages = {3282-3297}
}
CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE
Neighbor list info ...
update: every = 1 steps, delay = 0 steps, check = yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 14
ghost atom cutoff = 14
binsize = 7, bins = 4 4 4
3 neighbor lists, perpetual/occasional/extra = 3 0 0
(1) pair eam/fs, perpetual, trim from (2)
attributes: half, newton on, cut 8
pair build: trim
stencil: none
bin: none
(2) pair coul/ctip, perpetual, half/full from (3)
attributes: half, newton on
pair build: halffull/newton
stencil: none
bin: none
(3) fix qeq/ctip, perpetual
attributes: full, newton on
pair build: full/bin/atomonly
stencil: full/bin/3d
bin: standard
WARNING: Energy due to 1 extra global DOFs will be included in minimizer energies
(src/min.cpp:219)
Per MPI rank memory allocation (min/avg/max) = 19.71 | 19.71 | 19.71 Mbytes
Step Temp PotEng Lx Ly Lz Pxx Pyy Pzz c_q1 c_q2
0 0 -9633.183 24.719478 24.719478 24.719478 -1491.273 -1491.273 -1491.273 1.2374666 -1.2374666
6 0 -9633.1929 24.707505 24.707505 24.707505 0.0050498849 0.0050498856 0.0050498855 1.2410908 -1.2410908
Loop time of 0.288818 on 4 procs for 6 steps with 1728 atoms
99.6% CPU use with 4 MPI tasks x 1 OpenMP threads
Minimization stats:
Stopping criterion = energy tolerance
Energy initial, next-to-last, final =
-9633.18301849946 -9633.19294329957 -9633.19294333066
Force two-norm initial, final = 42.177998 0.00014286398
Force max component initial, final = 42.177998 0.00014268867
Final line search alpha, max atom move = 0.0079490643 1.1342414e-06
Iterations, force evaluations = 6 8
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.09401 | 0.095886 | 0.097631 | 0.4 | 33.20
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.0024298 | 0.004185 | 0.0060676 | 2.1 | 1.45
Output | 0 | 0 | 0 | 0.0 | 0.00
Modify | 0.18779 | 0.1878 | 0.18781 | 0.0 | 65.02
Other | | 0.000945 | | | 0.33
Nlocal: 432 ave 432 max 432 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Nghost: 8593 ave 8593 max 8593 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Neighs: 54000 ave 54000 max 54000 min
Histogram: 4 0 0 0 0 0 0 0 0 0
FullNghs: 585792 ave 585792 max 585792 min
Histogram: 4 0 0 0 0 0 0 0 0 0
Total # of neighbors = 2343168
Ave neighs/atom = 1356
Neighbor list builds = 0
Dangerous builds = 0
unfix relax
#Dynamics
reset_timestep 0
variable T equal 1000
variable rnd equal round(random(0,999,${T}))
variable rnd equal round(random(0,999,1000))
velocity all create ${T} ${rnd} mom yes rot yes
velocity all create 1000 ${rnd} mom yes rot yes
velocity all create 1000 233 mom yes rot yes
fix npt all npt temp ${T} ${T} 0.1 iso 0 0 1
fix npt all npt temp 1000 ${T} 0.1 iso 0 0 1
fix npt all npt temp 1000 1000 0.1 iso 0 0 1
run 1000
Per MPI rank memory allocation (min/avg/max) = 18.83 | 18.83 | 18.83 Mbytes
Step Temp PotEng Lx Ly Lz Pxx Pyy Pzz c_q1 c_q2
0 1000 -9633.1929 24.707505 24.707505 24.707505 15934.991 15754.787 15735.602 1.2410908 -1.2410908
100 600.77874 -9528.0602 24.816519 24.816519 24.816519 -16709.313 -15443.072 -17750.832 1.2181988 -1.2181988
200 578.84295 -9490.9794 24.812627 24.812627 24.812627 -5879.8769 -4851.4601 -6722.107 1.2254363 -1.2254363
300 694.7973 -9478.5512 24.764285 24.764285 24.764285 14639.415 13827.989 13766.766 1.2372201 -1.2372201
400 803.93731 -9462.2542 24.866629 24.866629 24.866629 -4644.2853 -6017.2884 -7744.2567 1.2086229 -1.2086229
500 893.70492 -9441.0072 24.891756 24.891756 24.891756 -5784.2232 -8219.1644 -4187.392 1.2001224 -1.2001224
600 947.21728 -9416.7532 24.863623 24.863623 24.863623 11265.076 12952.469 11331.883 1.2115124 -1.2115124
700 1040.4874 -9409.8397 24.933859 24.933859 24.933859 -6570.5926 -8532.7456 -3284.7317 1.1902794 -1.1902794
800 1037.9366 -9398.4828 24.935138 24.935138 24.935138 -4681.8675 -2576.5001 -7160.5622 1.1880324 -1.1880324
900 1049.4211 -9411.115 24.899733 24.899733 24.899733 3250.2695 8121.9274 5945.0541 1.2024086 -1.2024086
1000 964.18789 -9412.4405 24.926442 24.926442 24.926442 -7652.603 -5142.926 -8351.8839 1.1908935 -1.1908935
Loop time of 63.5378 on 4 procs for 1000 steps with 1728 atoms
Performance: 1.360 ns/day, 17.649 hours/ns, 15.739 timesteps/s, 27.196 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 | 12.737 | 12.782 | 12.839 | 1.1 | 20.12
Neigh | 0.082989 | 0.083627 | 0.084898 | 0.3 | 0.13
Comm | 0.39773 | 0.45431 | 0.49896 | 5.5 | 0.72
Output | 0.00038299 | 0.0004067 | 0.00047658 | 0.0 | 0.00
Modify | 50.207 | 50.207 | 50.208 | 0.0 | 79.02
Other | | 0.01047 | | | 0.02
Nlocal: 432 ave 446 max 421 min
Histogram: 1 0 1 0 1 0 0 0 0 1
Nghost: 8594.5 ave 8608 max 8579 min
Histogram: 1 0 0 0 0 1 1 0 0 1
Neighs: 52597 ave 54466 max 51209 min
Histogram: 1 0 1 0 1 0 0 0 0 1
FullNghs: 558619 ave 576961 max 544134 min
Histogram: 1 0 1 0 1 0 0 0 0 1
Total # of neighbors = 2234476
Ave neighs/atom = 1293.0995
Neighbor list builds = 5
Dangerous builds = 0
Total wall time: 0:01:04

4
potentials/NiO.ctip Normal file
View File

@ -0,0 +1,4 @@
# CTIP potential parameters for Ni-O UNITS: metal DATE: 2024-09-11 CONTRIBUTOR: Gabriel Plummer gabriel.w.plummer@nasa.gov
# X (eV) J (eV) gamma (1/ang) zeta (1/ang) Z (e) qmin qmax omega
Ni -5.840000 14.157390 0.549290 0.000000 0.000000 0.000000 2.000000 100.000
O 0.000000 15.655862 1.428571 0.000000 0.000000 -2.000000 0.000000 100.000

18007
potentials/NiO.eam.fs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,7 @@ cdeam concentration-dependent EAM
cgdna potential files for styles in the CG-DNA package cgdna potential files for styles in the CG-DNA package
comb COMB potential comb COMB potential
comb3 COMB3 potential comb3 COMB3 potential
ctip Coulombic portion of CTIP potential
eam embedded atom method (EAM) single element, DYNAMO funcfl format eam embedded atom method (EAM) single element, DYNAMO funcfl format
eam.alloy EAM multi-element alloy, DYNAMO setfl format eam.alloy EAM multi-element alloy, DYNAMO setfl format
eam.fs Finnis-Sinclair EAM format (single element or alloy) eam.fs Finnis-Sinclair EAM format (single element or alloy)

4
src/.gitignore vendored
View File

@ -439,6 +439,8 @@
/pair_coul_cut_global.h /pair_coul_cut_global.h
/pair_coul_streitz.cpp /pair_coul_streitz.cpp
/pair_coul_streitz.h /pair_coul_streitz.h
/pair_coul_ctip.cpp
/pair_coul_ctip.h
/pair_gauss.cpp /pair_gauss.cpp
/pair_gauss.h /pair_gauss.h
/pair_lj96_cut.cpp /pair_lj96_cut.cpp
@ -978,6 +980,8 @@
/fix_pour.h /fix_pour.h
/fix_qeq_comb.cpp /fix_qeq_comb.cpp
/fix_qeq_comb.h /fix_qeq_comb.h
/fix_qeq_ctip.cpp
/fix_qeq_ctip.h
/fix_qeq_fire.cpp /fix_qeq_fire.cpp
/fix_qeq_fire.h /fix_qeq_fire.h
/fix_qeq_reaxff.cpp /fix_qeq_reaxff.cpp

View File

@ -0,0 +1,580 @@
/* ----------------------------------------------------------------------
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 Plummer (NASA)
------------------------------------------------------------------------- */
#include "pair_coul_ctip.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "ewald_const.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "neigh_list.h"
#include "neighbor.h"
#include "potential_file_reader.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace MathConst;
using namespace EwaldConst;
static constexpr int DELTA = 4;
/* ---------------------------------------------------------------------- */
PairCoulCTIP::PairCoulCTIP(LAMMPS *lmp) :
Pair(lmp), params(nullptr), shield(nullptr), shieldcu(nullptr), reffc(nullptr),
reffcsq(nullptr), reffc4(nullptr), reffc7(nullptr), s2d_shift(nullptr), f_shift(nullptr),
e_shift(nullptr), self_factor(nullptr), qeq_x(nullptr), qeq_j(nullptr), qeq_g(nullptr),
qeq_z(nullptr), qeq_c(nullptr), qeq_q1(nullptr), qeq_q2(nullptr), qeq_w(nullptr)
{
single_enable = 0;
}
/* ---------------------------------------------------------------------- */
PairCoulCTIP::~PairCoulCTIP()
{
if (copymode) return;
memory->sfree(params);
memory->destroy(elem1param);
memory->destroy(shield);
memory->destroy(shieldcu);
memory->destroy(reffc);
memory->destroy(reffcsq);
memory->destroy(reffc4);
memory->destroy(reffc7);
memory->destroy(s2d_shift);
memory->destroy(f_shift);
memory->destroy(e_shift);
memory->destroy(self_factor);
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(qeq_x);
memory->destroy(qeq_j);
memory->destroy(qeq_g);
memory->destroy(qeq_z);
memory->destroy(qeq_c);
memory->destroy(qeq_q1);
memory->destroy(qeq_q2);
memory->destroy(qeq_w);
}
}
/* ---------------------------------------------------------------------- */
void PairCoulCTIP::compute(int eflag, int vflag)
{
int i, j, ii, jj, inum, jnum, itype, jtype;
int iparam_i, jparam_j;
double qtmp, xtmp, ytmp, ztmp, delx, dely, delz, ecoul, fpair;
double r, rsq, reff, reffsq, reff4, forcecoul, factor_coul;
double prefactor, erfcc, erfcd, t;
double selfion;
int *ilist, *jlist, *numneigh, **firstneigh;
ecoul = 0.0;
selfion = 0.0;
ev_init(eflag, vflag);
double **x = atom->x;
double **f = atom->f;
double *q = atom->q;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
int newton_pair = force->newton_pair;
double qqrd2e = force->qqrd2e;
double erfcd_cut, t_cut, erfcc_cut;
erfcd_cut = exp(-alpha * alpha * cut_coulsq);
t_cut = 1.0 / (1.0 + EWALD_P * alpha * cut_coul);
erfcc_cut = t_cut * (A1 + t_cut * (A2 + t_cut * (A3 + t_cut * (A4 + t_cut * A5)))) * erfcd_cut;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = map[type[i]];
jlist = firstneigh[i];
jnum = numneigh[i];
iparam_i = elem1param[itype];
selfion = self(&params[iparam_i], qtmp);
if (evflag) ev_tally(i, i, nlocal, 0, 0.0, selfion, 0.0, 0.0, 0.0, 0.0);
if (eflag) {
double e_self = self_factor[iparam_i][iparam_i] * qtmp * qtmp;
ev_tally(i, i, nlocal, 0, 0.0, e_self, 0.0, 0.0, 0.0, 0.0);
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx * delx + dely * dely + delz * delz;
if (rsq < cut_coulsq) {
jtype = map[type[j]];
jparam_j = elem1param[jtype];
r = sqrt(rsq);
reff = cbrt(rsq * r + 1 / shieldcu[iparam_i][jparam_j]);
reffsq = reff * reff;
reff4 = reffsq * reffsq;
prefactor = qqrd2e * qtmp * q[j] / r;
erfcd = exp(-alpha * alpha * rsq);
t = 1.0 / (1.0 + EWALD_P * alpha * r);
erfcc = t * (A1 + t * (A2 + t * (A3 + t * (A4 + t * A5)))) * erfcd;
forcecoul = prefactor *
(erfcc / r + 2.0 * alpha / MY_PIS * erfcd + rsq * r / reff4 - 1 / r -
r * f_shift[iparam_i][jparam_j] + r * s2d_shift[iparam_i][jparam_j] * (r - cut_coul)) *
r;
if (factor_coul < 1.0) forcecoul -= (1.0 - factor_coul) * prefactor;
fpair = forcecoul / rsq;
f[i][0] += delx * fpair;
f[i][1] += dely * fpair;
f[i][2] += delz * fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx * fpair;
f[j][1] -= dely * fpair;
f[j][2] -= delz * fpair;
}
if (eflag) {
ecoul = prefactor *
(erfcc + r / reff - 1 - r * erfcc_cut / cut_coul - r / reffc[iparam_i][jparam_j] +
r / cut_coul + r * f_shift[iparam_i][jparam_j] * (r - cut_coul) -
r * s2d_shift[iparam_i][jparam_j] * (r - cut_coul) * (r - cut_coul) * 0.5);
if (factor_coul < 1.0) ecoul -= (1.0 - factor_coul) * prefactor;
} else
ecoul = 0.0;
if (evflag) ev_tally(i, j, nlocal, newton_pair, 0.0, ecoul, fpair, delx, dely, delz);
}
}
}
if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
double PairCoulCTIP::self(Param *param, double qi)
{
double s1 = param->chi, s2 = param->eta, s3 = param->qmin, s4 = param->qmax, s5 = param->omega;
if (qi < s3) {
return qi * ((s1 - 2 * s3 * s5) + qi * (0.50 * s2 + s5)) + s3 * s3 * s5;
} else if (qi < s4) {
return qi * (s1 + qi * (0.50 * s2));
} else {
return qi * ((s1 - 2 * s4 * s5) + qi * (0.50 * s2 + s5)) + s4 * s4 * s5;
}
return 0.0;
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairCoulCTIP::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag, n + 1, n + 1, "pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) setflag[i][j] = 0;
memory->create(cutsq, n + 1, n + 1, "pair:cutsq");
memory->create(qeq_x, n + 1, "pair:qeq_x");
memory->create(qeq_j, n + 1, "pair:qeq_j");
memory->create(qeq_g, n + 1, "pair:qeq_g");
memory->create(qeq_z, n + 1, "pair:qeq_z");
memory->create(qeq_c, n + 1, "pair:qeq_c");
memory->create(qeq_q1, n + 1, "pair:qeq_q1");
memory->create(qeq_q2, n + 1, "pair:qeq_q2");
memory->create(qeq_w, n + 1, "pair:qeq_w");
map = new int[n + 1];
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairCoulCTIP::settings(int narg, char **arg)
{
if (narg != 2) error->all(FLERR, "Illegal pair_style command");
alpha = utils::numeric(FLERR, arg[0], false, lmp);
cut_coul = utils::numeric(FLERR, arg[1], false, lmp);
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairCoulCTIP::coeff(int narg, char **arg)
{
if (!allocated) allocate();
map_element2type(narg - 3, arg + 3);
// read potential file and initialize potential parameters
read_file(arg[2]);
setup_params();
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairCoulCTIP::init_style()
{
if (!atom->q_flag) error->all(FLERR, "Pair style coul/ctip requires atom attribute q");
neighbor->add_request(this);
cut_coulsq = cut_coul * cut_coul;
memory->destroy(shield);
memory->destroy(shieldcu);
memory->destroy(reffc);
memory->destroy(reffcsq);
memory->destroy(reffc4);
memory->destroy(reffc7);
memory->destroy(s2d_shift);
memory->destroy(f_shift);
memory->destroy(e_shift);
memory->destroy(self_factor);
memory->create(shield, nelements, nelements, "pair:shield");
memory->create(shieldcu, nelements, nelements, "pair:shieldcu");
memory->create(reffc, nelements, nelements, "pair:reffc");
memory->create(reffcsq, nelements, nelements, "pair:reffcsq");
memory->create(reffc4, nelements, nelements, "pair:reffc4");
memory->create(reffc7, nelements, nelements, "pair:reffc7");
memory->create(s2d_shift, nelements, nelements, "pair:s2d_shift");
memory->create(f_shift, nelements, nelements, "pair:f_shift");
memory->create(e_shift, nelements, nelements, "pair:e_shift");
memory->create(self_factor, nelements, nelements, "pair:self_factor");
double qqrd2e = force->qqrd2e;
double cut_coulcu, cut_coul4, alphacu, erfcd_cut, t_cut, erfcc_cut;
cut_coulcu = cut_coulsq * cut_coul;
cut_coul4 = cut_coulsq * cut_coulsq;
alphacu = alpha * alpha * alpha;
erfcd_cut = exp(-alpha * alpha * cut_coulsq);
t_cut = 1.0 / (1.0 + EWALD_P * alpha * cut_coul);
erfcc_cut = t_cut * (A1 + t_cut * (A2 + t_cut * (A3 + t_cut * (A4 + t_cut * A5)))) * erfcd_cut;
for (int elt1 = 0; elt1 < nelements; elt1++) {
for (int elt2 = 0; elt2 < nelements; elt2++) {
shield[elt1][elt2] = sqrt(params[elt1].gamma * params[elt2].gamma);
shieldcu[elt1][elt2] = shield[elt1][elt2] * shield[elt1][elt2] * shield[elt1][elt2];
reffc[elt1][elt2] = std::cbrt(cut_coulcu + 1.0 / shieldcu[elt1][elt2]);
reffcsq[elt1][elt2] = reffc[elt1][elt2] * reffc[elt1][elt2];
reffc4[elt1][elt2] = reffcsq[elt1][elt2] * reffcsq[elt1][elt2];
reffc7[elt1][elt2] = reffc4[elt1][elt2] * reffcsq[elt1][elt2] * reffc[elt1][elt2];
s2d_shift[elt1][elt2] = 2.0 * erfcc_cut / cut_coulcu +
4.0 * alpha / MY_PIS * erfcd_cut / cut_coulsq + 4.0 * alphacu / MY_PIS * erfcd_cut -
2.0 / cut_coulcu + 4.0 * cut_coul4 / reffc7[elt1][elt2] -
2.0 * cut_coul / reffc4[elt1][elt2];
f_shift[elt1][elt2] = erfcc_cut / cut_coulsq + 2.0 * alpha / MY_PIS * erfcd_cut / cut_coul -
1.0 / cut_coulsq + cut_coulsq / reffc4[elt1][elt2];
e_shift[elt1][elt2] = 2.0 * erfcc_cut / cut_coul + 2.0 * alpha / MY_PIS * erfcd_cut -
2.0 / cut_coul + 1.0 / reffc[elt1][elt2] + cut_coulcu / reffc4[elt1][elt2] +
s2d_shift[elt1][elt2] * cut_coulsq * 0.5;
self_factor[elt1][elt2] = -(e_shift[elt1][elt2] * 0.5 + alpha / MY_PIS) * qqrd2e;
}
}
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairCoulCTIP::init_one(int /*i*/, int /*j*/)
{
return cut_coul;
}
/* ---------------------------------------------------------------------- */
void PairCoulCTIP::read_file(char *file)
{
memory->sfree(params);
params = nullptr;
nparams = 0;
maxparam = 0;
// open file on proc 0
if (comm->me == 0) {
PotentialFileReader reader(lmp, file, "coul/ctip");
char *line;
while ((line = reader.next_line(NPARAMS_PER_LINE))) {
try {
ValueTokenizer values(line);
std::string iname = values.next_string();
// ielement = 1st args
int ielement;
for (ielement = 0; ielement < nelements; ielement++)
if (iname == elements[ielement]) break;
// load up parameter settings and error check their values
if (nparams == maxparam) {
maxparam += DELTA;
params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params");
// make certain all addional allocated storage is initialized
// to avoid false positives when checking with valgrind
memset(params + nparams, 0, DELTA * sizeof(Param));
}
params[nparams].ielement = ielement;
params[nparams].chi = values.next_double();
params[nparams].eta = values.next_double();
params[nparams].gamma = values.next_double();
params[nparams].zeta = values.next_double();
params[nparams].zcore = values.next_double();
params[nparams].qmin = values.next_double();
params[nparams].qmax = values.next_double();
params[nparams].omega = values.next_double();
} catch (TokenizerException &e) {
error->one(FLERR, e.what());
}
// parameter sanity check
if (params[nparams].eta < 0.0 || params[nparams].zeta < 0.0 || params[nparams].zcore < 0.0 ||
params[nparams].gamma < 0.0 || params[nparams].qmin > params[nparams].qmax ||
params[nparams].omega < 0.0)
error->one(FLERR, "Illegal coul/ctip parameter");
nparams++;
}
}
MPI_Bcast(&nparams, 1, MPI_INT, 0, world);
MPI_Bcast(&maxparam, 1, MPI_INT, 0, world);
if (comm->me != 0) {
params = (Param *) memory->srealloc(params, maxparam * sizeof(Param), "pair:params");
}
MPI_Bcast(params, maxparam * sizeof(Param), MPI_BYTE, 0, world);
}
/* ---------------------------------------------------------------------- */
void PairCoulCTIP::setup_params()
{
int i, m, n;
// set elem1param
memory->destroy(elem1param);
memory->create(elem1param, nelements, "pair:elem1param");
for (i = 0; i < nelements; i++) {
n = -1;
for (m = 0; m < nparams; m++) {
if (i == params[m].ielement) {
if (n >= 0) error->all(FLERR, "Potential file has duplicate entry");
n = m;
}
}
if (n < 0) error->all(FLERR, "Potential file is missing an entry");
elem1param[i] = n;
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairCoulCTIP::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i, j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) { fwrite(&setflag[i][j], sizeof(int), 1, fp); }
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairCoulCTIP::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i, j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) utils::sfread(FLERR, &setflag[i][j], sizeof(int), 1, fp, nullptr, error);
MPI_Bcast(&setflag[i][j], 1, MPI_INT, 0, world);
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairCoulCTIP::write_restart_settings(FILE *fp)
{
fwrite(&alpha, sizeof(double), 1, fp);
fwrite(&cut_coul, sizeof(double), 1, fp);
fwrite(&offset_flag, sizeof(int), 1, fp);
fwrite(&mix_flag, sizeof(int), 1, fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairCoulCTIP::read_restart_settings(FILE *fp)
{
if (comm->me == 0) {
utils::sfread(FLERR, &alpha, sizeof(double), 1, fp, nullptr, error);
utils::sfread(FLERR, &cut_coul, sizeof(double), 1, fp, nullptr, error);
utils::sfread(FLERR, &offset_flag, sizeof(int), 1, fp, nullptr, error);
utils::sfread(FLERR, &mix_flag, sizeof(int), 1, fp, nullptr, error);
}
MPI_Bcast(&alpha, 1, MPI_DOUBLE, 0, world);
MPI_Bcast(&cut_coul, 1, MPI_DOUBLE, 0, world);
MPI_Bcast(&offset_flag, 1, MPI_INT, 0, world);
MPI_Bcast(&mix_flag, 1, MPI_INT, 0, world);
}
/* ---------------------------------------------------------------------- */
void *PairCoulCTIP::extract(const char *str, int &dim)
{
if (strcmp(str, "cut_coul") == 0) {
dim = 0;
return (void *) &cut_coul;
}
if (strcmp(str, "chi") == 0 && qeq_x) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_x[i] = params[map[i]].chi;
else
qeq_x[i] = 0.0;
return (void *) qeq_x;
}
if (strcmp(str, "eta") == 0 && qeq_j) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_j[i] = params[map[i]].eta;
else
qeq_j[i] = 0.0;
return (void *) qeq_j;
}
if (strcmp(str, "gamma") == 0 && qeq_g) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_g[i] = params[map[i]].gamma;
else
qeq_g[i] = 0.0;
return (void *) qeq_g;
}
if (strcmp(str, "zeta") == 0 && qeq_z) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_z[i] = params[map[i]].zeta;
else
qeq_z[i] = 0.0;
return (void *) qeq_z;
}
if (strcmp(str, "zcore") == 0 && qeq_c) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_c[i] = params[map[i]].zcore;
else
qeq_c[i] = 0.0;
return (void *) qeq_c;
}
if (strcmp(str, "qmin") == 0 && qeq_q1) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_q1[i] = params[map[i]].qmin;
else
qeq_q1[i] = 0.0;
return (void *) qeq_q1;
}
if (strcmp(str, "qmax") == 0 && qeq_q2) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_q2[i] = params[map[i]].qmax;
else
qeq_q2[i] = 0.0;
return (void *) qeq_q2;
}
if (strcmp(str, "omega") == 0 && qeq_w) {
dim = 1;
for (int i = 1; i <= atom->ntypes; i++)
if (map[i] >= 0)
qeq_w[i] = params[map[i]].omega;
else
qeq_w[i] = 0.0;
return (void *) qeq_w;
}
return nullptr;
}

View File

@ -0,0 +1,70 @@
/* -*- 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(coul/ctip,PairCoulCTIP);
// clang-format on
#else
#ifndef LMP_PAIR_COUL_CTIP_H
#define LMP_PAIR_COUL_CTIP_H
#include "pair.h"
namespace LAMMPS_NS {
class PairCoulCTIP : public Pair {
public:
PairCoulCTIP(class LAMMPS *);
~PairCoulCTIP() 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;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_restart_settings(FILE *) override;
void read_restart_settings(FILE *) override;
void *extract(const char *, int &) override;
static constexpr int NPARAMS_PER_LINE = 9;
protected:
double cut_coul, cut_coulsq;
double alpha;
struct Param {
double chi, eta, gamma, zeta, zcore, qmin, qmax, omega;
int ielement;
};
Param *params;
double **shield, **shieldcu, **reffc, **reffcsq, **reffc4, **reffc7;
double **s2d_shift, **f_shift, **e_shift, **self_factor;
double *qeq_x, *qeq_j, *qeq_g, *qeq_z, *qeq_c, *qeq_q1, *qeq_q2, *qeq_w;
void allocate();
void read_file(char *);
void setup_params();
double self(Param *, double);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -44,3 +44,5 @@ action fix_qeq_shielded.cpp
action fix_qeq_shielded.h action fix_qeq_shielded.h
action fix_qeq_slater.cpp action fix_qeq_slater.cpp
action fix_qeq_slater.h action fix_qeq_slater.h
action fix_qeq_ctip.cpp
action fix_qeq_ctip.h

View File

@ -27,7 +27,9 @@
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "neigh_list.h" #include "neigh_list.h"
#include "pair.h"
#include "respa.h" #include "respa.h"
#include "suffix.h"
#include "text_file_reader.h" #include "text_file_reader.h"
#include "update.h" #include "update.h"
@ -53,7 +55,7 @@ namespace {
FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) : FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), list(nullptr), chi(nullptr), eta(nullptr), Fix(lmp, narg, arg), list(nullptr), chi(nullptr), eta(nullptr),
gamma(nullptr), zeta(nullptr), zcore(nullptr), chizj(nullptr), shld(nullptr), gamma(nullptr), zeta(nullptr), zcore(nullptr), qmin(nullptr), qmax(nullptr), omega(nullptr), chizj(nullptr), shld(nullptr),
s(nullptr), t(nullptr), s_hist(nullptr), t_hist(nullptr), Hdia_inv(nullptr), b_s(nullptr), s(nullptr), t(nullptr), s_hist(nullptr), t_hist(nullptr), Hdia_inv(nullptr), b_s(nullptr),
b_t(nullptr), p(nullptr), q(nullptr), r(nullptr), d(nullptr), b_t(nullptr), p(nullptr), q(nullptr), r(nullptr), d(nullptr),
qf(nullptr), q1(nullptr), q2(nullptr), qv(nullptr) qf(nullptr), q1(nullptr), q2(nullptr), qv(nullptr)
@ -75,9 +77,9 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Illegal fix qeq command"); error->all(FLERR,"Illegal fix qeq command");
// must have charges // must have charges
if (!atom->q_flag) error->all(FLERR, "Fix {} requires atom attribute q", style); if (!atom->q_flag) error->all(FLERR, "Fix {} requires atom attribute q", style);
alpha = 0.20;
swa = 0.0; swa = 0.0;
swb = cutoff; swb = cutoff;
@ -115,6 +117,7 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) :
q2 = nullptr; q2 = nullptr;
streitz_flag = 0; streitz_flag = 0;
reax_flag = 0; reax_flag = 0;
ctip_flag = 0;
qv = nullptr; qv = nullptr;
comm_forward = comm_reverse = 1; comm_forward = comm_reverse = 1;
@ -134,6 +137,8 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) :
streitz_flag = 1; streitz_flag = 1;
} else if (utils::strmatch(arg[7],"^reax..")) { } else if (utils::strmatch(arg[7],"^reax..")) {
reax_flag = 1; reax_flag = 1;
} else if (strcmp(arg[7],"coul/ctip") == 0) {
ctip_flag = 1;
} else { } else {
read_file(arg[7]); read_file(arg[7]);
} }
@ -144,7 +149,6 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) :
FixQEq::~FixQEq() FixQEq::~FixQEq()
{ {
// unregister callbacks to this fix from Atom class // unregister callbacks to this fix from Atom class
if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW); if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW);
memory->destroy(s_hist); memory->destroy(s_hist);
@ -155,12 +159,15 @@ FixQEq::~FixQEq()
memory->destroy(shld); memory->destroy(shld);
if (!streitz_flag && !reax_flag) { if (!streitz_flag && !reax_flag && !ctip_flag) {
memory->destroy(chi); memory->destroy(chi);
memory->destroy(eta); memory->destroy(eta);
memory->destroy(gamma); memory->destroy(gamma);
memory->destroy(zeta); memory->destroy(zeta);
memory->destroy(zcore); memory->destroy(zcore);
memory->destroy(qmin);
memory->destroy(qmax);
memory->destroy(omega);
} }
} }
@ -756,6 +763,9 @@ void FixQEq::read_file(char *file)
memory->create(gamma,ntypes+1,"qeq:gamma"); memory->create(gamma,ntypes+1,"qeq:gamma");
memory->create(zeta,ntypes+1,"qeq:zeta"); memory->create(zeta,ntypes+1,"qeq:zeta");
memory->create(zcore,ntypes+1,"qeq:zcore"); memory->create(zcore,ntypes+1,"qeq:zcore");
memory->create(qmin,ntypes+1,"qeq:qmin");
memory->create(qmax,ntypes+1,"qeq:qmax");
memory->create(omega,ntypes+1,"qeq:omega");
// read each line out of file, skipping blank lines or leading '#' // read each line out of file, skipping blank lines or leading '#'
// store line of params if all 3 element tags are in element list // store line of params if all 3 element tags are in element list
@ -764,7 +774,7 @@ void FixQEq::read_file(char *file)
int *setflag = new int[ntypes+1]; int *setflag = new int[ntypes+1];
for (int n=0; n <= ntypes; ++n) { for (int n=0; n <= ntypes; ++n) {
setflag[n] = 0; setflag[n] = 0;
chi[n] = eta[n] = gamma[n] = zeta[n] = zcore[n] = 0.0; chi[n] = eta[n] = gamma[n] = zeta[n] = zcore[n] = qmin[n] = qmax[n] = omega[n] = 0.0;
} }
FILE *fp = nullptr; FILE *fp = nullptr;
@ -782,8 +792,13 @@ void FixQEq::read_file(char *file)
auto values = reader.next_values(0); auto values = reader.next_values(0);
if (values.count() == 0) continue; if (values.count() == 0) continue;
if (values.count() < 6) if (ctip_flag) {
throw qeq_parser_error("Invalid qeq parameter file"); if (values.count() < 9)
throw qeq_parser_error(fmt::format("Invalid qeq parameter file for {}", style));
} else {
if (values.count() < 6)
throw qeq_parser_error(fmt::format("Invalid qeq parameter file for {}", style));
}
auto word = values.next_string(); auto word = values.next_string();
utils::bounds(FLERR,word,1,ntypes,nlo,nhi,nullptr); utils::bounds(FLERR,word,1,ntypes,nlo,nhi,nullptr);
@ -800,6 +815,14 @@ void FixQEq::read_file(char *file)
for (int n=nlo; n <= nhi; ++n) zeta[n] = val; for (int n=nlo; n <= nhi; ++n) zeta[n] = val;
val = values.next_double(); val = values.next_double();
for (int n=nlo; n <= nhi; ++n) zcore[n] = val; for (int n=nlo; n <= nhi; ++n) zcore[n] = val;
if (ctip_flag) {
val = values.next_double();
for (int n=nlo; n <= nhi; ++n) qmin[n] = val;
val = values.next_double();
for (int n=nlo; n <= nhi; ++n) qmax[n] = val;
val = values.next_double();
for (int n=nlo; n <= nhi; ++n) omega[n] = val;
}
for (int n=nlo; n <= nhi; ++n) setflag[n] = 1; for (int n=nlo; n <= nhi; ++n) setflag[n] = 1;
} }
} catch (EOFException &) { } catch (EOFException &) {
@ -810,7 +833,7 @@ void FixQEq::read_file(char *file)
for (int n=1; n <= ntypes; ++n) for (int n=1; n <= ntypes; ++n)
if (setflag[n] == 0) if (setflag[n] == 0)
error->one(FLERR,"Parameters for atom type {} missing in qeq parameter file", n); error->one(FLERR, "Parameters for atom type {} missing in qeq parameter file", n);
delete[] setflag; delete[] setflag;
} }
@ -819,4 +842,7 @@ void FixQEq::read_file(char *file)
MPI_Bcast(gamma,ntypes+1,MPI_DOUBLE,0,world); MPI_Bcast(gamma,ntypes+1,MPI_DOUBLE,0,world);
MPI_Bcast(zeta,ntypes+1,MPI_DOUBLE,0,world); MPI_Bcast(zeta,ntypes+1,MPI_DOUBLE,0,world);
MPI_Bcast(zcore,ntypes+1,MPI_DOUBLE,0,world); MPI_Bcast(zcore,ntypes+1,MPI_DOUBLE,0,world);
MPI_Bcast(qmin,ntypes+1,MPI_DOUBLE,0,world);
MPI_Bcast(qmax,ntypes+1,MPI_DOUBLE,0,world);
MPI_Bcast(omega,ntypes+1,MPI_DOUBLE,0,world);
} }

View File

@ -70,10 +70,10 @@ class FixQEq : public Fix {
int maxwarn; // print warning when max iterations was reached int maxwarn; // print warning when max iterations was reached
double cutoff, cutoff_sq; // neighbor cutoff double cutoff, cutoff_sq; // neighbor cutoff
double *chi, *eta, *gamma, *zeta, *zcore; // qeq parameters double *chi, *eta, *gamma, *zeta, *zcore, *qmin, *qmax, *omega;
double *chizj; double *chizj;
double **shld; double **shld;
int streitz_flag, reax_flag; int streitz_flag, reax_flag, ctip_flag;
bigint ngroup; bigint ngroup;
@ -96,10 +96,6 @@ class FixQEq : public Fix {
double *b_s, *b_t; double *b_s, *b_t;
double *p, *q, *r, *d; double *p, *q, *r, *d;
// streitz-mintmire
double alpha;
// damped dynamics // damped dynamics
double *qf, *q1, *q2, qdamp, qstep; double *qf, *q1, *q2, qdamp, qstep;

438
src/QEQ/fix_qeq_ctip.cpp Normal file
View File

@ -0,0 +1,438 @@
// clang-format off
/* ----------------------------------------------------------------------
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 Plummer (NASA)
------------------------------------------------------------------------- */
#include "fix_qeq_ctip.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "ewald_const.h"
#include "force.h"
#include "kspace.h"
#include "math_const.h"
#include "memory.h"
#include "neigh_list.h"
#include "neighbor.h"
#include "pair.h"
#include "update.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace EwaldConst;
using namespace MathConst;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixQEqCTIP::FixQEqCTIP(LAMMPS *lmp, int narg, char **arg) :
FixQEq(lmp, narg, arg), reff(nullptr), reffsq(nullptr), reff4(nullptr), reff7(nullptr),
s2d_self(nullptr), shield(nullptr), shieldcu(nullptr), reffc(nullptr), reffcsq(nullptr),
reffc4(nullptr), reffc7(nullptr), s2d_shift(nullptr), f_shift(nullptr), e_shift(nullptr)
{
cdamp = 0.30;
maxrepeat = 10;
// optional args
int iarg = 8;
while (iarg < narg) {
if (strcmp(arg[iarg], "cdamp") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix qeq/ctip cdamp", error);
cdamp = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg += 2;
} else if (strcmp(arg[iarg], "maxrepeat") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix qeq/ctip maxrepeat", error);
maxrepeat = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg += 2;
} else if (strcmp(arg[iarg], "warn") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix qeq/ctip warn", error);
maxwarn = utils::logical(FLERR, arg[iarg + 1], false, lmp);
iarg += 2;
} else
error->all(FLERR, "Unknown fix qeq/ctip keyword: {}", arg[iarg]);
}
extract_ctip();
}
FixQEqCTIP::~FixQEqCTIP()
{
delete[] reff;
delete[] reffsq;
delete[] reff4;
delete[] reff7;
delete[] s2d_self;
memory->destroy(shield);
memory->destroy(shieldcu);
memory->destroy(reffc);
memory->destroy(reffcsq);
memory->destroy(reffc4);
memory->destroy(reffc7);
memory->destroy(s2d_shift);
memory->destroy(f_shift);
memory->destroy(e_shift);
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::init()
{
FixQEq::init();
neighbor->add_request(this, NeighConst::REQ_FULL);
int ntypes = atom->ntypes;
memory->create(shld, ntypes + 1, ntypes + 1, "qeq:shielding");
delete[] reff;
delete[] reffsq;
delete[] reff4;
delete[] reff7;
delete[] s2d_self;
reff = new double[ntypes];
reffsq = new double[ntypes];
reff4 = new double[ntypes];
reff7 = new double[ntypes];
s2d_self = new double[ntypes];
double r = cutoff;
double rsq = r * r;
double r6 = rsq * rsq * rsq;
double erfcd_cut = exp(-cdamp * cdamp * rsq);
double t_cut = 1.0 / (1.0 + EWALD_P * cdamp * r);
double erfcc_cut =
(t_cut * (A1 + t_cut * (A2 + t_cut * (A3 + t_cut * (A4 + t_cut * A5)))) * erfcd_cut) / r;
for (int elt1 = 0; elt1 < ntypes; elt1++) {
reff[elt1] = std::cbrt(rsq * r + 1.0 / (gamma[elt1 + 1] * gamma[elt1 + 1] * gamma[elt1 + 1]));
reffsq[elt1] = reff[elt1] * reff[elt1];
reff4[elt1] = reffsq[elt1] * reffsq[elt1];
reff7[elt1] = reff4[elt1] * reffsq[elt1] * reff[elt1];
s2d_self[elt1] = 2.0 * force->qqr2e *
(1.5 * erfcc_cut + 2.0 * cdamp / MY_PIS * erfcd_cut +
cdamp * cdamp * cdamp / MY_PIS * rsq * erfcd_cut + 0.5 / reff[elt1] - 1.5 / r +
r6 / reff7[elt1] + cdamp / MY_PIS);
}
memory->destroy(shield);
memory->destroy(shieldcu);
memory->destroy(reffc);
memory->destroy(reffcsq);
memory->destroy(reffc4);
memory->destroy(reffc7);
memory->destroy(s2d_shift);
memory->destroy(f_shift);
memory->destroy(e_shift);
memory->create(shield, ntypes, ntypes, "qeq:shield");
memory->create(shieldcu, ntypes, ntypes, "qeq:shieldcu");
memory->create(reffc, ntypes, ntypes, "qeq:reffc");
memory->create(reffcsq, ntypes, ntypes, "qeq:reffcsq");
memory->create(reffc4, ntypes, ntypes, "qeq:reffc4");
memory->create(reffc7, ntypes, ntypes, "qeq:reffc7");
memory->create(s2d_shift, ntypes, ntypes, "qeq:s2d_shift");
memory->create(f_shift, ntypes, ntypes, "qeq:f_shift");
memory->create(e_shift, ntypes, ntypes, "qeq:e_shift");
double cutoffsq = cutoff * cutoff;
double cutoffcu = cutoffsq * cutoff;
double cutoff4 = cutoffsq * cutoffsq;
double cdampcu = cdamp * cdamp * cdamp;
for (int elt1 = 0; elt1 < atom->ntypes; elt1++) {
for (int elt2 = 0; elt2 < atom->ntypes; elt2++) {
shield[elt1][elt2] = sqrt(gamma[elt1 + 1] * gamma[elt2 + 1]);
shieldcu[elt1][elt2] = shield[elt1][elt2] * shield[elt1][elt2] * shield[elt1][elt2];
reffc[elt1][elt2] = cbrt(cutoffcu + 1 / shieldcu[elt1][elt2]);
reffcsq[elt1][elt2] = reffc[elt1][elt2] * reffc[elt1][elt2];
reffc4[elt1][elt2] = reffcsq[elt1][elt2] * reffcsq[elt1][elt2];
reffc7[elt1][elt2] = reffc4[elt1][elt2] * reffcsq[elt1][elt2] * reffc[elt1][elt2];
s2d_shift[elt1][elt2] = 2.0 * erfcc_cut / cutoffcu +
4.0 * cdamp / MY_PIS * erfcd_cut / cutoffsq + 4.0 * cdampcu / MY_PIS * erfcd_cut -
2 / cutoffcu + 4 * cutoff4 / reffc7[elt1][elt2] - 2 * cutoff / reffc4[elt1][elt2];
f_shift[elt1][elt2] = erfcc_cut / cutoffsq + 2.0 * cdamp / MY_PIS * erfcd_cut / cutoff -
1 / cutoffsq + cutoffsq / reffc4[elt1][elt2];
e_shift[elt1][elt2] = erfcc_cut / cutoff + 1 / reffc[elt1][elt2] - 1 / cutoff;
}
}
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::extract_ctip()
{
Pair *pair = force->pair_match("^coul/ctip",0);
if (pair == nullptr) error->all(FLERR,"No pair style coul/ctip for fix qeq/ctip");
int tmp;
chi = (double *) pair->extract("chi",tmp);
eta = (double *) pair->extract("eta",tmp);
gamma = (double *) pair->extract("gamma",tmp);
zeta = (double *) pair->extract("zeta",tmp);
zcore = (double *) pair->extract("zcore",tmp);
qmin = (double *) pair->extract("qmin",tmp);
qmax = (double *) pair->extract("qmax",tmp);
omega = (double *) pair->extract("omega",tmp);
if (chi == nullptr || eta == nullptr || gamma == nullptr || zeta == nullptr ||
zcore == nullptr || qmin == nullptr || qmax == nullptr || omega == nullptr)
error->all(FLERR, "Fix qeq/ctip could not extract all params from pair style coul/ctip");
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::pre_force(int /*vflag*/)
{
int i,n;
if (update->ntimestep % nevery) return;
nlocal = atom->nlocal;
if (atom->nmax > nmax) reallocate_storage();
if (nlocal > n_cap*DANGER_ZONE || m_fill > m_cap*DANGER_ZONE)
reallocate_matrix();
for (i=1; i <= maxrepeat; i++) {
init_matvec();
matvecs = CG(b_s, s); // CG on s - parallel
matvecs += CG(b_t, t); // CG on t - parallel
matvecs /= 2;
n=calculate_check_Q();
MPI_Allreduce(&n, &nout, 1, MPI_INT, MPI_SUM, world);
if (nout == 0) break;
}
if (i > maxrepeat && comm->me == 0)
error->all(FLERR,"Fix qeq some charges not bound within the domain");
if (force->kspace) force->kspace->qsum_qsq();
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::init_matvec()
{
compute_H();
int inum, ii, i;
int *ilist;
double *q = atom->q, qi;
int *type = atom->type;
double r = cutoff;
double rsq = r*r;
double r6 = rsq*rsq*rsq;
double erfcd_cut = exp(-cdamp * cdamp * rsq);
double t_cut = 1.0 / (1.0 + EWALD_P * cdamp * r);
double erfcc_cut = (t_cut * (A1 + t_cut * (A2 + t_cut * (A3 + t_cut * (A4 + t_cut * A5)))) * erfcd_cut) / r;
inum = list->inum;
ilist = list->ilist;
for (ii = 0; ii < inum; ++ii) {
i = ilist[ii];
if (atom->mask[i] & groupbit) {
qi=q[i];
if (qi < qmin[type[i]]) {
Hdia_inv[i] = 1. / (eta[type[i]]+2*omega[type[i]]-s2d_self[type[i]-1]);
b_s[i] = -((chi[type[i]]-2*qmin[type[i]]*omega[type[i]]) + chizj[i]);
} else if (qi < qmax[type[i]]) {
Hdia_inv[i] = 1. / (eta[type[i]]-s2d_self[type[i]-1]);
b_s[i] = -(chi[type[i]] + chizj[i]);
} else {
Hdia_inv[i] = 1. / (eta[type[i]]+2*omega[type[i]]-s2d_self[type[i]-1]);
b_s[i] = -((chi[type[i]]-2*qmax[type[i]]*omega[type[i]]) + chizj[i]);
}
b_t[i] = -1.0;
t[i] = t_hist[i][2] + 3 * (t_hist[i][0] - t_hist[i][1]);
s[i] = 4*(s_hist[i][0]+s_hist[i][2])-(6*s_hist[i][1]+s_hist[i][3]);
}
}
pack_flag = 2;
comm->forward_comm(this); //Dist_vector(s);
pack_flag = 3;
comm->forward_comm(this); //Dist_vector(t);
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::compute_H()
{
int inum, jnum, *ilist, *jlist, *numneigh, **firstneigh;
int i, j, ii, jj;
double dx, dy, dz, r_sqr, r, reff;
double cutoffsq, cutoffcu, cutoff4, cdampcu, erfcc_cut, erfcd_cut, t_cut;
double erfcc, erfcd, t;
int elt1, elt2;
double **x = atom->x;
int *mask = atom->mask;
int *type = atom->type;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
cutoffsq = cutoff * cutoff;
cutoffcu = cutoffsq * cutoff;
cutoff4 = cutoffsq * cutoffsq;
cdampcu = cdamp * cdamp * cdamp;
erfcd_cut = exp(-cdamp * cdamp * cutoffsq);
t_cut = 1.0 / (1.0 + EWALD_P * cdamp * cutoff);
erfcc_cut = t_cut * (A1 + t_cut * (A2 + t_cut * (A3 + t_cut * (A4 + t_cut * A5)))) * erfcd_cut;
// fill in the H matrix
m_fill = 0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (mask[i] & groupbit) {
jlist = firstneigh[i];
jnum = numneigh[i];
H.firstnbr[i] = m_fill;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
dx = x[j][0] - x[i][0];
dy = x[j][1] - x[i][1];
dz = x[j][2] - x[i][2];
r_sqr = dx*dx + dy*dy + dz*dz;
if (r_sqr <= cutoff_sq) {
H.jlist[m_fill] = j;
r = sqrt(r_sqr);
reff = cbrt(r_sqr * r + 1 / shieldcu[type[i]-1][type[j]-1]);
erfcd = exp(-cdamp * cdamp * r_sqr);
t = 1.0 / (1.0 + EWALD_P * cdamp * r);
erfcc = t * (A1 + t * (A2 + t * (A3 + t * (A4 + t * A5)))) * erfcd;
H.val[m_fill] = 0.5*force->qqr2e*(erfcc/r+1/reff-1/r-e_shift[type[i]-1][type[j]-1]+f_shift[type[i]-1][type[j]-1]*(r-cutoff)-s2d_shift[type[i]-1][type[j]-1]*0.5*(r-cutoff)*(r-cutoff));
m_fill++;
}
}
H.numnbrs[i] = m_fill - H.firstnbr[i];
}
}
if (m_fill >= H.m)
error->all(FLERR,"Fix qeq/ctip has insufficient H matrix size: m_fill={} H.m={}\n",m_fill, H.m);
}
/* ---------------------------------------------------------------------- */
void FixQEqCTIP::sparse_matvec(sparse_matrix *A, double *x, double *b)
{
int i, j, itr_j;
double *q=atom->q, qi;
int *type = atom->type;
nlocal = atom->nlocal;
nall = atom->nlocal + atom->nghost;
for (i = 0; i < nlocal; ++i) {
if (atom->mask[i] & groupbit) {
qi=q[i];
if (qi < qmin[type[i]]) {
b[i] = (eta[type[i]]+2*omega[type[i]]-s2d_self[type[i]-1])*x[i];
} else if (qi < qmax[type[i]]) {
b[i] = (eta[type[i]]-s2d_self[type[i]-1]) * x[i];
} else {
b[i] = (eta[type[i]]+2*omega[type[i]]-s2d_self[type[i]-1])*x[i];
}
}
}
for (i = nlocal; i < nall; ++i) {
if (atom->mask[i] & groupbit)
b[i] = 0;
}
for (i = 0; i < nlocal; ++i) {
if (atom->mask[i] & groupbit) {
for (itr_j=A->firstnbr[i]; itr_j<A->firstnbr[i]+A->numnbrs[i]; itr_j++) {
j = A->jlist[itr_j];
b[i] += A->val[itr_j] * x[j];
b[j] += A->val[itr_j] * x[i];
}
}
}
}
/* ---------------------------------------------------------------------- */
int FixQEqCTIP::calculate_check_Q()
{
int i, k, inum, ii;
int *ilist;
double u, s_sum, t_sum;
double *q = atom->q;
int *type = atom->type;
double qi_old,qi_new;
double qi_check1,qi_check2;
double qi_check3;
int n;
inum = list->inum;
ilist = list->ilist;
s_sum = parallel_vector_acc( s, inum );
t_sum = parallel_vector_acc( t, inum);
u = s_sum / t_sum;
n = 0;
for( ii = 0; ii < inum; ++ii ) {
i = ilist[ii];
if (atom->mask[i] & groupbit) {
qi_old = q[i];
q[i] = s[i] - u * t[i];
for( k = 4; k > 0; --k ) {
s_hist[i][k] = s_hist[i][k-1];
t_hist[i][k] = t_hist[i][k-1];
}
s_hist[i][0] = s[i];
t_hist[i][0] = t[i];
qi_new = q[i];
qi_check1=(qi_new-qmin[type[i]])*(qi_old-qmin[type[i]]);
qi_check2=(qi_new-qmax[type[i]])*(qi_old-qmax[type[i]]);
if ( qi_check1 < 0.0 || qi_check2 < 0.0 ) {
qi_check3=abs(qi_new-qi_old);
if (qi_check3 > tolerance) n++;
}
}
}
pack_flag = 4;
comm->forward_comm( this ); //Dist_vector( atom->q );
return n;
}

51
src/QEQ/fix_qeq_ctip.h Normal file
View File

@ -0,0 +1,51 @@
/* -*- 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 FIX_CLASS
// clang-format off
FixStyle(qeq/ctip,FixQEqCTIP);
// clang-format on
#else
#ifndef LMP_FIX_QEQ_CTIP_H
#define LMP_FIX_QEQ_CTIP_H
#include "fix_qeq.h"
namespace LAMMPS_NS {
class FixQEqCTIP : public FixQEq {
public:
FixQEqCTIP(class LAMMPS *, int, char **);
~FixQEqCTIP() override;
void init() override;
void pre_force(int) override;
protected:
void init_matvec();
void sparse_matvec(sparse_matrix *, double *, double *) override;
void compute_H();
void extract_ctip();
int calculate_check_Q();
double *reff, *reffsq, *reff4, *reff7, *s2d_self;
double **shield, **shieldcu, **reffc, **reffcsq, **reffc4, **reffc7;
double **s2d_shift, **f_shift, **e_shift;
double cdamp;
int maxrepeat;
int nout;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -31,7 +31,7 @@ class FixQEqSlater : public FixQEq {
void init() override; void init() override;
void pre_force(int) override; void pre_force(int) override;
private: protected:
void init_matvec(); void init_matvec();
void sparse_matvec(sparse_matrix *, double *, double *) override; void sparse_matvec(sparse_matrix *, double *, double *) override;
void compute_H(); void compute_H();
@ -40,6 +40,7 @@ class FixQEqSlater : public FixQEq {
void extract_streitz(); void extract_streitz();
class PairCoulStreitz *streitz; class PairCoulStreitz *streitz;
double alpha;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif

View File

@ -0,0 +1,92 @@
---
lammps_version: 29 Aug 2024
tags:
date_generated: Tue Sep 10 21:29:25 2024
epsilon: 5e-13
skip_tests:
prerequisites: ! |
atom full
pair coul/ctip
pre_commands: ! |
variable units index metal
variable newton_pair delete
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
post_commands: ! |
timestep 0.001
pair_modify mix arithmetic
velocity all scale 10.0
input_file: in.fourmol
pair_style: coul/ctip 0.3 8.0
pair_coeff: ! |
* * NiO.ctip Ni O Ni O O
extract: ! ""
natoms: 29
init_vdwl: 0
init_coul: 268.83312357946403
init_stress: ! |2-
6.3490063021156979e+00 3.7408695241730894e+00 7.0361156620229268e+00 2.0792271323016851e+00 1.5573754855973017e+00 2.7470162844995999e-01
init_forces: ! |2
1 -6.6766498869476165e-01 -5.5042307531553758e-01 9.7032502239632901e-01
2 7.7521977879752624e-01 5.0872136823803349e-01 -9.8588006812149209e-01
3 7.0494670150651594e-03 6.7222063121221878e-02 2.9642961180318752e-02
4 -2.1429412404391085e-02 -2.0950579072655018e-02 -3.3568909100718497e-02
5 -3.7363529861740602e-02 -2.4923337785193594e-02 1.1516900374344946e-02
6 -1.0946612479959126e+00 8.9700509334645628e-01 4.9320185843336117e-01
7 1.1854416475916033e-01 -2.6576678610813409e-01 -1.0899734140877935e+00
8 6.4955585415778372e-01 -7.6274120860081573e-01 -6.3166430197088130e-01
9 3.3316295347683439e-01 8.0330773793723831e-02 1.3555612385253035e+00
10 1.1467966540573368e-01 -2.8828389443679403e-01 3.8986752595171752e-02
11 -2.4384183205874675e-02 3.3909937515907505e-02 1.8524465479279953e-02
12 -1.9578368735092340e-02 -6.4486478848736154e-04 1.4237271164103524e-01
13 1.4680378874991862e-01 -6.6502911869983319e-02 -6.2810542877883603e-03
14 -1.0152770779985132e-01 2.4657561691070650e-02 -1.6160131249611986e-01
15 2.0317060148768745e-02 1.5135710002923145e-01 8.7520151900347225e-03
16 4.0894956691719275e-01 -3.8805473224896847e-01 -1.1465067428171507e+00
17 -5.6419218424954654e-01 5.9312634326499702e-01 9.1123225799149365e-01
18 -1.0353302404272195e-01 -3.0606707755299051e-01 1.4428249631391288e+00
19 -7.4737534024659158e-01 -5.4784645392478748e-01 -8.3742536745705298e-01
20 8.2767150614670815e-01 8.5638074072256409e-01 -5.2830130487714022e-01
21 -4.2535085192871286e-01 -4.2523240078604435e-01 1.4034119287909781e+00
22 -7.0318546735293863e-01 -1.9656967920669050e-01 -1.0670964282227489e+00
23 1.1119704560782739e+00 6.3955433504897763e-01 -3.1639917324870870e-01
24 2.9868496682933654e-01 -1.2313751450902117e+00 7.0609939414552292e-01
25 -1.0090099351955220e+00 1.1559130801748081e-01 -8.2798310388092733e-01
26 6.9019280914785663e-01 1.1080935733374833e+00 1.0138627381567281e-01
27 1.9301178235023941e-01 -1.3471486311081766e+00 4.8386252002863672e-01
28 -1.0539921061236890e+00 4.0997619288717529e-01 -7.0289214632426211e-01
29 8.7743452785694820e-01 9.3660438688114711e-01 2.1787206316617308e-01
run_vdwl: 0
run_coul: 268.4476086884773
run_stress: ! |2-
5.9299248883876601e+00 3.4781130547249339e+00 6.5801272741781647e+00 1.8619728227105692e+00 1.4659099790426291e+00 3.5924356392720608e-01
run_forces: ! |2
1 -6.0427571725450790e-01 -4.9892889777278226e-01 8.8545319536786815e-01
2 7.1312454132801029e-01 4.5923931150828301e-01 -9.0158273806646261e-01
3 6.5930657976885961e-03 6.8086911518340634e-02 3.0298419004164478e-02
4 -2.0005152917110077e-02 -2.0495734577847459e-02 -3.3168698480578490e-02
5 -3.6989504598576979e-02 -2.4815949113475184e-02 1.0615514262009192e-02
6 -1.0766475299916556e+00 8.8359720904052264e-01 4.7219323578273070e-01
7 1.2279399227984265e-01 -2.6624889781330596e-01 -1.0434209735871274e+00
8 6.5311135505192497e-01 -7.1476474929937395e-01 -5.5684953652533686e-01
9 3.1104308514004397e-01 3.7965971349324459e-02 1.2513806890774151e+00
10 1.1744727580125273e-01 -2.9036328040419229e-01 3.9026787957685875e-02
11 -2.4486616434667621e-02 3.4101196287017937e-02 1.7731496391806937e-02
12 -1.8112753214851833e-02 -1.5329987398169501e-03 1.3724246989467195e-01
13 1.4421485545442478e-01 -6.4023023867411502e-02 -6.4830241578088810e-03
14 -1.0093704405052448e-01 2.3626240487656585e-02 -1.5594488783666602e-01
15 1.8113350861168019e-02 1.5003134533333243e-01 9.0410683517616990e-03
16 3.9564305615954043e-01 -3.8326160090034744e-01 -1.1107744422444059e+00
17 -5.5350195813896730e-01 5.9523443686042754e-01 8.7501993236997910e-01
18 -3.5281227598702475e-02 -1.9465990896490087e-01 1.2667234231080493e+00
19 -6.8038617394630396e-01 -5.1379378261297537e-01 -7.5333352330996883e-01
20 6.8989560916162340e-01 7.1158296007868249e-01 -4.3113760667659928e-01
21 -3.8916912422204580e-01 -3.6027897454313712e-01 1.2562100641596712e+00
22 -6.3524203874677565e-01 -1.8438227441572771e-01 -9.5303869389459417e-01
23 1.0072567206938428e+00 5.6287061853542042e-01 -2.8243135805657577e-01
24 2.9449971576480227e-01 -1.1247166291512272e+00 6.5352065873792231e-01
25 -9.4482316277239342e-01 9.9894478313402951e-02 -7.7751414482791736e-01
26 6.2907073683814840e-01 1.0167291975732295e+00 1.0258032074544736e-01
27 1.7910891405692830e-01 -1.2099165608953455e+00 4.2142835781775040e-01
28 -9.4665562310478557e-01 3.6784596735523806e-01 -6.2528460074895109e-01
29 7.8459735260262686e-01 8.4137741883098838e-01 2.0249859538405895e-01
...