diff --git a/doc/src/Commands_fix.rst b/doc/src/Commands_fix.rst index 4793568288..671716e89d 100644 --- a/doc/src/Commands_fix.rst +++ b/doc/src/Commands_fix.rst @@ -46,6 +46,7 @@ OPT. * :doc:`bond/react ` * :doc:`bond/swap ` * :doc:`box/relax ` + * :doc:`charge/regulation ` * :doc:`client/md ` * :doc:`cmap ` * :doc:`colvars ` diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index b10983a35b..f1c590d850 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -586,7 +586,7 @@ MC package Several fixes and a pair style that have Monte Carlo (MC) or MC-like attributes. These include fixes for creating, breaking, and swapping bonds, for performing atomic swaps, and performing grand-canonical MC -(GCMC) in conjunction with dynamics. +(GCMC) or similar processes in conjunction with dynamics. **Supporting info:** @@ -594,8 +594,12 @@ bonds, for performing atomic swaps, and performing grand-canonical MC * :doc:`fix atom/swap ` * :doc:`fix bond/break ` * :doc:`fix bond/create ` +* :doc:`fix bond/create/angle ` * :doc:`fix bond/swap ` +* :doc:`fix charge/regulation ` * :doc:`fix gcmc ` +* :doc:`fix tfmc ` +* :doc:`fix widom ` * :doc:`pair_style dsmc ` * https://lammps.sandia.gov/movies.html#gcmc diff --git a/doc/src/fix.rst b/doc/src/fix.rst index 2e516faa4e..109bfb00be 100644 --- a/doc/src/fix.rst +++ b/doc/src/fix.rst @@ -189,6 +189,7 @@ accelerated styles exist. * :doc:`bond/react ` - apply topology changes to model reactions * :doc:`bond/swap ` - Monte Carlo bond swapping * :doc:`box/relax ` - relax box size during energy minimization +* :doc:`charge/regulation ` - Monte Carlo sampling of charge regulation * :doc:`client/md ` - MD client for client/server simulations * :doc:`cmap ` - enables CMAP cross-terms of the CHARMM force field * :doc:`colvars ` - interface to the collective variables "Colvars" library diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst new file mode 100644 index 0000000000..ef91db1e59 --- /dev/null +++ b/doc/src/fix_charge_regulation.rst @@ -0,0 +1,276 @@ + +.. index:: fix charge/regulation + +fix charge/regulation command +============================= + +Syntax +"""""" + +.. parsed-literal:: + + fix ID group-ID charge/regulation cation_type anion_type keyword value(s) + +* ID, group-ID are documented in fix command +* charge/regulation = style name of this fix command +* cation_type = atom type of free cations +* anion_type = atom type of free anions + +* zero or more keyword/value pairs may be appended + + .. parsed-literal:: + + keyword = *pH*, *pKa*, *pKb*, *pIp*, *pIm*, *pKs*, *acid_type*, *base_type*, *lunit_nm*, *temp*, *tempfixid*, *nevery*, *nmc*, *xrd*, *seed*, *tag*, *group*, *onlysalt*, *pmcmoves* + *pH* value = pH of the solution + *pKa* value = acid dissociation constant + *pKb* value = base dissociation constant + *pIp* value = chemical potential of free cations + *pIm* value = chemical potential of free anions + *pKs* value = solution self-dissociation constant + *acid_type* = atom type of acid groups + *base_type* = atom type of base groups + *lunit_nm* value = unit length used by LAMMPS (# in the units of nanometers) + *temp* value = temperature + *tempfixid* value = fix ID of temperature thermostat + *nevery* value = invoke this fix every nevery steps + *nmc* value = number of charge regulation MC moves to attempt every nevery steps + *xrd* value = cutoff distance for acid/base reaction + *seed* value = random # seed (positive integer) + *tag* value = yes or no (yes: The code assign unique tags to inserted ions; no: The tag of all inserted ions is "0") + *group* value = group-ID, inserted ions are assigned to group group-ID. Can be used multiple times to assign inserted ions to multiple groups. + *onlysalt* values = flag charge_cation charge_anion. + flag = yes or no (yes: the fix performs only ion insertion/deletion, no: perform acid/base dissociation and ion insertion/deletion) + charge_cation, charge_anion = value of cation/anion charge, must be an integer (only specify if flag = yes) + *pmcmoves* values = pmcA pmcB pmcI - MC move fractions for acid ionization (pmcA), base ionization (pmcB) and free ion exchange (pmcI) + +Examples +"""""""" +.. code-block:: LAMMPS + + fix chareg all charge/regulation 1 2 acid_type 3 base_type 4 pKa 5 pKb 7 lb 1.0 nevery 200 nexchange 200 seed 123 tempfixid fT + + fix chareg all charge/regulation 1 2 pIp 3 pIm 3 onlysalt yes 2 -1 seed 123 tag yes temp 1.0 + +Description +""""""""""" + +This fix performs Monte Carlo (MC) sampling of charge regulation and +exchange of ions with a reservoir as discussed in :ref:`(Curk1) ` +and :ref:`(Curk2) `. The implemented method is largely analogous +to the grand-reaction ensemble method in :ref:`(Landsgesell) +`. The implementation is parallelized, compatible with +existing LAMMPS functionalities, and applicable to any system utilizing +discrete, ionizable groups or surface sites. + +Specifically, the fix implements the following three types of MC moves, +which discretely change the charge state of individual particles and +insert ions into the systems: :math:`\mathrm{A} \rightleftharpoons +\mathrm{A}^-+\mathrm{X}^+`, :math:`\mathrm{B} \rightleftharpoons +\mathrm{B}^++\mathrm{X}^-`, and :math:`\emptyset \rightleftharpoons +Z^-\mathrm{X}^{Z^+}+Z^+\mathrm{X}^{-Z^-}`. In the former two types of +reactions, Monte Carlo moves alter the charge value of specific atoms +(:math:`\mathrm{A}`, :math:`\mathrm{B}`) and simultaneously insert a +counterion to preserve the charge neutrality of the system, modeling the +dissociation/association process. The last type of reaction performs +grand canonical MC exchange of ion pairs with a (fictitious) reservoir. + +In our implementation "acid" refers to particles that can attain charge +:math:`q=\{0,-1\}` and "base" to particles with :math:`q=\{0,1\}`, +whereas the MC exchange of free ions allows any integer charge values of +:math:`{Z^+}` and :math:`{Z^-}`. + +Here we provide several practical examples for modeling charge +regulation effects in solvated systems. An acid ionization reaction +(:math:`\mathrm{A} \rightleftharpoons \mathrm{A}^-+\mathrm{H}^+`) can be +defined via a single line in the input file + +.. code-block:: LAMMPS + + fix acid_reaction all charge/regulation 2 3 acid_type 1 pH 7.0 pKa 5.0 pIp 7.0 pIm 7.0 + +where the fix attempts to charge :math:`\mathrm{A}` (discharge +:math:`\mathrm{A}^-`) to :math:`\mathrm{A}^-` (:math:`\mathrm{A}`) and +insert (delete) a proton (atom type 2). Besides, the fix implements +self-ionization reaction of water :math:`\emptyset \rightleftharpoons +\mathrm{H}^++\mathrm{OH}^-`. However, this approach is highly +inefficient at :math:`\mathrm{pH} \approx 7` when the concentration of +both protons and hydroxyl ions is low, resulting in a relatively low +acceptance rate of MC moves. + +A more efficient way is to allow salt ions to participate in ionization +reactions, which can be easily achieved via + +.. code-block:: LAMMPS + + fix acid_reaction all charge/regulation 4 5 acid_type 1 pH 7.0 pKa 5.0 pIp 2.0 pIm 2.0 + +where particles of atom type 4 and 5 are the salt cations and anions, +both at chemical potential pI=2.0, see :ref:`(Curk1) ` and +:ref:`(Landsgesell) ` for more details. + + + Similarly, we could have simultaneously added a base ionization reaction + (:math:`\mathrm{B} \rightleftharpoons \mathrm{B}^++\mathrm{OH}^-`) + +.. code-block:: LAMMPS + + fix base_reaction all charge/regulation 2 3 base_type 6 pH 7.0 pKb 6.0 pIp 7.0 pIm 7.0 + +where the fix will attempt to charge :math:`\mathrm{B}` (discharge +:math:`\mathrm{B}^+`) to :math:`\mathrm{B}^+` (:math:`\mathrm{B}`) and +insert (delete) a hydroxyl ion :math:`\mathrm{OH}^-` of atom type 3. If +neither the acid or the base type is specified, for example, + +.. code-block:: LAMMPS + + fix salt_reaction all charge/regulation 4 5 pIp 2.0 pIm 2.0 + +the fix simply inserts or deletes an ion pair of a free cation (atom +type 4) and a free anion (atom type 5) as done in a conventional +grand-canonical MC simulation. + + +The fix is compatible with LAMMPS sub-packages such as *molecule* or +*rigid*. That said, the acid and base particles can be part of larger +molecules or rigid bodies. Free ions that are inserted to or deleted +from the system must be defined as single particles (no bonded +interactions allowed) and cannot be part of larger molecules or rigid +bodies. If *molecule* package is used, all inserted ions have a molecule +ID equal to zero. + +Note that LAMMPS implicitly assumes a constant number of particles +(degrees of freedom). Since using this fix alters the total number of +particles during the simulation, any thermostat used by LAMMPS, such as +NVT or Langevin, must use a dynamic calculation of system +temperature. This can be achieved by specifying a dynamic temperature +compute (e.g. dtemp) and using it with the desired thermostat, e.g. a +Langevin thermostat: + +.. code-block:: LAMMPS + + compute dtemp all temp + compute_modify dtemp dynamic yes + fix fT all langevin 1.0 1.0 1.0 123 + fix_modify fT temp dtemp + +The chemical potential units (e.g. pH) are in the standard log10 +representation assuming reference concentration :math:`\rho_0 = +\mathrm{mol}/\mathrm{l}`. Therefore, to perform the internal unit +conversion, the length (in nanometers) of the LAMMPS unit length must be +specified via *lunit_nm* (default is set to the Bjerrum length in water +at room temperature *lunit_nm* = 0.71nm). For example, in the dilute +ideal solution limit, the concentration of free ions will be +:math:`c_\mathrm{I} = 10^{-\mathrm{pIp}}\mathrm{mol}/\mathrm{l}`. + +The temperature used in MC acceptance probability is set by *temp*. This +temperature should be the same as the temperature set by the molecular +dynamics thermostat. For most purposes, it is probably best to use +*tempfixid* keyword which dynamically sets the temperature equal to the +chosen MD thermostat temperature, in the example above we assumed the +thermostat fix-ID is *fT*. The inserted particles attain a random +velocity corresponding to the specified temperature. Using *tempfixid* +overrides any fixed temperature set by *temp*. + +The *xrd* keyword can be used to restrict the inserted/deleted +counterions to a specific radial distance from an acid or base particle +that is currently participating in a reaction. This can be used to +simulate more realist reaction dynamics. If *xrd* = 0 or *xrd* > *L* / +2, where *L* is the smallest box dimension, the radial restriction is +automatically turned off and free ion can be inserted or deleted +anywhere in the simulation box. + +If the *tag yes* is used, every inserted atom gets a unique tag ID, +otherwise, the tag of every inserted atom is set to 0. *tag yes* might +cause an integer overflow in very long simulations since the tags are +unique to every particle and thus increase with every successful +particle insertion. + +The *pmcmoves* keyword sets the relative probability of attempting the +three types of MC moves (reactions): acid charging, base charging, and +ion pair exchange. The fix only attempts to perform particle charging +MC moves if *acid_type* or *base_type* is defined. Otherwise fix only +performs free ion insertion/deletion. For example, if *acid_type* is not +defined, *pmcA* is automatically set to 0. The vector *pmcmoves* is +automatically normalized, for example, if set to *pmcmoves* 0 0.33 0.33, +the vector would be normalized to [0,0.5,0.5]. + +The *only_salt* option can be used to perform multivalent +grand-canonical ion-exchange moves. If *only_salt yes* is used, no +charge exchange is performed, only ion insertion/deletion (*pmcmoves* is +set to [0,0,1]), but ions can be multivalent. In the example above, an +MC move would consist of three ion insertion/deletion to preserve the +charge neutrality of the system. + +The *group* keyword can be used to add inserted particles to a specific +group-ID. All inserted particles are automatically added to group *all*. + + +Output +"""""" + +This fix computes a global vector of length 8, which can be accessed by +various output commands. The vector values are the following global +quantities: + +* 1 = cumulative MC attempts +* 2 = cumulative MC successes +* 3 = current # of neutral acid atoms +* 4 = current # of -1 charged acid atoms +* 5 = current # of neutral base atoms +* 6 = current # of +1 charged base atoms +* 7 = current # of free cations +* 8 = current # of free anions + + +Restrictions +"""""""""""" + +This fix is part of the MC package. It is only enabled if LAMMPS +was built with that package. See the :doc:`Build package +` doc page for more info. + +The :doc:`atom_style `, used must contain the charge +property, for example, the style could be *charge* or *full*. Only +usable for 3D simulations. Atoms specified as free ions cannot be part +of rigid bodies or molecules and cannot have bonding interactions. The +scheme is limited to integer charges, any atoms with non-integer charges +will not be considered by the fix. + +All interaction potentials used must be continuous, otherwise the MD +integration and the particle exchange MC moves do not correspond to the +same equilibrium ensemble. For example, if an lj/cut pair style is used, +the LJ potential must be shifted so that it vanishes at the cutoff. This +can be easily achieved using the :doc:`pair_modify ` +command, i.e., by using: *pair_modify shift yes*. + +.. note:: + + Region restrictions are not yet implemented. + +Related commands +"""""""""""""""" + +:doc:`fix gcmc `, +:doc:`fix atom/swap ` + +Default +""""""" + +pH = 7.0; pKa = 100.0; pKb = 100.0; pIp = 5.0; pIm = 5.0; pKs = 14.0; +acid_type = -1; base_type = -1; lunit_nm = 0.71; temp = 1.0; nevery = +100; nmc = 100; xrd = 0; seed = 0; tag = no; onlysalt = no, pmcmoves = +[1/3, 1/3, 1/3], group-ID = all + +---------- + +.. _Curk1: + +**(Curk1)** T. Curk, J. Yuan, and E. Luijten, "Coarse-grained simulation of charge regulation using LAMMPS", preprint (2021). + +.. _Curk2: + +**(Curk2)** T. Curk and E. Luijten, "Charge-regulation effects in nanoparticle self-assembly", PRL (2021) + +.. _Landsgesell: + +**(Landsgesell)** J. Landsgesell, P. Hebbeker, O. Rud, R. Lunkad, P. Kosovan, and C. Holm, "Grand-reaction method for simulations of ionization equilibria coupled to ion partitioning", Macromolecules 53, 3007-3020 (2020). diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 402ce471cc..54cb6d2f3c 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -261,6 +261,7 @@ bitmask bitrate bitrates Bitzek +Bjerrum Blaise blanchedalmond blocksize @@ -504,6 +505,8 @@ coulgauss coulombic Coulombic Coulombics +counterion +counterions Courant covalent covalently @@ -732,6 +735,7 @@ DRUDE dsf dsmc dt +dtemp dtgrow dtheta dtshrink @@ -880,6 +884,7 @@ equilibrates equilibrating equilibration Equilibria +equilibria equilization equipartitioning Ercolessi @@ -1216,6 +1221,7 @@ hbnewflag hbond hcp heatconduction +Hebbeker Hebenstreit Hecht Heenen @@ -1283,6 +1289,7 @@ hy hydrophobicity hydrostatic hydrostatically +hydroxyl Hynninen Hyoungki hyperdynamics @@ -1373,6 +1380,7 @@ ints inv invariants inversed +ionizable ionocovalent iostreams iparam @@ -1552,6 +1560,7 @@ Koning Kooser Korn Koskinen +Kosovan Koster Kosztin Kp @@ -1598,6 +1607,7 @@ Lamoureux Lanczos Lande Landron +Landsgesell langevin Langevin Langston @@ -1735,10 +1745,13 @@ lpsapi lrt lsfftw ltbbmalloc +Lua lubricateU lucy -Lua Luding +Luijten +lunit +Lunkad Lussetti Lustig lval @@ -2029,6 +2042,7 @@ multiscale multisectioning multithreading Multithreading +multivalent Mundy Murdick Murtola @@ -2074,6 +2088,7 @@ Nanoletters nanomechanics nanometer nanometers +nanoparticle nanoparticles Nanotube nanotube @@ -2183,6 +2198,7 @@ nm Nm Nmax nmax +nmc Nmin nmin Nmols @@ -2317,6 +2333,7 @@ OMP oneAPI onelevel oneway +onlysalt onn ons OO @@ -2401,6 +2418,8 @@ pbc pc pchain Pchain +pcmoves +pmcmoves Pdamp pdb pdf @@ -2445,6 +2464,7 @@ phosphide Phs Physica physik +pI Piaggi picocoulomb picocoulombs @@ -2456,7 +2476,9 @@ pid piecewise Pieniazek Pieter +pIm pimd +pIp Piola Pisarev Pishevar @@ -2471,6 +2493,9 @@ ploop PloS plt plumedfile +pKa +pKb +pKs pmb Pmolrotate Pmoltrans @@ -2799,6 +2824,7 @@ rst rstyle Rubensson Rubia +Rud Rudd Rudra Rudranarayan diff --git a/examples/USER/misc/charge_regulation/README b/examples/USER/misc/charge_regulation/README new file mode 100644 index 0000000000..c704b67dea --- /dev/null +++ b/examples/USER/misc/charge_regulation/README @@ -0,0 +1,36 @@ +This directory has two input scripts that illustrates how to use fix +charge_regulation in LAMMPS to perform coarse-grained molecular dynamics +(MD) simulations with incorporation of charge regulation effects. The +charge regulation is implemented via Monte Carlo (MC) sampling following +the reaction ensemble MC approach, producing a MC/MD hybrid tool for +modeling charge regulation in solvated systems. + +The script `in.chreg-acid` sets up a simple weak acid electrolyte +(pH=7,pKa=6,pI=3). Four different types of MC moves are implemented: +acid protonation & de-protonation, and monovalent ion pair insertion and +deletion. Note here we have grouped all free monovalent ions into a +single type, a physically natural choice on the level of coarse-grained +primitive electrolyte models, which increases the calculation +performance but has no effects on thermodynamic observables. The +variables such as pH, pKa, pI, and lb at the top of the input script can +be adjusted to play with various simulation parameters. The cumulative +MC attempted moves and cumulative number of accepted moves, as well as, +current number of neutral and charged acid particles, neutral and +charged base particles (in this example always 0), and the current +number of free cations and anions in the system are printed in the +output. + +The script `in.chreg-polymer` sets up a weak poly-electrolyte chain of +N=80 beads. Each bead is a weak acid with pKa=5 and solution has pH=7 +and monovalent salt chemical potential pI=3. In this example, we choose +to treat salt ions, protons, and hydroxyl ions separately, which results +in 5 types of MC moves: acid [type 1] protonation & de-protonation (with +protons [type 4] insertion & deletion), acid [type 1] protonation & +de-protonation (with salt cation [type 2] insertion & deletion), water +self-ionization (insertion and deletion of proton [type4] and hydroxyl +ion [type 5] pair), insertion and deletion of monovalent salt pair [type +2 and type 3] , insertion and deletion of a proton [type4] and salt +anion [type 3]. The current number of neutral and charged acid +particles, the current number of free salt cations and anions, and the +current number of protons and hydroxyl ions are printed in the output. + diff --git a/examples/USER/misc/charge_regulation/data.chreg-acid b/examples/USER/misc/charge_regulation/data.chreg-acid new file mode 100644 index 0000000000..edc7082ad0 --- /dev/null +++ b/examples/USER/misc/charge_regulation/data.chreg-acid @@ -0,0 +1,235 @@ +LAMMPS data file generated by get_input.py + +219 atoms +3 atom types +-2.5000000000000000e+01 2.5000000000000000e+01 xlo xhi +-2.5000000000000000e+01 2.5000000000000000e+01 ylo yhi +-2.5000000000000000e+01 2.5000000000000000e+01 zlo zhi + +Masses + +1 1 +2 1 +3 1 + +Atoms + +1 1 0 2.5983275747497636 -8.368052973860795 20.001288664343484 +2 1 -1 -18.182868728594865 -8.079792367885453 8.253737231981816 +3 1 -1 -17.437350808966414 8.120411567445771 10.747650340639332 +4 1 -1 6.502476583291578 -23.497326620756837 19.948223080086798 +5 1 -1 -22.528179279677296 -18.783433570718127 -17.964657736688018 +6 1 -1 -9.713496019164342 18.97235576760402 -19.495620818582825 +7 1 -1 -12.831976006720659 0.12265736526942561 -21.679396938423718 +8 1 -1 20.909063679212295 -2.16535062758771 0.46197866620165584 +9 1 -1 23.86211981166997 24.024928465132284 10.534067202515907 +10 1 -1 -0.5289298325031275 23.820222457999776 -2.657199543669442 +11 1 -1 9.57021229491361 11.973871502198485 3.4206509716759186 +12 1 -1 -10.201559985782705 7.557482594092384 12.07004973873643 +13 1 -1 4.898458045226889 2.0169997859717945 -20.765285372762087 +14 1 -1 -24.086606883730077 4.424991619615298 -4.204294764756856 +15 1 -1 3.6837161829600795 -4.763233144818308 -12.75873457519811 +16 1 -1 -12.217842496816345 -17.720229208905618 -13.556354139556914 +17 1 -1 -21.456229140133704 -7.423996317612119 -6.94398044071275 +18 1 -1 13.697298849253912 8.503639732052164 8.085487457359058 +19 1 -1 -5.764222710061347 11.49890485049034 -5.1113880296575935 +20 1 -1 3.9944161041544426 16.928204188257893 -14.875635895409372 +21 1 -1 4.509525276444776 16.63590711792657 -22.21846494992397 +22 1 -1 22.115374932704306 -18.97293932558108 -23.982486000144267 +23 1 -1 14.169061011408473 -16.69837647199978 13.779039228068108 +24 1 -1 17.186846147657228 8.827459489898189 23.055435051390333 +25 1 -1 2.9822901981431045 -16.83687718528342 -21.278623587083484 +26 1 -1 16.657554689423897 -1.6217275605348647 -11.315859420404218 +27 1 -1 19.215533149393543 -15.512634977936068 7.2701088767584565 +28 1 -1 -8.886744157248422 -24.09644410100167 4.013016013803799 +29 1 -1 20.99918340066754 4.4716257356730225 0.3847245765737597 +30 1 -1 1.3442294253060716 5.601341425720583 -14.918594492786674 +31 1 -1 -6.962977050326831 20.470183675946515 -16.37885865567279 +32 1 -1 -9.98531733187143 9.52233798117566 -24.979630708193724 +33 1 -1 -17.327989778292306 5.761352103841766 5.720220488689204 +34 1 -1 5.168359673466362 -23.698812306679418 2.6199762372169744 +35 1 -1 18.978042448492154 6.41188742965139 6.31975357155018 +36 1 -1 -16.38534911663758 -14.8262205163943 4.125239045887575 +37 1 -1 7.974455406459249 -18.88332583451115 11.00721254217055 +38 1 -1 13.779816416416402 1.8581999350851426 9.104219696003227 +39 1 -1 -23.90949397031401 -3.346877828308571 -10.228782973473443 +40 1 -1 21.61647622174447 8.443955423089903 -19.12066464239769 +41 1 -1 -8.823979405515548 14.461154001848172 16.061704411241706 +42 1 -1 -2.4406878944912513 12.5535360118296 20.606764200087852 +43 1 -1 -18.459404356124697 15.260951448001258 21.187332685021346 +44 1 -1 2.2354003384439878 -23.350013178190736 11.369307324043625 +45 1 -1 15.595889705552018 -6.6075680254604805 5.434256329408505 +46 1 -1 -17.528243443870238 4.109747707896265 -1.4167331089310942 +47 1 -1 2.161977144405782 -16.511059804921263 -12.186191310598671 +48 1 -1 -8.685671837367341 -7.0743613044263185 -1.1561844713769105 +49 1 -1 15.62258718398045 -6.559293763708908 20.556775995508488 +50 1 -1 -6.965207014475155 -14.348784897390543 -14.421447863144754 +51 1 -1 -12.099361509567913 -24.62785640990423 -15.839126670614329 +52 1 -1 6.673854222058246 7.83575773885061 -9.714128155619994 +53 1 -1 -17.413453800948826 12.386754276446203 -16.882300786608994 +54 1 -1 21.8966589175091 12.485943283688762 -14.553421680298634 +55 1 -1 -8.37629917390651 -24.783875012947064 7.454467809536389 +56 1 -1 14.081149297694104 -21.719204113108943 -17.447225564400064 +57 1 -1 4.681992702049627 1.9719544892622558 -7.823736613205725 +58 1 -1 4.353171917533494 15.86928389762705 24.669680272563014 +59 1 -1 23.31502072066573 -4.685724298328946 2.459643890128799 +60 1 -1 7.0470920520598455 23.016693234922386 -13.139471333592677 +61 1 -1 11.725555941181668 -15.809323171320772 -1.6292879532275037 +62 1 -1 -20.36388898925061 -12.084932320023162 -22.816700826388757 +63 1 -1 -2.492146614764735 -0.7314052253623018 -15.89959178250266 +64 1 -1 -22.45303825831233 -11.27996814407809 -9.553770912146142 +65 1 -1 24.76771926037101 20.128947543233757 10.528974830883733 +66 1 -1 11.326213670190818 -11.624187194192492 -9.687726413467862 +67 1 -1 -5.712764220166093 15.778887306376163 -0.9263244618113831 +68 1 -1 -15.073201136996362 -12.372916148178115 -5.461704510273556 +69 1 -1 -5.82976670348781 -4.57812040989473 9.0443548565365 +70 1 -1 -5.429195387856279 1.4542054472230177 -7.397291151203568 +71 1 -1 -23.385555726942343 -11.924588975396505 3.8215294321466153 +72 1 -1 -1.0694104826815725 2.999945633116507 3.67092922106918 +73 1 -1 12.134312161994352 1.9747455475585376 -14.895893366599623 +74 1 -1 21.30950120583112 18.97294626436546 -17.520867878211376 +75 1 -1 -24.356703356157063 3.594879254976714 17.172993705171677 +76 1 -1 12.634233603338409 24.373499564220822 4.561976273909789 +77 1 -1 -10.740243207970495 19.345205140729554 -3.3368424800818097 +78 1 -1 -3.027848793907552 10.604939843027267 7.493012332728249 +79 1 -1 5.000539296336658 11.770088203844622 17.227492055930185 +80 1 -1 1.1585200269400353 -24.45822157176123 -12.515688997756257 +81 1 -1 1.9163088584430596 -14.064330279670672 11.302445490552905 +82 1 -1 -20.857041355570576 21.292791787236673 17.397470691573346 +83 1 -1 -24.50473305235651 -12.741459355708756 -1.9325218065560357 +84 1 -1 2.658628688373309 -1.1131226252194608 7.491603553398086 +85 1 -1 -18.515435126408363 24.20642384141299 14.466889392835121 +86 1 -1 19.63928177206153 9.942655640416291 8.691463646789934 +87 1 -1 -7.69626451160762 11.762517043363786 -7.457263991495665 +88 1 -1 1.051431093064835 -11.460307039827766 16.90304637479744 +89 1 -1 0.9157815447227939 23.656751182559688 -6.538587603918376 +90 1 -1 23.330169435555234 -7.293893221439802 -10.739388379883973 +91 1 -1 1.3454906653067376 0.3584300740797559 8.837879234629618 +92 1 -1 -21.93056639286312 -10.890279576013356 -10.412914392053596 +93 1 -1 21.9136101677979 -10.780221720642636 11.543925933359859 +94 1 -1 1.213289938136601 -7.171863230861625 20.734527885288102 +95 1 -1 23.102370131877777 21.949933206350458 0.29281565885028016 +96 1 -1 -18.917780884063298 -0.03244735062602544 23.633906995676227 +97 1 -1 7.583004866601307 10.74178675512821 -4.857297835527785 +98 1 -1 -7.4910066746799835 -14.168364618485734 -6.426540836249767 +99 1 -1 -20.672200987670426 -8.746789722660697 11.011389790610103 +100 1 -1 -18.662115132221917 -21.356740361991612 -8.735991534410413 +101 2 1 11.900973676882046 6.591531431964558 19.018193594877637 +102 2 1 -23.433591822114983 -18.956429005519567 4.8373984358422994 +103 2 1 -11.825475204099472 -3.8206287568445134 3.1167558949026173 +104 2 1 -17.49780467176259 -23.115560141825554 9.614132296727426 +105 2 1 10.88916113281772 4.512200980010334 18.685489050240854 +106 2 1 -22.04662313800728 23.973268925992897 -23.417792740205652 +107 2 1 -13.57041123540546 17.3687874050987 21.186270978357783 +108 2 1 6.586851196789095 16.27860887432974 -3.638909639278946 +109 2 1 8.191448685630277 6.828880619305412 -6.347576950950089 +110 2 1 -15.723292856220288 -20.484673256634117 -15.14713811293425 +111 2 1 18.58081219522701 19.060706710849452 -10.295676869062909 +112 2 1 -21.09194001526127 -7.739334786748358 5.417635948058724 +113 2 1 -14.10404878784055 -15.769737592448523 -18.881834262561505 +114 2 1 -14.644589058195612 8.84169065013063 8.611654925486256 +115 2 1 -11.719050253933538 -4.9700119000832 -0.9846728956163453 +116 2 1 19.498247505274143 -10.418045613133986 -22.12098182226518 +117 2 1 21.857683401772697 20.157098661061575 -13.652393197742995 +118 2 1 -17.623414455798407 21.873813778550875 -6.533965802006303 +119 2 1 7.231785003326529 -13.925962842972222 5.360080190636602 +120 2 1 -7.509430039873415 19.13541714591672 -16.23545960168472 +121 2 1 -4.048249209544995 13.126195473202351 -7.156541250053138 +122 2 1 -20.26837137264583 21.46366988603839 15.603080527043964 +123 2 1 -4.478253524569759 -3.1812369811955783 -18.52918159641348 +124 2 1 21.541019047040052 13.514999235394065 -1.8086547561089752 +125 2 1 -15.223319907923727 -5.958117989814905 -7.194967640819577 +126 2 1 -20.87181173003304 -7.66780336209651 20.518235718821714 +127 2 1 -3.7444846073700297 21.014628245718292 7.197818215477007 +128 2 1 -5.904222844268787 7.656315546673127 -1.3911802017487425 +129 2 1 -21.49072414090769 -23.123923448235523 10.49453669763092 +130 2 1 24.90628307456096 7.081046671281136 -14.422530828641655 +131 2 1 -12.173002002514222 -23.250366655717176 -5.145802772598103 +132 2 1 -19.68809858318764 4.476541650697328 6.249229323733747 +133 2 1 16.85550827580734 -0.8462194407221624 18.011901711631936 +134 2 1 17.289399533444858 -11.99379336569853 11.875868193611936 +135 2 1 19.532020913911126 -23.053375288330326 -4.9162076250112605 +136 2 1 -12.432304028989998 5.029488375070969 7.535325299264009 +137 2 1 14.934807008644 8.086694342170496 19.68691014849572 +138 2 1 -7.088283921093918 -23.094109864922018 16.57088328184242 +139 2 1 14.77413976080318 21.343550134324772 13.996489344579572 +140 2 1 -14.606423208703657 -6.928316926567433 -22.717483260149475 +141 2 1 -17.139771555632173 14.533410346451518 -21.83064865887975 +142 2 1 4.261830086466784 15.518968841247663 -17.791505649414617 +143 2 1 -9.814793042774223 -5.120956154726329 14.054454130549104 +144 2 1 8.313311590434793 3.9666876022475606 -20.677101093823236 +145 2 1 10.603190079756637 -2.62347089527481 1.6661989541795634 +146 2 1 -17.763718339721695 1.2541370478041287 -21.55649971308305 +147 2 1 -8.538066365356812 14.81814356892842 -4.478673557614034 +148 2 1 -5.809558827384787 14.611789154829552 13.287687188309562 +149 2 1 8.986830839040898 -17.43898584267833 -18.08640526127862 +150 2 1 -13.315275244526854 8.890431200255954 -8.708179477452443 +151 2 1 -0.5407152591412618 -23.67970550599055 -24.1586910560046 +152 2 1 -19.79961109336906 -16.10906604558887 -5.879899717095562 +153 2 1 -23.626316306846658 9.337407355717588 -9.640842288307239 +154 2 1 -18.847256196659333 -16.303517291166603 -10.786416046984721 +155 2 1 13.567770091716845 -24.4927974402177 8.896906985984664 +156 2 1 13.652894892068794 -24.87567116574863 21.89026113439551 +157 2 1 -8.575912713332162 9.92386172372207 5.029537530028822 +158 2 1 20.69339436974964 1.129252448454178 0.3584458063532807 +159 2 1 -0.9971941518705947 18.317397852358788 6.795424830570379 +160 2 1 23.155704681402298 15.458725773368961 17.01599672991628 +161 2 1 22.278634187244123 14.642946508468171 20.543957651530896 +162 2 1 9.771629496835963 -21.696904301438853 -5.259678202922196 +163 2 1 5.253009955872763 17.911287158418148 15.769047957152992 +164 2 1 -20.759038961257414 5.59089552770853 -12.383953925685166 +165 2 1 3.2163819108147145 -4.948608591009169 -17.85036103684716 +166 2 1 20.637631925250837 9.109955226257064 6.177181979863878 +167 2 1 5.306344093540837 12.647347581939556 23.229957406774105 +168 2 1 -24.15187998806597 17.263903348029615 -17.141028077545826 +169 2 1 -15.705280442832997 -15.655358704303895 -10.488762557871972 +170 2 1 -6.601131108664461 -22.50322976595015 -5.672942609306119 +171 2 1 22.869179482568555 13.369592422303498 -9.378437532422556 +172 2 1 -23.151055417980903 -3.928919101213168 -11.117061489640207 +173 2 1 1.3592343286386246 -18.552063924235036 -15.346172149331993 +174 2 1 10.23567488314778 -18.14207926130103 -1.6884247085891886 +175 2 1 12.595888032974493 -1.7416169207452157 -21.786811832485718 +176 2 1 -0.14792438162408672 17.11748549051584 1.2788726677139053 +177 2 1 24.349235298880274 -8.664350854740949 12.4309854455257 +178 2 1 -18.827147816604253 -18.80258748867273 -1.6980553939283212 +179 2 1 -9.048793002383698 -1.788614428205263 -11.841289777017172 +180 2 1 -22.49667217853208 -22.112076711777533 10.01393503943838 +181 2 1 -16.183333848138453 1.3098533508906556 0.8096413611556166 +182 2 1 -4.007575369376703 -24.447854073342157 -19.683971619997376 +183 2 1 8.79123015290173 -15.890906503248287 -23.45721570121758 +184 2 1 -8.557898021171628 -21.985380426316674 22.626382729361595 +185 2 1 7.143974673263372 16.57516065778192 0.5907315164854055 +186 2 1 7.05280226857041 6.658154377550723 17.993436860997946 +187 2 1 20.98391844656716 -3.7711929542825544 -22.37222924252256 +188 2 1 -8.856382807041598 -16.421301042649826 -7.682473719905396 +189 2 1 -14.381919492441797 -7.667674808763277 -10.178028203828621 +190 2 1 -22.93472549116592 10.072854607637751 3.756868463885592 +191 2 1 9.458987867260412 17.23200182595278 -0.03503381482496337 +192 2 1 11.013603635791974 19.842184408029837 -5.83598462187852 +193 2 1 23.28897987479008 2.835578651649044 -20.512845011389647 +194 2 1 -18.86161127148128 8.956542530565656 14.193388541103026 +195 2 1 13.688477473034126 -15.973205475346514 10.952445409682397 +196 2 1 2.1058159557459497 2.740725960214597 -23.72037436968614 +197 2 1 20.982351847235442 7.072739454450108 -24.07322254392252 +198 2 1 5.962360707177609 -19.424513569281604 22.469955103109243 +199 2 1 -17.13607356062674 20.038457022813326 12.94227215395123 +200 2 1 11.592617137491743 22.283887092702138 2.339699650677858 +201 2 1 -1.3864952037065237 19.199632510575505 -7.684210221911414 +202 2 1 -22.44476570586083 -19.66385674506424 -8.981660607669522 +203 2 1 0.36547911522815824 -7.628556098996082 16.326944822668068 +204 2 1 -9.766164330974753 24.38435844399602 -14.352553497163 +205 2 1 -0.6310792726759544 -5.625399375968325 13.665993163571486 +206 2 1 2.6795300975636103 -0.37097710463575595 15.575183407667495 +207 2 1 10.68508361399715 24.638181487800373 -17.538711281692827 +208 2 1 18.30809729940504 18.39121662193474 18.285926328751984 +209 2 1 -11.52561870836783 -11.871004571782223 12.890674390475048 +210 3 -1 16.038097437687007 -0.8308290507120688 9.140710202344948 +211 3 -1 -12.071581865552927 23.77532123232212 -6.250109721970887 +212 3 -1 24.179073767023887 19.6390206210449 22.20321951706368 +213 3 -1 22.899159789805424 8.918385700451317 -1.1269016129923664 +214 3 -1 -10.48576153865241 5.691510884812594 21.955276995406933 +215 3 -1 6.272776670877239 10.035821052072265 22.22030412319301 +216 3 -1 14.689947575936934 -7.785907120217196 0.5033983092114553 +217 3 -1 23.173937996535116 -21.041572031861037 -21.057283440516468 +218 3 -1 -6.015120142466472 6.3962924962024985 21.58241945230285 +219 3 -1 -0.77667042466472 0.3962848125024985 1.582473830285 \ No newline at end of file diff --git a/examples/USER/misc/charge_regulation/data.chreg-acid-real b/examples/USER/misc/charge_regulation/data.chreg-acid-real new file mode 100644 index 0000000000..1f005a155b --- /dev/null +++ b/examples/USER/misc/charge_regulation/data.chreg-acid-real @@ -0,0 +1,235 @@ +LAMMPS data file generated by get_input.py + +219 atoms +3 atom types +-180 180 xlo xhi +-180 180 ylo yhi +-180 180 zlo zhi + +Masses + +1 20 +2 20 +3 20 + +Atoms + +1 1 0 18.70795854 -60.24998141 144.0092784 +2 1 -1 -130.9166548 -58.17450505 59.42690807 +3 1 -1 -125.5489258 58.46696329 77.38308245 +4 1 -1 46.8178314 -169.1807517 143.6272062 +5 1 -1 -162.2028908 -135.2407217 -129.3455357 +6 1 -1 -69.93717134 136.6009615 -140.3684699 +7 1 -1 -92.39022725 0.88313303 -156.091658 +8 1 -1 150.5452585 -15.59052452 3.326246397 +9 1 -1 171.8072626 172.9794849 75.84528386 +10 1 -1 -3.808294794 171.5056017 -19.13183671 +11 1 -1 68.90552852 86.21187482 24.628687 +12 1 -1 -73.4512319 54.41387468 86.90435812 +13 1 -1 35.26889793 14.52239846 -149.5100547 +14 1 -1 -173.4235696 31.85993966 -30.27092231 +15 1 -1 26.52275652 -34.29527864 -91.86288894 +16 1 -1 -87.96846598 -127.5856503 -97.6057498 +17 1 -1 -154.4848498 -53.45277349 -49.99665917 +18 1 -1 98.62055171 61.22620607 58.21550969 +19 1 -1 -41.50240351 82.79211492 -36.80199381 +20 1 -1 28.75979595 121.8830702 -107.1045784 +21 1 -1 32.46858199 119.7785312 -159.9729476 +22 1 -1 159.2306995 -136.6051631 -172.6738992 +23 1 -1 102.0172393 -120.2283106 99.20908244 +24 1 -1 123.7452923 63.55770833 165.9991324 +25 1 -1 21.47248943 -121.2255157 -153.2060898 +26 1 -1 119.9343938 -11.67643844 -81.47418783 +27 1 -1 138.3518387 -111.6909718 52.34478391 +28 1 -1 -63.98455793 -173.4943975 28.8937153 +29 1 -1 151.1941205 32.1957053 2.770016951 +30 1 -1 9.678451862 40.32965827 -107.4138803 +31 1 -1 -50.13343476 147.3853225 -117.9277823 +32 1 -1 -71.89428479 68.56083346 -179.8533411 +33 1 -1 -124.7615264 41.48173515 41.18558752 +34 1 -1 37.21218965 -170.6314486 18.86382891 +35 1 -1 136.6419056 46.16558949 45.50222572 +36 1 -1 -117.9745136 -106.7487877 29.70172113 +37 1 -1 57.41607893 -135.959946 79.2519303 +38 1 -1 99.2146782 13.37903953 65.55038181 +39 1 -1 -172.1483566 -24.09752036 -73.64723741 +40 1 -1 155.6386288 60.79647905 -137.6687854 +41 1 -1 -63.53265172 104.1203088 115.6442718 +42 1 -1 -17.57295284 90.38545929 148.3687022 +43 1 -1 -132.9077114 109.8788504 152.5487953 +44 1 -1 16.09488244 -168.1200949 81.85901273 +45 1 -1 112.2904059 -47.57448978 39.12664557 +46 1 -1 -126.2033528 29.5901835 -10.20047838 +47 1 -1 15.56623544 -118.8796306 -87.74057744 +48 1 -1 -62.53683723 -50.93540139 -8.324528194 +49 1 -1 112.4826277 -47.2269151 148.0087872 +50 1 -1 -50.1494905 -103.3112513 -103.8344246 +51 1 -1 -87.11540287 -177.3205662 -114.041712 +52 1 -1 48.0517504 56.41745572 -69.94172272 +53 1 -1 -125.3768674 89.18463079 -121.5525657 +54 1 -1 157.6559442 89.89879164 -104.7846361 +55 1 -1 -60.30935405 -178.4439001 53.67216823 +56 1 -1 101.3842749 -156.3782696 -125.6200241 +57 1 -1 33.71034745 14.19807232 -56.33090362 +58 1 -1 31.34283781 114.2588441 177.621698 +59 1 -1 167.8681492 -33.73721495 17.70943601 +60 1 -1 50.73906277 165.7201913 -94.6041936 +61 1 -1 84.42400278 -113.8271268 -11.73087326 +62 1 -1 -146.6200007 -87.0115127 -164.2802459 +63 1 -1 -17.94345563 -5.266117623 -114.4770608 +64 1 -1 -161.6618755 -81.21577064 -68.78715057 +65 1 -1 178.3275787 144.9284223 75.80861878 +66 1 -1 81.54873843 -83.6941478 -69.75163018 +67 1 -1 -41.13190239 113.6079886 -6.669536125 +68 1 -1 -108.5270482 -89.08499627 -39.32427247 +69 1 -1 -41.97432027 -32.96246695 65.11935497 +70 1 -1 -39.09020679 10.47027922 -53.26049629 +71 1 -1 -168.3760012 -85.85704062 27.51501191 +72 1 -1 -7.699755475 21.59960856 26.43069039 +73 1 -1 87.36704757 14.21816794 -107.2504322 +74 1 -1 153.4284087 136.6052131 -126.1502487 +75 1 -1 -175.3682642 25.88313064 123.6455547 +76 1 -1 90.96648194 175.4891969 32.84622917 +77 1 -1 -77.3297511 139.285477 -24.02526586 +78 1 -1 -21.80051132 76.35556687 53.9496888 +79 1 -1 36.00388293 84.74463507 124.0379428 +80 1 -1 8.341344194 -176.0991953 -90.11296078 +81 1 -1 13.79742378 -101.263178 81.37760753 +82 1 -1 -150.1706978 153.3081009 125.261789 +83 1 -1 -176.434078 -91.73850736 -13.91415701 +84 1 -1 19.14212656 -8.014482902 53.93954558 +85 1 -1 -133.3111329 174.2862517 104.1616036 +86 1 -1 141.4028288 71.58712061 62.57853826 +87 1 -1 -55.41310448 84.69012271 -53.69230074 +88 1 -1 7.57030387 -82.51421069 121.7019339 +89 1 -1 6.593627122 170.3286085 -47.07783075 +90 1 -1 167.9772199 -52.51603119 -77.32359634 +91 1 -1 9.68753279 2.580696533 63.63273049 +92 1 -1 -157.900078 -78.41001295 -74.97298362 +93 1 -1 157.7779932 -77.61759639 83.11626672 +94 1 -1 8.735687555 -51.63741526 149.2886008 +95 1 -1 166.3370649 158.0395191 2.108272744 +96 1 -1 -136.2080224 -0.233620925 170.1641304 +97 1 -1 54.59763504 77.34086464 -34.97254442 +98 1 -1 -53.93524806 -102.0122253 -46.27109402 +99 1 -1 -148.8398471 -62.976886 79.28200649 +100 1 -1 -134.367229 -153.7685306 -62.89913905 +101 2 1 85.68701047 47.45902631 136.9309939 +102 2 1 -168.7218611 -136.4862888 34.82926874 +103 2 1 -85.14342147 -27.50852705 22.44064244 +104 2 1 -125.9841936 -166.432033 69.22175254 +105 2 1 78.40196016 32.48784706 134.5355212 +106 2 1 -158.7356866 172.6075363 -168.6081077 +107 2 1 -97.70696089 125.0552693 152.541151 +108 2 1 47.42532862 117.2059839 -26.2001494 +109 2 1 58.97843054 49.16794046 -45.70255405 +110 2 1 -113.2077086 -147.4896474 -109.0593944 +111 2 1 133.7818478 137.2370883 -74.12887346 +112 2 1 -151.8619681 -55.72321046 39.00697883 +113 2 1 -101.5491513 -113.5421107 -135.9492067 +114 2 1 -105.4410412 63.66017268 62.00391546 +115 2 1 -84.37716183 -35.78408568 -7.089644848 +116 2 1 140.387382 -75.00992841 -159.2710691 +117 2 1 157.3753205 145.1311104 -98.29723102 +118 2 1 -126.8885841 157.4914592 -47.04455377 +119 2 1 52.06885202 -100.2669325 38.59257737 +120 2 1 -54.06789629 137.7750035 -116.8953091 +121 2 1 -29.14739431 94.50860741 -51.527097 +122 2 1 -145.9322739 154.5384232 112.3421798 +123 2 1 -32.24342538 -22.90490626 -133.4101075 +124 2 1 155.0953371 97.30799449 -13.02231424 +125 2 1 -109.6079033 -42.89844953 -51.80376701 +126 2 1 -150.2770445 -55.20818421 147.7312972 +127 2 1 -26.96028917 151.3053234 51.82429115 +128 2 1 -42.51040448 55.12547194 -10.01649745 +129 2 1 -154.7332138 -166.4922488 75.56066422 +130 2 1 179.3252381 50.98353603 -103.842222 +131 2 1 -87.64561442 -167.4026399 -37.04977996 +132 2 1 -141.7543098 32.23109989 44.99445113 +133 2 1 121.3596596 -6.092779973 129.6856923 +134 2 1 124.4836766 -86.35531223 85.50625099 +135 2 1 140.6305506 -165.9843021 -35.3966949 +136 2 1 -89.51258901 36.2123163 54.25434215 +137 2 1 107.5306105 58.22419926 141.7457531 +138 2 1 -51.03564423 -166.277591 119.3103596 +139 2 1 106.3738063 153.673561 100.7747233 +140 2 1 -105.1662471 -49.88388187 -163.5658795 +141 2 1 -123.4063552 104.6405545 -157.1806703 +142 2 1 30.68517662 111.7365757 -128.0988407 +143 2 1 -70.66650991 -36.87088431 101.1920697 +144 2 1 59.85584345 28.56015074 -148.8751279 +145 2 1 76.34296857 -18.88899045 11.99663247 +146 2 1 -127.898772 9.029786744 -155.2067979 +147 2 1 -61.47407783 106.6906337 -32.24644961 +148 2 1 -41.82882356 105.2048819 95.67134776 +149 2 1 64.70518204 -125.5606981 -130.2221179 +150 2 1 -95.86998176 64.01110464 -62.69889224 +151 2 1 -3.893149866 -170.4938796 -173.9425756 +152 2 1 -142.5571999 -115.9852755 -42.33527796 +153 2 1 -170.1094774 67.22933296 -69.41406448 +154 2 1 -135.7002446 -117.3853245 -77.66219554 +155 2 1 97.68794466 -176.3481416 64.0577303 +156 2 1 98.30084322 -179.1048324 157.6098802 +157 2 1 -61.74657154 71.45180441 36.21267022 +158 2 1 148.9924395 8.130617629 2.580809806 +159 2 1 -7.179797893 131.8852645 48.92705878 +160 2 1 166.7210737 111.3028256 122.5151765 +161 2 1 160.4061661 105.4292149 147.9164951 +162 2 1 70.35573238 -156.217711 -37.86968306 +163 2 1 37.82167168 128.9612675 113.5371453 +164 2 1 -149.4650805 40.2544478 -89.16446826 +165 2 1 23.15794976 -35.62998186 -128.5225995 +166 2 1 148.5909499 65.59167763 44.47571026 +167 2 1 38.20567747 91.06090259 167.2556933 +168 2 1 -173.8935359 124.3001041 -123.4154022 +169 2 1 -113.0780192 -112.7185827 -75.51909042 +170 2 1 -47.52814398 -162.0232543 -40.84518679 +171 2 1 164.6580923 96.26106544 -67.52475023 +172 2 1 -166.687599 -28.28821753 -80.04284273 +173 2 1 9.786487166 -133.5748603 -110.4924395 +174 2 1 73.69685916 -130.6229707 -12.1566579 +175 2 1 90.69039384 -12.53964183 -156.8650452 +176 2 1 -1.065055548 123.2458955 9.207883208 +177 2 1 175.3144942 -62.38332615 89.50309521 +178 2 1 -135.5554643 -135.3786299 -12.22599884 +179 2 1 -65.15130962 -12.87802388 -85.25728639 +180 2 1 -161.9760397 -159.2069523 72.10033228 +181 2 1 -116.5200037 9.430944126 5.8294178 +182 2 1 -28.85454266 -176.0245493 -141.7245957 +183 2 1 63.2968571 -114.4145268 -168.891953 +184 2 1 -61.61686575 -158.2947391 162.9099557 +185 2 1 51.43661765 119.3411567 4.253266919 +186 2 1 50.78017633 47.93871152 129.5527454 +187 2 1 151.0842128 -27.15258927 -161.0800505 +188 2 1 -63.76595621 -118.2333675 -55.31381078 +189 2 1 -103.5498203 -55.20725862 -73.28180307 +190 2 1 -165.1300235 72.52455317 27.04945294 +191 2 1 68.10471264 124.0704131 -0.252243467 +192 2 1 79.29794618 142.8637277 -42.01908928 +193 2 1 167.6806551 20.41616629 -147.6924841 +194 2 1 -135.8036012 64.48710622 102.1923975 +195 2 1 98.55703781 -115.0070794 78.85760695 +196 2 1 15.16187488 19.73322691 -170.7866955 +197 2 1 151.0729333 50.92372407 -173.3272023 +198 2 1 42.92899709 -139.8564977 161.7836767 +199 2 1 -123.3797296 144.2768906 93.18435951 +200 2 1 83.46684339 160.4439871 16.84583748 +201 2 1 -9.982765467 138.2373541 -55.3263136 +202 2 1 -161.6023131 -141.5797686 -64.66795638 +203 2 1 2.63144963 -54.92560391 117.5540027 +204 2 1 -70.31638318 175.5673808 -103.3383852 +205 2 1 -4.543770763 -40.50287551 98.39515078 +206 2 1 19.2926167 -2.671035153 112.1413205 +207 2 1 76.93260202 177.3949067 -126.2787212 +208 2 1 131.8183006 132.4167597 131.6586696 +209 2 1 -82.9844547 -85.47123292 92.81285561 +210 3 -1 115.4743016 -5.981969165 65.81311346 +211 3 -1 -86.91538943 171.1823129 -45.00079 +212 3 -1 174.0893311 141.4009485 159.8631805 +213 3 -1 164.8739505 64.21237704 -8.113691614 +214 3 -1 -75.49748308 40.97887837 158.0779944 +215 3 -1 45.16399203 72.25791157 159.9861897 +216 3 -1 105.7676225 -56.05853127 3.624467826 +217 3 -1 166.8523536 -151.4993186 -151.6124408 +218 3 -1 -43.30886503 46.05330597 155.3934201 +219 3 -1 -5.592027058 2.85325065 11.39381158 \ No newline at end of file diff --git a/examples/USER/misc/charge_regulation/data.chreg-polymer b/examples/USER/misc/charge_regulation/data.chreg-polymer new file mode 100644 index 0000000000..2c5bd3e1ed --- /dev/null +++ b/examples/USER/misc/charge_regulation/data.chreg-polymer @@ -0,0 +1,264 @@ +##A Weak PE Chain of N=80 + +160 atoms +79 bonds + +5 atom types +1 bond types + +-50 50 xlo xhi +-50 50 ylo yhi +-50 50 zlo zhi + +Masses + +1 1.0 +2 1.0 +3 1.0 +4 1.0 +5 1.0 + +Atoms +# atom_id molecule_id atom_type charge x y z +1 1 1 -1 0 0 -48.37753795169063 +2 1 1 -1 0 0 -47.255075903381254 +3 1 1 -1 0 0 -46.13261385507188 +4 1 1 -1 0 0 -45.01015180676251 +5 1 1 -1 0 0 -43.887689758453135 +6 1 1 -1 0 0 -42.76522771014376 +7 1 1 -1 0 0 -41.64276566183439 +8 1 1 -1 0 0 -40.520303613525016 +9 1 1 -1 0 0 -39.39784156521564 +10 1 1 -1 0 0 -38.27537951690627 +11 1 1 -1 0 0 -37.1529174685969 +12 1 1 -1 0 0 -36.030455420287524 +13 1 1 -1 0 0 -34.90799337197815 +14 1 1 -1 0 0 -33.78553132366878 +15 1 1 -1 0 0 -32.663069275359405 +16 1 1 -1 0 0 -31.54060722705003 +17 1 1 -1 0 0 -30.41814517874066 +18 1 1 -1 0 0 -29.295683130431286 +19 1 1 -1 0 0 -28.173221082121913 +20 1 1 -1 0 0 -27.05075903381254 +21 1 1 -1 0 0 -25.928296985503167 +22 1 1 -1 0 0 -24.805834937193794 +23 1 1 -1 0 0 -23.68337288888442 +24 1 1 -1 0 0 -22.560910840575048 +25 1 1 -1 0 0 -21.438448792265675 +26 1 1 -1 0 0 -20.3159867439563 +27 1 1 -1 0 0 -19.19352469564693 +28 1 1 -1 0 0 -18.071062647337556 +29 1 1 -1 0 0 -16.948600599028183 +30 1 1 -1 0 0 -15.82613855071881 +31 1 1 -1 0 0 -14.703676502409436 +32 1 1 -1 0 0 -13.581214454100063 +33 1 1 -1 0 0 -12.45875240579069 +34 1 1 -1 0 0 -11.336290357481317 +35 1 1 -1 0 0 -10.213828309171944 +36 1 1 -1 0 0 -9.091366260862571 +37 1 1 -1 0 0 -7.968904212553198 +38 1 1 -1 0 0 -6.846442164243825 +39 1 1 -1 0 0 -5.723980115934452 +40 1 1 -1 0 0 -4.601518067625079 +41 1 1 -1 0 0 -3.4790560193157063 +42 1 1 -1 0 0 -2.3565939710063333 +43 1 1 -1 0 0 -1.2341319226969603 +44 1 1 -1 0 0 -0.11166987438758724 +45 1 1 -1 0 0 1.0107921739217858 +46 1 1 -1 0 0 2.133254222231159 +47 1 1 -1 0 0 3.255716270540532 +48 1 1 -1 0 0 4.378178318849905 +49 1 1 -1 0 0 5.500640367159278 +50 1 1 -1 0 0 6.623102415468651 +51 1 1 -1 0 0 7.745564463778024 +52 1 1 -1 0 0 8.868026512087397 +53 1 1 -1 0 0 9.99048856039677 +54 1 1 -1 0 0 11.112950608706143 +55 1 1 -1 0 0 12.235412657015516 +56 1 1 -1 0 0 13.357874705324889 +57 1 1 -1 0 0 14.480336753634262 +58 1 1 -1 0 0 15.602798801943635 +59 1 1 -1 0 0 16.725260850253008 +60 1 1 -1 0 0 17.84772289856238 +61 1 1 -1 0 0 18.970184946871754 +62 1 1 -1 0 0 20.092646995181127 +63 1 1 -1 0 0 21.2151090434905 +64 1 1 -1 0 0 22.337571091799873 +65 1 1 -1 0 0 23.460033140109246 +66 1 1 -1 0 0 24.58249518841862 +67 1 1 -1 0 0 25.704957236727992 +68 1 1 -1 0 0 26.827419285037365 +69 1 1 -1 0 0 27.949881333346738 +70 1 1 -1 0 0 29.07234338165611 +71 1 1 -1 0 0 30.194805429965484 +72 1 1 -1 0 0 31.317267478274857 +73 1 1 -1 0 0 32.43972952658423 +74 1 1 -1 0 0 33.5621915748936 +75 1 1 -1 0 0 34.684653623202976 +76 1 1 -1 0 0 35.80711567151235 +77 1 1 -1 0 0 36.92957771982172 +78 1 1 -1 0 0 38.052039768131095 +79 1 1 -1 0 0 39.17450181644047 +80 1 1 -1 0 0 40.29696386474984 +81 0 2 1 -27.886422274724097 27.72001798427955 38.68169635811057 +82 0 2 1 29.812255760623188 17.871838747003693 -29.094648426460257 +83 0 2 1 -13.23881351410531 13.28123966828678 -24.422176415560116 +84 0 2 1 4.9465650593939685 -37.7521903558826 -15.115417767729575 +85 0 2 1 34.82527943387106 29.457664434004897 -25.565595338061254 +86 0 2 1 46.35660570786446 -7.161776614070412 -20.2471250527001 +87 0 2 1 39.20854546781531 34.96815569014278 13.893531822586723 +88 0 2 1 -7.797240698180197 0.07861219105048889 48.686453603015224 +89 0 2 1 43.92391845355516 -39.42362941705827 22.448930565867585 +90 0 2 1 -40.371744364329984 -17.743039071967246 -15.08153047835009 +91 0 2 1 -21.573165497710058 -0.5844447399891948 -45.73596994149077 +92 0 2 1 -19.882394451769102 -7.392447895357577 30.733607063808876 +93 0 2 1 -17.393031309514107 26.882975097407467 -47.64059480000892 +94 0 2 1 25.652222561671735 1.0229206994719107 -14.959030208952043 +95 0 2 1 26.075045766879313 19.902341017250052 46.70284805469666 +96 0 2 1 39.91980369168496 0.753749460187592 -26.203575929573407 +97 0 2 1 13.777613371273958 7.112171629839359 -33.5270487721399 +98 0 2 1 18.944534687271826 20.090215089875286 -34.381335468790574 +99 0 2 1 -23.801856387842435 -42.275962146864586 -8.322936238250279 +100 0 2 1 -31.386991395893826 29.83894468611787 8.937114269513422 +101 0 2 1 -41.07090001085809 49.59339931450579 6.666864232174753 +102 0 2 1 -46.58911504232167 -32.46068937927039 19.40424197066872 +103 0 2 1 -39.94659416571965 -36.28203465180086 5.841020764632312 +104 0 2 1 -26.027467090120137 -41.05522015175137 -1.1145958296128313 +105 0 2 1 37.09602855959457 23.76087951027276 45.09142423198867 +106 0 2 1 -27.78138413517528 -48.97344929918942 45.91491289356401 +107 0 2 1 4.468912883622387 -5.217782298407556 6.381420595433383 +108 0 2 1 36.758686966564525 48.425582881586166 -25.909273336802997 +109 0 2 1 -27.045102667146036 -19.713951008254117 4.339232870380627 +110 0 2 1 -5.984280016624311 -49.45311479123866 36.35727783065221 +111 0 2 1 27.833389147163018 -47.80144978082761 -47.71458334276804 +112 0 2 1 -23.628507668044364 -30.353876765128685 36.174277933133254 +113 0 2 1 -40.93360714431151 40.1336490864843 -27.035347797435495 +114 0 2 1 6.3523980881104976 -28.636485436097082 -10.671354350535445 +115 0 2 1 42.765716958607086 -32.85779663523676 -1.9682360265562124 +116 0 2 1 -33.68069757415453 16.800769050458484 -6.273374390373085 +117 0 2 1 13.909148568042937 4.921040289518388 12.111069913598996 +118 0 2 1 6.728324076730296 -48.44092815223126 -35.92436883370601 +119 0 2 1 -18.121173967321912 -15.76903395165283 2.2495451015454933 +120 0 2 1 -11.75253233489407 -45.82569982175387 -12.477142440015896 +121 0 2 1 1.9713864197144133 17.961034900064007 32.97992150691711 +122 0 2 1 -3.993384770632943 -47.63120435620297 27.75490859098018 +123 0 2 1 -0.32208279553454844 -47.30616152402566 -22.751109302380367 +124 0 2 1 -0.135777029397957 23.88599790464609 -31.87440560354473 +125 0 2 1 -6.123924906817393 -2.038519565120424 45.4809181974626 +126 0 2 1 -29.622588299895046 42.40404115712096 6.640479709229595 +127 0 2 1 -11.694512971272673 19.983258641775762 -38.152427411711145 +128 0 2 1 -20.93721440637313 39.46397829322392 -45.52708262202337 +129 0 2 1 34.13340147809369 36.14268504987945 -23.978137043267044 +130 0 2 1 -37.422309952611485 29.181841318883087 27.55677757161692 +131 0 2 1 30.11314373799594 18.721794400471353 1.5553303682670574 +132 0 2 1 -7.3563467211571805 46.84253369205935 -39.84708490437832 +133 0 2 1 -3.695927445484358 2.494403998274727 -7.634369981832755 +134 0 2 1 44.09701173592077 17.717328437831043 31.54108326477207 +135 0 2 1 48.070189931616795 10.601166369398662 -28.28574863896286 +136 0 2 1 -7.044858382811761 -42.080663380241766 -1.4369925734636553 +137 0 2 1 -12.485032488076918 23.87106169116919 6.178803347562642 +138 0 2 1 -15.613232443702309 10.103630885941392 -20.447182948810916 +139 0 2 1 28.610332347774147 37.08335835592116 -19.90280831362493 +140 0 2 1 25.853920233242505 -27.768648181803655 24.971357611943475 +141 0 2 1 9.256159541363296 -23.562096053197934 -4.722701100419371 +142 0 2 1 39.96929397877305 -11.88228547846326 -28.70638149104603 +143 0 2 1 -37.98545134633291 -23.50528193202669 -10.939982626098441 +144 0 2 1 25.40017763114089 -47.49220127581256 15.1783064865064 +145 0 2 1 28.073596076651768 3.6631266774864386 31.54355751177208 +146 0 2 1 -19.596457173068703 46.79824882013442 -12.302655772327597 +147 0 2 1 -36.46192411958321 -2.785830672302666 -25.1901381125736 +148 0 2 1 -27.377389198969894 11.295792272951147 39.32842550184691 +149 0 2 1 32.24967019136358 -20.517755791016402 31.20590722085157 +150 0 2 1 47.70698618147787 9.75462874031868 -28.267447889542563 +151 0 2 1 17.157803106328345 -27.48141290657965 7.7670687016760525 +152 0 2 1 15.089833959419678 5.342811012118396 27.35336620165029 +153 0 2 1 9.836963929211372 -11.047378229392443 -20.960811370690678 +154 0 2 1 44.66600586278604 14.949733274456321 -29.328965994323575 +155 0 2 1 -21.006260382140685 8.492712712433658 -46.31580169190271 +156 0 2 1 -29.970979487850748 -36.46250489415931 26.914372830947457 +157 0 2 1 -1.0821372755756329 -8.453379951300242 -19.95665062432509 +158 0 2 1 -24.033653425909772 -39.51330620205049 20.067656167683793 +159 0 2 1 27.747287624384626 -21.904990435351312 -10.819345241055956 +160 0 2 1 -40.86737066410612 -25.609300376714796 -21.128139356809783 + +Bonds + # bond_id bond_type atom1_id atom2_id +1 1 1 2 +2 1 2 3 +3 1 3 4 +4 1 4 5 +5 1 5 6 +6 1 6 7 +7 1 7 8 +8 1 8 9 +9 1 9 10 +10 1 10 11 +11 1 11 12 +12 1 12 13 +13 1 13 14 +14 1 14 15 +15 1 15 16 +16 1 16 17 +17 1 17 18 +18 1 18 19 +19 1 19 20 +20 1 20 21 +21 1 21 22 +22 1 22 23 +23 1 23 24 +24 1 24 25 +25 1 25 26 +26 1 26 27 +27 1 27 28 +28 1 28 29 +29 1 29 30 +30 1 30 31 +31 1 31 32 +32 1 32 33 +33 1 33 34 +34 1 34 35 +35 1 35 36 +36 1 36 37 +37 1 37 38 +38 1 38 39 +39 1 39 40 +40 1 40 41 +41 1 41 42 +42 1 42 43 +43 1 43 44 +44 1 44 45 +45 1 45 46 +46 1 46 47 +47 1 47 48 +48 1 48 49 +49 1 49 50 +50 1 50 51 +51 1 51 52 +52 1 52 53 +53 1 53 54 +54 1 54 55 +55 1 55 56 +56 1 56 57 +57 1 57 58 +58 1 58 59 +59 1 59 60 +60 1 60 61 +61 1 61 62 +62 1 62 63 +63 1 63 64 +64 1 64 65 +65 1 65 66 +66 1 66 67 +67 1 67 68 +68 1 68 69 +69 1 69 70 +70 1 70 71 +71 1 71 72 +72 1 72 73 +73 1 73 74 +74 1 74 75 +75 1 75 76 +76 1 76 77 +77 1 77 78 +78 1 78 79 +79 1 79 80 diff --git a/examples/USER/misc/charge_regulation/in.chreg-acid b/examples/USER/misc/charge_regulation/in.chreg-acid new file mode 100644 index 0000000000..68ef5e1b7c --- /dev/null +++ b/examples/USER/misc/charge_regulation/in.chreg-acid @@ -0,0 +1,36 @@ +# Charge regulation lammps for simple weak electrolyte + +units lj +atom_style charge +neighbor 3.0 bin +read_data data.chreg-acid + +variable cut_long equal 12.5 +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0) +variable lunit_nm equal 0.72 # in the units of nm +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_coeff * * 1.0 1.0 +kspace_style ewald 1.0e-3 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep 0.005 +run 2000 diff --git a/examples/USER/misc/charge_regulation/in.chreg-acid-real b/examples/USER/misc/charge_regulation/in.chreg-acid-real new file mode 100644 index 0000000000..d7225f33ea --- /dev/null +++ b/examples/USER/misc/charge_regulation/in.chreg-acid-real @@ -0,0 +1,44 @@ +# Charge regulation lammps for simple weak electrolyte + +units real +atom_style charge +neighbor 10.0 bin +read_data data.chreg-acid-real + +#real units +variable sigma equal 7.2 # particle diameter 0.72 nm +variable temperature equal 298 # temperature 298 K +variable kb index 0.0019872067 # kB in Kcal/mol/K +variable epsilon equal ${kb}*${temperature} +variable tunit equal 2000 # time unit is 2000 fs +variable timestep equal 0.005*${tunit} + +variable cut_long equal 12.5*${sigma} +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0)*${sigma} +velocity all create ${temperature} 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_coeff * * ${epsilon} ${sigma} +kspace_style pppm 1.0e-3 +dielectric 78 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin $(v_temperature) $(v_temperature) $(v_tunit) 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep ${timestep} +run 2000 diff --git a/examples/USER/misc/charge_regulation/in.chreg-polymer b/examples/USER/misc/charge_regulation/in.chreg-polymer new file mode 100644 index 0000000000..0adab9b5e7 --- /dev/null +++ b/examples/USER/misc/charge_regulation/in.chreg-polymer @@ -0,0 +1,33 @@ +# Charge regulation lammps for a polymer chain +units lj +atom_style full +neighbor 3.0 bin +read_data data.chreg-polymer + +bond_style harmonic +bond_coeff 1 100 1.122462 # K R0 +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long 1.122462 20 +pair_coeff * * 1.0 1.0 1.122462 # charges +kspace_style pppm 1.0e-3 +pair_modify shift yes +dielectric 1.0 + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg1 all charge/regulation 2 3 acid_type 1 pH 7.0 pKa 6.5 pIp 3.0 pIm 3.0 temp 1.0 nmc 40 seed 2345 +fix chareg2 all charge/regulation 4 5 acid_type 1 pH 7.0 pKa 6.5 pIp 7.0 pIm 7.0 temp 1.0 nmc 40 seed 2345 +fix chareg3 all charge/regulation 4 3 pIp 7.0 pIm 3.0 temp 1.0 nmc 20 seed 2345 + +thermo 100 +# print: step, potential energy, temperature, neutral acids, charged acids, salt cations, salt anions, H+ ions, OH- ions +thermo_style custom step pe c_dtemp f_chareg1[3] f_chareg1[4] f_chareg1[7] f_chareg1[8] f_chareg2[7] f_chareg2[8] + +timestep 0.005 +run 2000 diff --git a/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.1 b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.1 new file mode 100644 index 0000000000..627281217b --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.1 @@ -0,0 +1,125 @@ +LAMMPS (10 Feb 2021) + using 1 OpenMP thread(s) per MPI task +# Charge regulation lammps for simple weak electrolyte + +units lj +atom_style charge +neighbor 3.0 bin +read_data data.chreg-acid +Reading data file ... + orthogonal box = (-25.000000 -25.000000 -25.000000) to (25.000000 25.000000 25.000000) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 219 atoms + read_data CPU = 0.003 seconds + +variable cut_long equal 12.5 +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0) +variable lunit_nm equal 0.72 # in the units of nm +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_style lj/cut/coul/long 1.12246204830937 ${cut_long} +pair_style lj/cut/coul/long 1.12246204830937 12.5 +pair_coeff * * 1.0 1.0 +kspace_style ewald 1.0e-3 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery 100 nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery 100 nmc 100 seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep 0.005 +run 2000 +Ewald initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:339) + G vector (1/distance) = 0.14221027 + estimated absolute RMS force accuracy = 0.0010128126 + estimated relative force accuracy = 0.0010128126 + KSpace vectors: actual max1d max3d = 257 5 665 + kxmax kymax kzmax = 5 5 5 +0 atoms in group FixChargeRegulation:exclusion_group:chareg +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 15.5 + ghost atom cutoff = 15.5 + binsize = 7.75, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 11.91 | 11.91 | 11.91 Mbytes +Step PotEng c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] + 0 -0.049662059 1 0 0 1 99 0 0 109 10 + 100 -0.053672881 0.99159291 100 71 16 84 0 0 92 8 + 200 -0.053383027 0.90935145 200 156 26 74 0 0 85 11 + 300 -0.040471335 0.97937429 300 240 21 79 0 0 87 8 + 400 -0.036188123 1.0837424 400 319 14 86 0 0 92 6 + 500 -0.057294925 1.0507526 500 407 10 90 0 0 98 8 + 600 -0.056009748 1.0669354 600 487 15 85 0 0 92 7 + 700 -0.069686562 0.99202496 700 567 14 86 0 0 96 10 + 800 -0.054695624 1.0592933 800 647 25 75 0 0 82 7 + 900 -0.058693653 0.97870458 900 728 27 73 0 0 83 10 + 1000 -0.062352957 1.0008923 1000 805 24 76 0 0 84 8 + 1100 -0.065011926 0.91691048 1100 886 22 78 0 0 87 9 + 1200 -0.080463686 0.98879304 1200 963 23 77 0 0 88 11 + 1300 -0.062146141 1.0566033 1300 1047 21 79 0 0 88 9 + 1400 -0.046980246 1.0847512 1400 1129 17 83 0 0 94 11 + 1500 -0.042935292 1.0075805 1500 1203 24 76 0 0 86 10 + 1600 -0.056075891 0.94173489 1600 1277 23 77 0 0 90 13 + 1700 -0.042279161 1.1126317 1700 1355 28 72 0 0 82 10 + 1800 -0.036842528 1.0255327 1800 1436 24 76 0 0 83 7 + 1900 -0.038816022 0.93883373 1900 1511 23 77 0 0 86 9 + 2000 -0.047008287 0.98904085 2000 1592 26 74 0 0 81 7 +Loop time of 11.6365 on 1 procs for 2000 steps with 188 atoms + +Performance: 74249.079 tau/day, 171.873 timesteps/s +99.8% 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.24337 | 0.24337 | 0.24337 | 0.0 | 2.09 +Kspace | 4.6009 | 4.6009 | 4.6009 | 0.0 | 39.54 +Neigh | 0.023451 | 0.023451 | 0.023451 | 0.0 | 0.20 +Comm | 0.027729 | 0.027729 | 0.027729 | 0.0 | 0.24 +Output | 0.0007813 | 0.0007813 | 0.0007813 | 0.0 | 0.01 +Modify | 6.7345 | 6.7345 | 6.7345 | 0.0 | 57.87 +Other | | 0.005713 | | | 0.05 + +Nlocal: 188.000 ave 188 max 188 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 597.000 ave 597 max 597 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2196.00 ave 2196 max 2196 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2196 +Ave neighs/atom = 11.680851 +Neighbor list builds = 2059 +Dangerous builds = 0 +Total wall time: 0:00:11 diff --git a/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.4 b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.4 new file mode 100644 index 0000000000..465dcbdb4e --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.4 @@ -0,0 +1,125 @@ +LAMMPS (10 Feb 2021) + using 1 OpenMP thread(s) per MPI task +# Charge regulation lammps for simple weak electrolyte + +units lj +atom_style charge +neighbor 3.0 bin +read_data data.chreg-acid +Reading data file ... + orthogonal box = (-25.000000 -25.000000 -25.000000) to (25.000000 25.000000 25.000000) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 219 atoms + read_data CPU = 0.003 seconds + +variable cut_long equal 12.5 +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0) +variable lunit_nm equal 0.72 # in the units of nm +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_style lj/cut/coul/long 1.12246204830937 ${cut_long} +pair_style lj/cut/coul/long 1.12246204830937 12.5 +pair_coeff * * 1.0 1.0 +kspace_style ewald 1.0e-3 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp ${pIp} pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm ${pIm} lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm ${lunit_nm} nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery 100 nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.72 nevery 100 nmc 100 seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep 0.005 +run 2000 +Ewald initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:339) + G vector (1/distance) = 0.14221027 + estimated absolute RMS force accuracy = 0.0010128126 + estimated relative force accuracy = 0.0010128126 + KSpace vectors: actual max1d max3d = 257 5 665 + kxmax kymax kzmax = 5 5 5 +0 atoms in group FixChargeRegulation:exclusion_group:chareg +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 15.5 + ghost atom cutoff = 15.5 + binsize = 7.75, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 11.89 | 11.89 | 11.89 Mbytes +Step PotEng c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] + 0 -0.049662059 1 0 0 1 99 0 0 109 10 + 100 -0.06196414 1.0156327 100 72 15 85 0 0 93 8 + 200 -0.053901683 0.95128403 200 160 24 76 0 0 87 11 + 300 -0.043852423 0.98035058 300 246 22 78 0 0 85 7 + 400 -0.048370798 1.0909844 400 324 16 84 0 0 91 7 + 500 -0.042546472 1.026849 500 410 13 87 0 0 95 8 + 600 -0.06133022 0.97805065 600 494 14 86 0 0 93 7 + 700 -0.053815853 1.0641005 700 572 17 83 0 0 91 8 + 800 -0.059974814 1.0192348 800 650 23 77 0 0 83 6 + 900 -0.051808132 1.0773288 900 728 25 75 0 0 85 10 + 1000 -0.050390995 1.0236954 1000 804 28 72 0 0 81 9 + 1100 -0.069766444 1.030965 1100 890 25 75 0 0 85 10 + 1200 -0.074580231 1.0490058 1200 963 21 79 0 0 88 9 + 1300 -0.060169443 0.93456607 1300 1043 22 78 0 0 86 8 + 1400 -0.05120764 1.0374062 1400 1127 19 81 0 0 92 11 + 1500 -0.027644416 0.99804782 1500 1204 24 76 0 0 85 9 + 1600 -0.038599195 0.99015524 1600 1283 22 78 0 0 90 12 + 1700 -0.050222686 1.1444379 1700 1365 27 73 0 0 84 11 + 1800 -0.049338003 1.1188048 1800 1449 22 78 0 0 84 6 + 1900 -0.04533154 0.99894341 1900 1527 22 78 0 0 86 8 + 2000 -0.058837311 0.95302017 2000 1608 26 74 0 0 81 7 +Loop time of 3.98119 on 4 procs for 2000 steps with 188 atoms + +Performance: 217020.495 tau/day, 502.362 timesteps/s +96.2% 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.050626 | 0.061127 | 0.071318 | 3.4 | 1.54 +Kspace | 1.1987 | 1.2504 | 1.288 | 3.1 | 31.41 +Neigh | 0.0056982 | 0.0063858 | 0.0069821 | 0.7 | 0.16 +Comm | 0.068302 | 0.11638 | 0.17922 | 12.8 | 2.92 +Output | 0.00055408 | 0.00092399 | 0.0020106 | 0.0 | 0.02 +Modify | 2.5399 | 2.5406 | 2.5417 | 0.0 | 63.81 +Other | | 0.005394 | | | 0.14 + +Nlocal: 47.0000 ave 55 max 42 min +Histogram: 1 0 1 1 0 0 0 0 0 1 +Nghost: 328.250 ave 335 max 317 min +Histogram: 1 0 0 0 0 1 0 0 0 2 +Neighs: 547.000 ave 659 max 466 min +Histogram: 2 0 0 0 0 0 1 0 0 1 + +Total # of neighbors = 2188 +Ave neighs/atom = 11.638298 +Neighbor list builds = 2057 +Dangerous builds = 0 +Total wall time: 0:00:04 diff --git a/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.1 b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.1 new file mode 100644 index 0000000000..c386b2bed9 --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.1 @@ -0,0 +1,131 @@ +LAMMPS (10 Feb 2021) + using 1 OpenMP thread(s) per MPI task +# Charge regulation lammps for a polymer chain +units lj +atom_style full +neighbor 3.0 bin +read_data data.chreg-polymer +Reading data file ... + orthogonal box = (-50.000000 -50.000000 -50.000000) to (50.000000 50.000000 50.000000) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 160 atoms + scanning bonds ... + 1 = max bonds/atom + reading bonds ... + 79 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.001 seconds + read_data CPU = 0.009 seconds + +bond_style harmonic +bond_coeff 1 100 1.122462 # K R0 +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long 1.122462 20 +pair_coeff * * 1.0 1.0 1.122462 # charges +kspace_style pppm 1.0e-3 +pair_modify shift yes +dielectric 1.0 + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg1 all charge/regulation 2 3 acid_type 1 pH 7.0 pKa 6.5 pIp 3.0 pIm 3.0 temp 1.0 nmc 40 seed 2345 +fix chareg2 all charge/regulation 4 5 acid_type 1 pH 7.0 pKa 6.5 pIp 7.0 pIm 7.0 temp 1.0 nmc 40 seed 2345 +fix chareg3 all charge/regulation 4 3 pIp 7.0 pIm 3.0 temp 1.0 nmc 20 seed 2345 + +thermo 100 +# print: step, potential energy, temperature, neutral acids, charged acids, salt cations, salt anions, H+ ions, OH- ions +thermo_style custom step pe c_dtemp f_chareg1[3] f_chareg1[4] f_chareg1[7] f_chareg1[8] f_chareg2[7] f_chareg2[8] + +timestep 0.005 +run 2000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:339) + G vector (1/distance) = 0.077106934 + grid = 8 8 8 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00074388331 + estimated relative force accuracy = 0.00074388331 + using double precision FFTW3 + 3d grid and FFT values/proc = 2197 512 +0 atoms in group FixChargeRegulation:exclusion_group:chareg1 +0 atoms in group FixChargeRegulation:exclusion_group:chareg2 +0 atoms in group FixChargeRegulation:exclusion_group:chareg3 +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 23 + ghost atom cutoff = 23 + binsize = 11.5, bins = 9 9 9 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.962 | 6.962 | 6.962 Mbytes +Step PotEng c_dtemp f_chareg1[3] f_chareg1[4] f_chareg1[7] f_chareg1[8] f_chareg2[7] f_chareg2[8] + 0 0.50528297 1 0 80 80 0 0 0 + 100 0.61185377 0.95892928 13 67 74 7 0 0 + 200 0.54355177 1.1282424 19 61 76 15 0 0 + 300 0.4519957 1.0764688 20 60 85 26 1 0 + 400 0.41479389 0.99212685 24 56 92 36 0 0 + 500 0.37382446 0.99776674 28 52 98 46 0 0 + 600 0.34785337 1.1115081 28 52 109 57 0 0 + 700 0.34637618 1.0332262 28 52 120 68 0 0 + 800 0.21020932 1.1264036 29 51 125 74 0 0 + 900 0.21246108 1.1168609 30 50 131 81 0 0 + 1000 0.20997475 1.1201478 32 48 132 84 0 0 + 1100 0.1984165 1.0209092 31 49 144 95 0 0 + 1200 0.2061932 0.95880059 35 45 151 106 0 0 + 1300 0.17220376 0.980077 36 44 156 112 0 0 + 1400 0.15671143 0.93535342 37 43 161 118 0 0 + 1500 0.16174665 0.9495928 36 44 168 124 0 0 + 1600 0.11062965 0.94072924 40 40 164 124 0 0 + 1700 0.13002563 0.95010828 38 42 167 125 0 0 + 1800 0.14527814 0.93555342 37 43 172 129 0 0 + 1900 0.17627465 0.96682495 32 48 176 128 0 0 + 2000 0.16497265 0.95226954 33 47 180 133 0 0 +Loop time of 7.45499 on 1 procs for 2000 steps with 393 atoms + +Performance: 115895.577 tau/day, 268.277 timesteps/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 | 0.45607 | 0.45607 | 0.45607 | 0.0 | 6.12 +Bond | 0.0062385 | 0.0062385 | 0.0062385 | 0.0 | 0.08 +Kspace | 2.3257 | 2.3257 | 2.3257 | 0.0 | 31.20 +Neigh | 0.067103 | 0.067103 | 0.067103 | 0.0 | 0.90 +Comm | 0.02577 | 0.02577 | 0.02577 | 0.0 | 0.35 +Output | 0.00087047 | 0.00087047 | 0.00087047 | 0.0 | 0.01 +Modify | 4.5664 | 4.5664 | 4.5664 | 0.0 | 61.25 +Other | | 0.006848 | | | 0.09 + +Nlocal: 393.000 ave 393 max 393 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 749.000 ave 749 max 749 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 5359.00 ave 5359 max 5359 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 5359 +Ave neighs/atom = 13.636132 +Ave special neighs/atom = 1.1908397 +Neighbor list builds = 1489 +Dangerous builds = 0 +Total wall time: 0:00:07 diff --git a/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.4 b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.4 new file mode 100644 index 0000000000..c623d3048b --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.4 @@ -0,0 +1,131 @@ +LAMMPS (10 Feb 2021) + using 1 OpenMP thread(s) per MPI task +# Charge regulation lammps for a polymer chain +units lj +atom_style full +neighbor 3.0 bin +read_data data.chreg-polymer +Reading data file ... + orthogonal box = (-50.000000 -50.000000 -50.000000) to (50.000000 50.000000 50.000000) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 160 atoms + scanning bonds ... + 1 = max bonds/atom + reading bonds ... + 79 bonds +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 2 = max # of 1-3 neighbors + 4 = max # of 1-4 neighbors + 6 = max # of special neighbors + special bonds CPU = 0.001 seconds + read_data CPU = 0.016 seconds + +bond_style harmonic +bond_coeff 1 100 1.122462 # K R0 +velocity all create 1.0 8008 loop geom + +pair_style lj/cut/coul/long 1.122462 20 +pair_coeff * * 1.0 1.0 1.122462 # charges +kspace_style pppm 1.0e-3 +pair_modify shift yes +dielectric 1.0 + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin 1.0 1.0 1.0 123 +fix_modify fT temp dtemp + +fix chareg1 all charge/regulation 2 3 acid_type 1 pH 7.0 pKa 6.5 pIp 3.0 pIm 3.0 temp 1.0 nmc 40 seed 2345 +fix chareg2 all charge/regulation 4 5 acid_type 1 pH 7.0 pKa 6.5 pIp 7.0 pIm 7.0 temp 1.0 nmc 40 seed 2345 +fix chareg3 all charge/regulation 4 3 pIp 7.0 pIm 3.0 temp 1.0 nmc 20 seed 2345 + +thermo 100 +# print: step, potential energy, temperature, neutral acids, charged acids, salt cations, salt anions, H+ ions, OH- ions +thermo_style custom step pe c_dtemp f_chareg1[3] f_chareg1[4] f_chareg1[7] f_chareg1[8] f_chareg2[7] f_chareg2[8] + +timestep 0.005 +run 2000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:339) + G vector (1/distance) = 0.077106934 + grid = 8 8 8 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00074388331 + estimated relative force accuracy = 0.00074388331 + using double precision FFTW3 + 3d grid and FFT values/proc = 1053 128 +0 atoms in group FixChargeRegulation:exclusion_group:chareg1 +0 atoms in group FixChargeRegulation:exclusion_group:chareg2 +0 atoms in group FixChargeRegulation:exclusion_group:chareg3 +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 23 + ghost atom cutoff = 23 + binsize = 11.5, bins = 9 9 9 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.878 | 6.935 | 6.992 Mbytes +Step PotEng c_dtemp f_chareg1[3] f_chareg1[4] f_chareg1[7] f_chareg1[8] f_chareg2[7] f_chareg2[8] + 0 0.50528297 1 0 80 80 0 0 0 + 100 0.60223729 0.89547569 13 67 75 8 0 0 + 200 0.65253636 0.87662399 18 62 78 16 0 0 + 300 0.51550501 1.0542131 22 58 84 27 1 0 + 400 0.43566766 0.94557633 26 54 90 36 0 0 + 500 0.36269507 1.0386276 31 49 94 45 0 0 + 600 0.32430641 0.99903033 27 53 111 58 0 0 + 700 0.30255299 0.91225991 28 52 121 69 0 0 + 800 0.27189951 0.9747089 28 52 127 75 0 0 + 900 0.25495247 1.0747821 28 52 135 83 0 0 + 1000 0.25950416 0.95256449 32 48 134 86 0 0 + 1100 0.22561248 1.0102255 32 48 147 99 0 0 + 1200 0.1734754 0.99475154 33 47 157 110 0 0 + 1300 0.20081084 0.99873599 36 44 160 116 0 0 + 1400 0.14240417 0.99442152 36 44 164 121 1 0 + 1500 0.15314186 0.94559876 39 41 167 126 0 0 + 1600 0.13574107 1.0484195 43 37 164 127 0 0 + 1700 0.14477789 1.0105172 42 38 166 128 0 0 + 1800 0.13493107 1.0349667 41 39 171 132 0 0 + 1900 0.14849779 0.9994329 33 47 178 131 0 0 + 2000 0.14485171 0.99739608 34 46 183 137 0 0 +Loop time of 3.18871 on 4 procs for 2000 steps with 400 atoms + +Performance: 270955.695 tau/day, 627.212 timesteps/s +94.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.086456 | 0.11738 | 0.18562 | 11.8 | 3.68 +Bond | 0.00099182 | 0.0018544 | 0.0030079 | 1.8 | 0.06 +Kspace | 0.77406 | 0.79354 | 0.80895 | 1.5 | 24.89 +Neigh | 0.017894 | 0.017948 | 0.018002 | 0.0 | 0.56 +Comm | 0.029044 | 0.07885 | 0.11432 | 11.3 | 2.47 +Output | 0.00054932 | 0.0009656 | 0.0021319 | 0.0 | 0.03 +Modify | 2.1676 | 2.1706 | 2.1733 | 0.2 | 68.07 +Other | | 0.007591 | | | 0.24 + +Nlocal: 100.000 ave 110 max 89 min +Histogram: 1 1 0 0 0 0 0 0 0 2 +Nghost: 415.000 ave 418 max 411 min +Histogram: 1 0 1 0 0 0 0 0 0 2 +Neighs: 1360.75 ave 1872 max 1018 min +Histogram: 1 1 0 0 1 0 0 0 0 1 + +Total # of neighbors = 5443 +Ave neighs/atom = 13.607500 +Ave special neighs/atom = 1.1700000 +Neighbor list builds = 1492 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.1 b/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.1 new file mode 100644 index 0000000000..6e50ea5ef3 --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.1 @@ -0,0 +1,145 @@ +LAMMPS (10 Feb 2021) +# Charge regulation lammps for simple weak electrolyte + +units real +atom_style charge +neighbor 10.0 bin +read_data data.chreg-acid-real +Reading data file ... + orthogonal box = (-180.00000 -180.00000 -180.00000) to (180.00000 180.00000 180.00000) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 219 atoms + read_data CPU = 0.002 seconds + +#real units +variable sigma equal 7.2 # particle diameter 0.72 nm +variable temperature equal 298 # temperature 298 K +variable kb index 0.0019872067 # kB in Kcal/mol/K +variable epsilon equal ${kb}*${temperature} +variable epsilon equal 0.0019872067*${temperature} +variable epsilon equal 0.0019872067*298 +variable tunit equal 2000 # time unit is 2000 fs +variable timestep equal 0.005*${tunit} +variable timestep equal 0.005*2000 + +variable cut_long equal 12.5*${sigma} +variable cut_long equal 12.5*7.2 +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0)*${sigma} +variable cut_lj equal 2^(1.0/6.0)*7.2 +velocity all create ${temperature} 8008 loop geom +velocity all create 298 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_style lj/cut/coul/long 8.08172674782749 ${cut_long} +pair_style lj/cut/coul/long 8.08172674782749 90 +pair_coeff * * ${epsilon} ${sigma} +pair_coeff * * 0.5921875966 ${sigma} +pair_coeff * * 0.5921875966 7.2 +kspace_style pppm 1.0e-3 +dielectric 78 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin $(v_temperature) $(v_temperature) $(v_tunit) 123 +fix fT all langevin 298 $(v_temperature) $(v_tunit) 123 +fix fT all langevin 298 298 $(v_tunit) 123 +fix fT all langevin 298 298 2000 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery 100 nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery 100 nmc 100 seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep ${timestep} +timestep 10 +run 2000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (../kspace.cpp:339) + G vector (1/distance) = 0.019408615 + grid = 8 8 8 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00012527706 + estimated relative force accuracy = 3.7726815e-07 + using double precision KISS FFT + 3d grid and FFT values/proc = 2197 512 +0 atoms in group FixChargeRegulation:exclusion_group:chareg +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (../neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 100 + ghost atom cutoff = 100 + binsize = 50, bins = 8 8 8 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.708 | 3.708 | 3.708 Mbytes +Step PotEng c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] + 0 -6.4798431 298 0 0 1 99 0 0 109 10 + 100 -6.9219668 306.44177 100 77 15 85 0 0 94 9 + 200 -6.8175255 306.64254 200 164 23 77 0 0 87 10 + 300 -5.2482381 331.67831 300 248 21 79 0 0 85 6 + 400 -7.4531538 285.3495 400 326 17 83 0 0 89 6 + 500 -6.9662528 286.2123 500 408 14 86 0 0 95 9 + 600 -6.528214 291.41762 600 492 14 86 0 0 95 9 + 700 -6.290871 271.50948 700 567 14 86 0 0 96 10 + 800 -6.4944741 300.66261 800 650 23 77 0 0 83 6 + 900 -8.0414672 305.6179 900 731 25 75 0 0 84 9 + 1000 -8.5694583 298.73349 1000 810 25 75 0 0 83 8 + 1100 -8.6677368 269.67435 1100 894 22 78 0 0 87 9 + 1200 -8.2246183 284.14886 1200 969 22 78 0 0 88 10 + 1300 -7.7674621 320.04838 1300 1040 23 77 0 0 85 8 + 1400 -9.5186335 303.48091 1400 1124 18 82 0 0 93 11 + 1500 -5.8437493 271.40712 1500 1204 25 75 0 0 83 8 + 1600 -5.9149181 268.24708 1600 1285 23 77 0 0 90 13 + 1700 -6.5047738 303.79732 1700 1369 27 73 0 0 84 11 + 1800 -7.3010139 308.98213 1800 1450 22 78 0 0 83 5 + 1900 -6.3505397 306.94357 1900 1527 22 78 0 0 86 8 + 2000 -5.7144173 287.06184 2000 1605 27 73 0 0 80 7 +Loop time of 1.17189 on 1 procs for 2000 steps with 187 atoms + +Performance: 1474.535 ns/day, 0.016 hours/ns, 1706.638 timesteps/s +99.6% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.035807 | 0.035807 | 0.035807 | 0.0 | 3.06 +Kspace | 0.37689 | 0.37689 | 0.37689 | 0.0 | 32.16 +Neigh | 0.008694 | 0.008694 | 0.008694 | 0.0 | 0.74 +Comm | 0.004793 | 0.004793 | 0.004793 | 0.0 | 0.41 +Output | 0.000746 | 0.000746 | 0.000746 | 0.0 | 0.06 +Modify | 0.74292 | 0.74292 | 0.74292 | 0.0 | 63.39 +Other | | 0.00205 | | | 0.17 + +Nlocal: 187.000 ave 187 max 187 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 437.000 ave 437 max 437 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1500.00 ave 1500 max 1500 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 1500 +Ave neighs/atom = 8.0213904 +Neighbor list builds = 2080 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.4 b/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.4 new file mode 100644 index 0000000000..927e29c1f3 --- /dev/null +++ b/examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.4 @@ -0,0 +1,145 @@ +LAMMPS (10 Feb 2021) +# Charge regulation lammps for simple weak electrolyte + +units real +atom_style charge +neighbor 10.0 bin +read_data data.chreg-acid-real +Reading data file ... + orthogonal box = (-180.00000 -180.00000 -180.00000) to (180.00000 180.00000 180.00000) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 219 atoms + read_data CPU = 0.002 seconds + +#real units +variable sigma equal 7.2 # particle diameter 0.72 nm +variable temperature equal 298 # temperature 298 K +variable kb index 0.0019872067 # kB in Kcal/mol/K +variable epsilon equal ${kb}*${temperature} +variable epsilon equal 0.0019872067*${temperature} +variable epsilon equal 0.0019872067*298 +variable tunit equal 2000 # time unit is 2000 fs +variable timestep equal 0.005*${tunit} +variable timestep equal 0.005*2000 + +variable cut_long equal 12.5*${sigma} +variable cut_long equal 12.5*7.2 +variable nevery equal 100 +variable nmc equal 100 +variable pH equal 7.0 +variable pKa equal 6.0 +variable pIm equal 3.0 +variable pIp equal 3.0 + +variable cut_lj equal 2^(1.0/6.0)*${sigma} +variable cut_lj equal 2^(1.0/6.0)*7.2 +velocity all create ${temperature} 8008 loop geom +velocity all create 298 8008 loop geom + +pair_style lj/cut/coul/long ${cut_lj} ${cut_long} +pair_style lj/cut/coul/long 8.08172674782749 ${cut_long} +pair_style lj/cut/coul/long 8.08172674782749 90 +pair_coeff * * ${epsilon} ${sigma} +pair_coeff * * 0.5921875966 ${sigma} +pair_coeff * * 0.5921875966 7.2 +kspace_style pppm 1.0e-3 +dielectric 78 +pair_modify shift yes + +######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### +fix fnve all nve +compute dtemp all temp +compute_modify dtemp dynamic yes +fix fT all langevin $(v_temperature) $(v_temperature) $(v_tunit) 123 +fix fT all langevin 298 $(v_temperature) $(v_tunit) 123 +fix fT all langevin 298 298 $(v_tunit) 123 +fix fT all langevin 298 298 2000 123 +fix_modify fT temp dtemp + +fix chareg all charge/regulation 2 3 acid_type 1 pH ${pH} pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa ${pKa} pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp ${pIp} pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm ${pIm} lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery ${nevery} nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery 100 nmc ${nmc} seed 2345 tempfixid fT +fix chareg all charge/regulation 2 3 acid_type 1 pH 7 pKa 6 pIp 3 pIm 3 lunit_nm 0.1 nevery 100 nmc 100 seed 2345 tempfixid fT +thermo 100 +thermo_style custom step pe c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] +timestep ${timestep} +timestep 10 +run 2000 +PPPM initialization ... + using 12-bit tables for long-range coulomb (../kspace.cpp:339) + G vector (1/distance) = 0.019408615 + grid = 8 8 8 + stencil order = 5 + estimated absolute RMS force accuracy = 0.00012527706 + estimated relative force accuracy = 3.7726815e-07 + using double precision KISS FFT + 3d grid and FFT values/proc = 1053 128 +0 atoms in group FixChargeRegulation:exclusion_group:chareg +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (../neighbor.cpp:486) +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 100 + ghost atom cutoff = 100 + binsize = 50, bins = 8 8 8 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.624 | 3.624 | 3.624 Mbytes +Step PotEng c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] f_chareg[6] f_chareg[7] f_chareg[8] + 0 -6.4798431 298 0 0 1 99 0 0 109 10 + 100 -7.6327126 304.68909 100 73 15 85 0 0 94 9 + 200 -6.1699041 272.19597 200 156 24 76 0 0 87 11 + 300 -7.7876571 288.90801 300 240 20 80 0 0 87 7 + 400 -6.3239918 274.65708 400 315 16 84 0 0 90 6 + 500 -5.3978659 257.49208 500 398 15 85 0 0 93 8 + 600 -5.6433949 322.52048 600 477 18 82 0 0 90 8 + 700 -6.5351367 269.20244 700 558 18 82 0 0 91 9 + 800 -6.2093085 315.21326 800 638 24 76 0 0 83 7 + 900 -7.0795998 311.93228 900 719 28 72 0 0 82 10 + 1000 -6.4668438 281.72674 1000 796 27 73 0 0 81 8 + 1100 -6.2377994 318.48594 1100 875 25 75 0 0 84 9 + 1200 -6.6305072 304.9091 1200 950 23 77 0 0 87 10 + 1300 -5.9624552 286.05027 1300 1029 22 78 0 0 86 8 + 1400 -4.4695814 261.81053 1400 1111 20 80 0 0 90 10 + 1500 -5.6928652 293.72403 1500 1191 24 76 0 0 86 10 + 1600 -6.8715413 290.47065 1600 1275 22 78 0 0 90 12 + 1700 -6.5067505 292.74735 1700 1356 25 75 0 0 85 10 + 1800 -5.3902702 307.79012 1800 1434 22 78 0 0 83 5 + 1900 -5.1407153 318.48918 1900 1510 21 79 0 0 87 8 + 2000 -4.9514719 281.87771 2000 1589 25 75 0 0 82 7 +Loop time of 0.562889 on 4 procs for 2000 steps with 189 atoms + +Performance: 3069.876 ns/day, 0.008 hours/ns, 3553.097 timesteps/s +99.6% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.008399 | 0.010383 | 0.011765 | 1.2 | 1.84 +Kspace | 0.17501 | 0.17543 | 0.1757 | 0.1 | 31.17 +Neigh | 0.001833 | 0.0021325 | 0.002293 | 0.4 | 0.38 +Comm | 0.023099 | 0.024255 | 0.026645 | 0.9 | 4.31 +Output | 0.000465 | 0.000546 | 0.000783 | 0.0 | 0.10 +Modify | 0.3464 | 0.34669 | 0.34698 | 0.0 | 61.59 +Other | | 0.003452 | | | 0.61 + +Nlocal: 47.2500 ave 57 max 41 min +Histogram: 1 1 0 1 0 0 0 0 0 1 +Nghost: 285.750 ave 303 max 263 min +Histogram: 1 0 0 0 1 0 0 0 1 1 +Neighs: 403.500 ave 548 max 324 min +Histogram: 2 0 0 1 0 0 0 0 0 1 + +Total # of neighbors = 1614 +Ave neighs/atom = 8.5396825 +Neighbor list builds = 2081 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp new file mode 100644 index 0000000000..34391b86fb --- /dev/null +++ b/src/MC/fix_charge_regulation.cpp @@ -0,0 +1,1379 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Tine Curk (tcurk5@gmail.com) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) +------------------------------------------------------------------------- */ + +#include "fix_charge_regulation.h" + +#include "angle.h" +#include "atom.h" +#include "atom_vec.h" +#include "bond.h" +#include "comm.h" +#include "compute.h" +#include "dihedral.h" +#include "domain.h" +#include "error.h" +#include "fix.h" +#include "force.h" +#include "group.h" +#include "improper.h" +#include "kspace.h" +#include "math_const.h" +#include "math_extra.h" +#include "math_special.h" +#include "memory.h" +#include "modify.h" +#include "molecule.h" +#include "neighbor.h" +#include "pair.h" +#include "random_park.h" +#include "region.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; +using namespace MathSpecial; + +// large energy value used to signal overlap +#define MAXENERGYSIGNAL 1.0e100 +#define MAXENERGYTEST 1.0e50 +#define SMALL 0.0000001 +#define NA_RHO0 0.602214 // Avogadro's constant times reference concentration (N_A * mol / liter) [nm^-3] + +/* ---------------------------------------------------------------------- */ + +FixChargeRegulation::FixChargeRegulation(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), + ngroups(0), groupstrings(nullptr), ptype_ID(nullptr), + random_equal(nullptr), random_unequal(nullptr), + idftemp(nullptr) +{ + + // Region restrictions not yet implemented .. + + vector_flag = 1; + size_vector = 8; + global_freq = 1; + extvector = 0; + restart_global = 1; + time_depend = 1; + cr_nmax = 0; + overlap_flag = 0; + energy_stored = 0; + + // necessary to specify the free ion types + cation_type = utils::inumeric(FLERR, arg[3], false, lmp); + anion_type = utils::inumeric(FLERR, arg[4], false, lmp); + + // set defaults and read optional arguments + options(narg - 5, &arg[5]); + + if ((nevery <= 0) || (nmc < 0) || (llength_unit_in_nm < 0.0) + || (*target_temperature_tcp < 0.0) || (cation_type <= 0) + || (anion_type <= 0) || (reaction_distance < 0.0) + || (salt_charge[0] <= 0) || (salt_charge[1] >= 0)) + error->all(FLERR, "Illegal fix charge/regulation command"); + + if (seed <= 0) + error->all(FLERR, "Illegal fix charge/regulation command: " + "Seed value (positive integer) must be provided "); + if ((salt_charge[1] % salt_charge[0] != 0) + && (salt_charge[0] % salt_charge[1] != 0)) + error->all(FLERR,"Illegal fix charge/regulation command, " + "multivalent cation/anion charges are allowed, " + "but must be divisible, e.g. (3,-1) is fine, " + "but (3,-2) is not implemented"); + + if (pmcmoves[0] < 0 || pmcmoves[1] < 0 || pmcmoves[2] < 0) + error->all(FLERR, "Illegal fix charge/regulation command"); + if (acid_type < 0) pmcmoves[0] = 0; + if (base_type < 0) pmcmoves[1] = 0; + + // normalize + double psum = pmcmoves[0] + pmcmoves[1] + pmcmoves[2]; + if (psum <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); + pmcmoves[0] /= psum; + pmcmoves[1] /= psum; + pmcmoves[2] /= psum; + + force_reneighbor = 1; + next_reneighbor = update->ntimestep + 1; + random_equal = new RanPark(lmp, seed); + random_unequal = new RanPark(lmp, seed); + nacid_attempts = 0; + nacid_successes = 0; + nbase_attempts = 0; + nbase_successes = 0; + nsalt_attempts = 0; + nsalt_successes = 0; +} + +FixChargeRegulation::~FixChargeRegulation() { + + memory->destroy(ptype_ID); + + delete random_equal; + delete random_unequal; + delete[] idftemp; + + if (group) { + int igroupall = group->find("all"); + neighbor->exclusion_group_group_delete(exclusion_group, igroupall); + } +} + +int FixChargeRegulation::setmask() { + int mask = 0; + mask |= PRE_EXCHANGE; + return mask; +} + +void FixChargeRegulation::init() { + + triclinic = domain->triclinic; + int ipe = modify->find_compute("thermo_pe"); + c_pe = modify->compute[ipe]; + + if (atom->molecule_flag) { + + int flag = 0; + for (int i = 0; i < atom->nlocal; i++) + if (atom->type[i] == cation_type || atom->type[i] == anion_type) + if (atom->molecule[i]) flag = 1; + int flagall = flag; + + MPI_Allreduce(&flag, &flagall, 1, MPI_INT, MPI_SUM, world); + if (flagall && comm->me == 0) + error->all(FLERR, "fix charge/regulation cannot exchange " + "individual atoms (ions) belonging to a molecule"); + } + + if (domain->dimension == 2) + error->all(FLERR, "Cannot use fix charge/regulation in a 2d simulation"); + + // create a new group for interaction exclusions + // used for attempted atom deletions + // skip if already exists from previous init() + + if (!exclusion_group_bit) { + + // create unique group name for atoms to be excluded + + auto group_id = fmt::format("FixChargeRegulation:exclusion_group:{}",id); + group->assign(group_id + " subtract all all"); + exclusion_group = group->find(group_id); + if (exclusion_group == -1) + error->all(FLERR,"Could not find fix charge/regulation exclusion " + "group ID"); + exclusion_group_bit = group->bitmask[exclusion_group]; + + // neighbor list exclusion setup + // turn off interactions between group all and the exclusion group + + int narg = 4; + char **arg = new char*[narg];; + arg[0] = (char *) "exclude"; + arg[1] = (char *) "group"; + arg[2] = (char *) group_id.c_str(); + arg[3] = (char *) "all"; + neighbor->modify_params(narg,arg); + delete [] arg; + } + + // check that no deletable atoms are in atom->firstgroup + // deleting such an atom would not leave firstgroup atoms first + + if (atom->firstgroup >= 0) { + int *mask = atom->mask; + int firstgroupbit = group->bitmask[atom->firstgroup]; + + int flag = 0; + for (int i = 0; i < atom->nlocal; i++) + if ((mask[i] == groupbit) && (mask[i] && firstgroupbit)) flag = 1; + + int flagall; + MPI_Allreduce(&flag, &flagall, 1, MPI_INT, MPI_SUM, world); + + if (flagall) + error->all(FLERR, "Cannot use fix charge/regulation on atoms " + "in atom_modify first group"); + } + + // construct group bitmask for all new atoms + // aggregated over all group keywords + + groupbitall = 1 | groupbit; + + for (int igroup = 0; igroup < ngroups; igroup++) { + int jgroup = group->find(groupstrings[igroup]); + if (jgroup == -1) + error->all(FLERR, "Could not find fix charge/regulation group ID"); + groupbitall |= group->bitmask[jgroup]; + } +} + +void FixChargeRegulation::pre_exchange() { + + if (next_reneighbor != update->ntimestep) return; + xlo = domain->boxlo[0]; + xhi = domain->boxhi[0]; + ylo = domain->boxlo[1]; + yhi = domain->boxhi[1]; + zlo = domain->boxlo[2]; + zhi = domain->boxhi[2]; + + if (triclinic) { + sublo = domain->sublo_lamda; + subhi = domain->subhi_lamda; + } else { + sublo = domain->sublo; + subhi = domain->subhi; + } + volume = domain->xprd * domain->yprd * domain->zprd; + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + comm->exchange(); + atom->nghost = 0; + comm->borders(); + + if (triclinic) domain->lamda2x(atom->nlocal + atom->nghost); + energy_stored = energy_full(); + if ((energy_stored > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR, "Energy of old configuration in fix " + "charge/regulation is > MAXENERGYTEST."); + + if ((reaction_distance > domain->prd_half[0]) || + (reaction_distance > domain->prd_half[1]) || + (reaction_distance > domain->prd_half[2])) { + if (comm->me == 0) + error->warning(FLERR,"reaction distance (rxd) is larger than " + "half the box dimension, resetting default: xrd = 0."); + reaction_distance = 0; + } + // volume in units of (N_A * mol / liter) + volume_rx = (xhi - xlo) * (yhi - ylo) * (zhi - zlo) + * cube(llength_unit_in_nm) * NA_RHO0; + if (reaction_distance < SMALL) { + vlocal_xrd = volume_rx; + } else { + vlocal_xrd = 4.0 * MY_PI * cube(reaction_distance) + / 3.0 * cube(llength_unit_in_nm) * NA_RHO0; + } + beta = 1.0 / (force->boltz * *target_temperature_tcp); + + // pre-compute powers + c10pH = pow(10.0,-pH); // dissociated ion (H+) activity + c10pKa = pow(10.0,-pKa); // acid dissociation constant + c10pKb = pow(10.0,-pKb); // base dissociation constant + c10pOH = pow(10.0,-pKs + pH); // dissociated anion (OH-) activity + c10pI_plus = pow(10.0,-pI_plus); // free cation activity + c10pI_minus = pow(10.0,-pI_minus); // free anion activity + + // reinitialize counters + nacid_neutral = particle_number(acid_type, 0); + nacid_charged = particle_number(acid_type, -1); + nbase_neutral = particle_number(base_type, 0); + nbase_charged = particle_number(base_type, 1); + ncation = particle_number(cation_type, salt_charge[0]); + nanion = particle_number(anion_type, salt_charge[1]); + + + // Attempt exchanges + if (!only_salt_flag) { + + // Do charge regulation + for (int i = 0; i < nmc; i++) { + double rand_number = random_equal->uniform(); + if (rand_number < pmcmoves[0] / 2) { + forward_acid(); + nacid_attempts++; + } else if (rand_number < pmcmoves[0]) { + backward_acid(); + nacid_attempts++; + } else if (rand_number < pmcmoves[0] + pmcmoves[1] / 2) { + forward_base(); + nbase_attempts++; + } else if (rand_number < pmcmoves[0] + pmcmoves[1]) { + backward_base(); + nbase_attempts++; + } else if (rand_number < pmcmoves[0] + pmcmoves[1] + pmcmoves[2] / 2) { + forward_ions(); + nsalt_attempts++; + } else { + backward_ions(); + nsalt_attempts++; + } + } + } else { + // do only ion insertion, multivalent cation/anions are implemented + if (salt_charge[0] >= -salt_charge[1]) { + salt_charge_ratio = -salt_charge[0] / salt_charge[1]; + } else { + salt_charge_ratio = -salt_charge[1] / salt_charge[0]; + } + for (int i = 0; i < nmc; i++) { + double rand_number = random_equal->uniform(); + if (rand_number < 0.5) { + forward_ions_multival(); + nsalt_attempts++; + } else { + backward_ions_multival(); + nsalt_attempts++; + } + } + } + + // assign unique tags to newly inserted ions + if (add_tags_flag && atom->tag_enable) assign_tags(); + + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + comm->exchange(); + atom->nghost = 0; + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal + atom->nghost); + next_reneighbor = update->ntimestep + nevery; +} + +void FixChargeRegulation::forward_acid() { + + double energy_before = energy_stored; + double factor; + double *dummyp = nullptr; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m2 = -1; + + m1 = get_random_particle(acid_type, 0, 0, dummyp); + if (npart_xrd != nacid_neutral) error->all(FLERR, "fix charge/regulation acid count inconsistent"); + + if (nacid_neutral > 0) { + if (m1 >= 0) { + atom->q[m1] = -1; // assign negative charge to acid + pos[0] = atom->x[m1][0]; + pos[1] = atom->x[m1][1]; + pos[2] = atom->x[m1][2]; + } + npart_xrd2 = ncation; + if (reaction_distance >= SMALL) { + pos_all[0] = pos[0]; + pos_all[1] = pos[1]; + pos_all[2] = pos[2]; + MPI_Allreduce(pos, pos_all, 3, MPI_DOUBLE, MPI_SUM, world); + npart_xrd2 = particle_number_xrd(cation_type, 1, reaction_distance, pos_all); + } + m2 = insert_particle(cation_type, 1, reaction_distance, pos_all); + factor = nacid_neutral * vlocal_xrd * c10pKa * c10pI_plus / + (c10pH * (1 + nacid_charged) * (1 + npart_xrd2)); + + double energy_after = energy_full(); + + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < factor * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + nacid_successes += 1; + ncation++; + nacid_charged++; + nacid_neutral--; + } else { + energy_stored = energy_before; + atom->natoms--; + if (m2 >= 0) { + atom->nlocal--; + } + if (m1 >= 0) { + atom->q[m1] = 0; + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + } + } +} + +void FixChargeRegulation::backward_acid() { + + double energy_before = energy_stored; + double factor; + int mask_tmp; + double *dummyp = nullptr; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m2 = -1; + + m1 = get_random_particle(acid_type, -1, 0, dummyp); + if (npart_xrd != nacid_charged) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); + + if (nacid_charged > 0) { + if (m1 >= 0) { + atom->q[m1] = 0; + pos[0] = atom->x[m1][0]; + pos[1] = atom->x[m1][1]; + pos[2] = atom->x[m1][2]; + } + if (reaction_distance >= SMALL) { + pos_all[0] = pos[0]; + pos_all[1] = pos[1]; + pos_all[2] = pos[2]; + MPI_Allreduce(pos, pos_all, 3, MPI_DOUBLE, MPI_SUM, world); + } + m2 = get_random_particle(cation_type, 1, reaction_distance, pos_all); + // note: npart_xrd changes everytime get_random_particle is called. + + if (npart_xrd > 0) { + if (m2 >= 0) { + atom->q[m2] = 0; + mask_tmp = atom->mask[m2]; // remember group bits. + atom->mask[m2] = exclusion_group_bit; + } + factor = (1 + nacid_neutral) * vlocal_xrd * c10pKa * c10pI_plus / + (c10pH * nacid_charged * npart_xrd); + + double energy_after = energy_full(); + + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < (1.0 / factor) * exp(beta * (energy_before - energy_after))) { + nacid_successes += 1; + atom->natoms--; + energy_stored = energy_after; + nacid_charged--; + nacid_neutral++; + ncation--; + if (m2 >= 0) { + atom->avec->copy(atom->nlocal - 1, m2, 1); + atom->nlocal--; + } + } else { + energy_stored = energy_before; + if (m1 >= 0) { + atom->q[m1] = -1; + } + if (m2 >= 0) { + atom->q[m2] = 1; + atom->mask[m2] = mask_tmp; + } + } + } else { + if (m1 >= 0) { + atom->q[m1] = -1; + } + } + } +} + +void FixChargeRegulation::forward_base() { + + double energy_before = energy_stored; + double factor; + double *dummyp = nullptr; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m2 = -1; + + m1 = get_random_particle(base_type, 0, 0, dummyp); + if (npart_xrd != nbase_neutral) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); + + if (nbase_neutral > 0) { + if (m1 >= 0) { + atom->q[m1] = 1; // assign negative charge to acid + pos[0] = atom->x[m1][0]; + pos[1] = atom->x[m1][1]; + pos[2] = atom->x[m1][2]; + } + npart_xrd2 = nanion; + if (reaction_distance >= SMALL) { + pos_all[0] = pos[0]; + pos_all[1] = pos[1]; + pos_all[2] = pos[2]; + MPI_Allreduce(pos, pos_all, 3, MPI_DOUBLE, MPI_SUM, world); + npart_xrd2 = particle_number_xrd(anion_type, -1, reaction_distance, pos_all); + } + factor = nbase_neutral * vlocal_xrd * c10pKb * c10pI_minus / + (c10pOH * (1 + nbase_charged) * (1 + npart_xrd2)); + m2 = insert_particle(anion_type, -1, reaction_distance, pos_all); + + double energy_after = energy_full(); + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < factor * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + nbase_successes += 1; + nbase_charged++; + nbase_neutral--; + nanion++; + } else { + energy_stored = energy_before; + atom->natoms--; + if (m2 >= 0) { + atom->nlocal--; + } + if (m1 >= 0) { + atom->q[m1] = 0; + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + } + } +} + +void FixChargeRegulation::backward_base() { + + double energy_before = energy_stored; + double factor; + double *dummyp = nullptr; + int mask_tmp; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m2 = -1; + + m1 = get_random_particle(base_type, 1, 0, dummyp); + if (npart_xrd != nbase_charged) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); + + if (nbase_charged > 0) { + if (m1 >= 0) { + atom->q[m1] = 0; + pos[0] = atom->x[m1][0]; + pos[1] = atom->x[m1][1]; + pos[2] = atom->x[m1][2]; + } + if (reaction_distance >= SMALL) { + pos_all[0] = pos[0]; + pos_all[1] = pos[1]; + pos_all[2] = pos[2]; + MPI_Allreduce(pos, pos_all, 3, MPI_DOUBLE, MPI_SUM, world); + } + m2 = get_random_particle(anion_type, -1, reaction_distance, pos_all); + + if (npart_xrd > 0) { + if (m2 >= 0) { + atom->q[m2] = 0; + mask_tmp = atom->mask[m2]; // remember group bits. + atom->mask[m2] = exclusion_group_bit; + } + factor = (1 + nbase_neutral) * vlocal_xrd * c10pKb * c10pI_minus / + (c10pOH * nbase_charged * npart_xrd); + + double energy_after = energy_full(); + + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < (1.0 / factor) * exp(beta * (energy_before - energy_after))) { + nbase_successes += 1; + atom->natoms--; + energy_stored = energy_after; + nbase_charged--; + nbase_neutral++; + nanion--; + if (m2 >= 0) { + atom->avec->copy(atom->nlocal - 1, m2, 1); + atom->nlocal--; + } + } else { + energy_stored = energy_before; + if (m1 >= 0) { + atom->q[m1] = 1; + } + if (m2 >= 0) { + atom->q[m2] = -1; + atom->mask[m2] = mask_tmp; + } + } + } else { + if (m1 >= 0) { + atom->q[m1] = 1; + } + } + } +} + +void FixChargeRegulation::forward_ions() { + + double energy_before = energy_stored; + double factor; + double *dummyp = nullptr; + int m1 = -1, m2 = -1; + factor = volume_rx * volume_rx * c10pI_plus * c10pI_minus / + ((1 + ncation) * (1 + nanion)); + + m1 = insert_particle(cation_type, +1, 0, dummyp); + m2 = insert_particle(anion_type, -1, 0, dummyp); + double energy_after = energy_full(); + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < factor * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + nsalt_successes += 1; + ncation++; + nanion++; + } else { + energy_stored = energy_before; + atom->natoms--; + if (m1 >= 0) { + atom->nlocal--; + } + atom->natoms--; + if (m2 >= 0) { + atom->nlocal--; + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + } +} + + +void FixChargeRegulation::backward_ions() { + + double energy_before = energy_stored; + double factor; + int mask1_tmp = 0, mask2_tmp = 0; + double *dummyp = nullptr; + int m1 = -1, m2 = -1; + + m1 = get_random_particle(cation_type, +1, 0, dummyp); + if (npart_xrd != ncation) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + if (ncation > 0) { + m2 = get_random_particle(anion_type, -1, 0, dummyp); + if (npart_xrd != nanion) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + if (nanion > 0) { + + // attempt deletion + + if (m1 >= 0) { + atom->q[m1] = 0; + mask1_tmp = atom->mask[m1]; + atom->mask[m1] = exclusion_group_bit; + } + if (m2 >= 0) { + atom->q[m2] = 0; + mask2_tmp = atom->mask[m2]; + atom->mask[m2] = exclusion_group_bit; + } + factor = volume_rx * volume_rx * c10pI_plus * c10pI_minus / (ncation * nanion); + + double energy_after = energy_full(); + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < (1.0 / factor) * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + nsalt_successes += 1; + ncation--; + nanion--; + + // ions must be deleted in order, otherwise index m could change upon the first deletion + atom->natoms -= 2; + if (m1 > m2) { + if (m1 >= 0) { + atom->avec->copy(atom->nlocal - 1, m1, 1); + atom->nlocal--; + } + if (m2 >= 0) { + atom->avec->copy(atom->nlocal - 1, m2, 1); + atom->nlocal--; + } + } else { + if (m2 >= 0) { + atom->avec->copy(atom->nlocal - 1, m2, 1); + atom->nlocal--; + } + if (m1 >= 0) { + atom->avec->copy(atom->nlocal - 1, m1, 1); + atom->nlocal--; + } + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + + } else { + energy_stored = energy_before; + + // reassign original charge and mask + if (m1 >= 0) { + atom->q[m1] = 1; + atom->mask[m1] = mask1_tmp; + } + if (m2 >= 0) { + atom->q[m2] = -1; + atom->mask[m2] = mask2_tmp; + } + } + } + } +} + +void FixChargeRegulation::forward_ions_multival() { + + double energy_before = energy_stored; + double factor = 1; + double *dummyp = nullptr; + int mm[salt_charge_ratio + 1];// particle ID array for all ions to be inserted + + if (salt_charge[0] <= -salt_charge[1]) { + // insert one anion and (salt_charge_ratio) cations + + mm[0] = insert_particle(anion_type, salt_charge[1], 0, dummyp); + factor *= volume_rx * c10pI_minus / (1 + nanion); + for (int i = 0; i < salt_charge_ratio; i++) { + mm[i + 1] = insert_particle(cation_type, salt_charge[0], 0, dummyp); + factor *= volume_rx *c10pI_plus / (1 + ncation + i); + } + } else { + // insert one cation and (salt_charge_ratio) anions + + mm[0] = insert_particle(cation_type, salt_charge[0], 0, dummyp); + factor *= volume_rx * c10pI_plus / (1 + ncation); + for (int i = 0; i < salt_charge_ratio; i++) { + mm[i + 1] = insert_particle(anion_type, salt_charge[1], 0, dummyp); + factor *= volume_rx * c10pI_minus / (1 + nanion + i); + } + } + + double energy_after = energy_full(); + if (energy_after < MAXENERGYTEST && random_equal->uniform() < factor * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + nsalt_successes += 1; + + if (salt_charge[0] <= -salt_charge[1]) { + ncation += salt_charge_ratio; + nanion++; + } else { + nanion += salt_charge_ratio; + ncation++; + } + } else { + energy_stored = energy_before; + + // delete inserted ions + for (int i = 0; i < salt_charge_ratio + 1; i++) { + atom->natoms--; + if (mm[i] >= 0) { + atom->nlocal--; + } + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + } +} + +void FixChargeRegulation::backward_ions_multival() { + + double energy_before = energy_stored; + double factor = 1; + double *dummyp = nullptr; // dummy pointer + int mm[salt_charge_ratio + 1]; // particle ID array for all deleted ions + double qq[salt_charge_ratio + 1]; // charge array for all deleted ions + int mask_tmp[salt_charge_ratio + 1]; // temporary mask array + + if (salt_charge[0] <= -salt_charge[1]) { + // delete one anion and (salt_charge_ratio) cations + if (ncation < salt_charge_ratio || nanion < 1) return; + + mm[0] = get_random_particle(anion_type, salt_charge[1], 0, dummyp); + if (npart_xrd != nanion) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + factor *= volume_rx * c10pI_minus / (nanion); + if (mm[0] >= 0) { + qq[0] = atom->q[mm[0]]; + atom->q[mm[0]] = 0; + mask_tmp[0] = atom->mask[mm[0]]; + atom->mask[mm[0]] = exclusion_group_bit; + } + for (int i = 0; i < salt_charge_ratio; i++) { + mm[i + 1] = get_random_particle(cation_type, salt_charge[0], 0, dummyp); + if (npart_xrd != ncation - i) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + factor *= volume_rx * c10pI_plus / (ncation - i); + if (mm[i + 1] >= 0) { + qq[i + 1] = atom->q[mm[i + 1]]; + atom->q[mm[i + 1]] = 0; + mask_tmp[i + 1] = atom->mask[mm[i + 1]]; + atom->mask[mm[i + 1]] = exclusion_group_bit; + } + } + } else { + // delete one cation and (salt_charge_ratio) anions + + if (nanion < salt_charge_ratio || ncation < 1) return; + mm[0] = get_random_particle(cation_type, salt_charge[0], 0, dummyp); + if (npart_xrd != ncation) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + factor *= volume_rx * c10pI_plus / (ncation); + if (mm[0] >= 0) { + qq[0] = atom->q[mm[0]]; + atom->q[mm[0]] = 0; + mask_tmp[0] = atom->mask[mm[0]]; + atom->mask[mm[0]] = exclusion_group_bit; + } + for (int i = 0; i < salt_charge_ratio; i++) { + mm[i + 1] = get_random_particle(anion_type, salt_charge[1], 0, dummyp); + if (npart_xrd != nanion - i) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); + if (mm[i + 1] >= 0) { + qq[i + 1] = atom->q[mm[i + 1]]; + atom->q[mm[i + 1]] = 0; + mask_tmp[i + 1] = atom->mask[mm[i + 1]]; + atom->mask[mm[i + 1]] = exclusion_group_bit; + } + factor *= volume_rx * c10pI_minus / (nanion - i); + } + } + + // attempt deletion + + double energy_after = energy_full(); + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < (1.0 / factor) * exp(beta * (energy_before - energy_after))) { + energy_stored = energy_after; + + atom->natoms -= 1 + salt_charge_ratio; + // ions must be deleted in order, otherwise index m could change upon the first deletion + for (int i = 0; i < salt_charge_ratio + 1; i++) { + // get max mm value, poor N^2 scaling, but charge ratio is a SMALL number (2 or 3). + int maxmm = -1, jmaxm = -1; + for (int j = 0; j < salt_charge_ratio + 1; j++) { + if (mm[j] > maxmm) { + maxmm = mm[j]; + jmaxm = j; + } + } + if (maxmm < 0) { + break; // already deleted all particles in this thread + } else { + // delete particle maxmm + atom->avec->copy(atom->nlocal - 1, maxmm, 1); + atom->nlocal--; + mm[jmaxm] = -1; + } + } + + // update indices + nsalt_successes += 1; + if (salt_charge[0] <= -salt_charge[1]) { + ncation -= salt_charge_ratio; + nanion--; + } else { + nanion -= salt_charge_ratio; + ncation--; + } + if (force->kspace) force->kspace->qsum_qsq(); + if (force->pair->tail_flag) force->pair->reinit(); + + } else { + energy_stored = energy_before; + + // reassign original charge and mask + for (int i = 0; i < salt_charge_ratio + 1; i++) { + if (mm[i] >= 0) { + atom->q[mm[i]] = qq[i]; + atom->mask[mm[i]] = mask_tmp[i]; + } + } + } +} + +int FixChargeRegulation::insert_particle(int ptype, double charge, double rd, double *target) { + + // insert a particle of type (ptype) with charge (charge) within distance (rd) of (target) + + double coord[3]; + int m = -1; + if (rd < SMALL) { + coord[0] = xlo + random_equal->uniform() * (xhi - xlo); + coord[1] = ylo + random_equal->uniform() * (yhi - ylo); + coord[2] = zlo + random_equal->uniform() * (zhi - zlo); + } else { + // get a random point inside a sphere with radius rd + // simple rejection sampling, probably the fastest method + double dxx=1,dyy=1,dzz=1; + while (dxx * dxx + dyy * dyy + dzz * dzz > 1.0) { + dxx = 2 * random_equal->uniform() - 1.0; + dyy = 2 * random_equal->uniform() - 1.0; + dzz = 2 * random_equal->uniform() - 1.0; + } + coord[0] = target[0] + rd * dxx; + coord[1] = target[1] + rd * dyy; + coord[2] = target[2] + rd * dzz; + + // Alternative way, but likely somewhat less efficient + /* + double radius = rd * pow(random_equal->uniform(), THIRD); + double theta = acos(2 * random_equal->uniform() - 1); + double phi = random_equal->uniform() * 2 * MY_PI; + double sinphi = sin(phi); + double cosphi = cos(phi); + double sintheta = sin(theta); + double costheta = cos(theta); + coord[0] = target[0] + radius * sintheta * cosphi; + coord[1] = target[1] + radius * sintheta * sinphi; + coord[2] = target[2] + radius * costheta; + */ + coord[0] = coord[0] - floor(1.0 * (coord[0] - xlo) / (xhi - xlo)) * (xhi - xlo); + coord[1] = coord[1] - floor(1.0 * (coord[1] - ylo) / (yhi - ylo)) * (yhi - ylo); + coord[2] = coord[2] - floor(1.0 * (coord[2] - zlo) / (zhi - zlo)) * (zhi - zlo); + } + + if (coord[0] >= sublo[0] && coord[0] < subhi[0] && + coord[1] >= sublo[1] && coord[1] < subhi[1] && + coord[2] >= sublo[2] && coord[2] < subhi[2]) { + atom->avec->create_atom(ptype, coord); + m = atom->nlocal - 1; + atom->mask[m] = groupbitall; + + sigma = sqrt(force->boltz * *target_temperature_tcp / atom->mass[ptype] / force->mvv2e); + atom->v[m][0] = random_unequal->gaussian() * sigma; + atom->v[m][1] = random_unequal->gaussian() * sigma; + atom->v[m][2] = random_unequal->gaussian() * sigma; + atom->q[m] = charge; + modify->create_attribute(m); + + } + atom->nghost = 0; + comm->borders(); + atom->natoms++; + return m; +} + +int FixChargeRegulation::get_random_particle(int ptype, double charge, double rd, double *target) { + + // returns a randomly chosen particle of type (ptype) with charge (charge) + // chosen among particles within distance (rd) of (target) + + int nlocal = atom->nlocal; + + // expand memory, if necessary + if (atom->nmax > cr_nmax) { + memory->sfree(ptype_ID); + cr_nmax = atom->nmax; + ptype_ID = (int *) memory->smalloc(cr_nmax * sizeof(int), + "CR: local_atom_list"); + } + + int count_local, count_global, count_before; + int m = -1; + count_local = 0; + count_global = 0; + count_before = 0; + + if (rd < SMALL) { //reaction_distance < SMALL: No constraint on random particle choice + for (int i = 0; i < nlocal; i++) { + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && + atom->mask[i] != exclusion_group_bit) { + ptype_ID[count_local] = i; + count_local++; + } + } + } else { + double dx, dy, dz, distance_check; + for (int i = 0; i < nlocal; i++) { + dx = fabs(atom->x[i][0] - target[0]); + dx -= static_cast(1.0 * dx / (xhi - xlo) + 0.5) * (xhi - xlo); + dy = fabs(atom->x[i][1] - target[1]); + dy -= static_cast(1.0 * dy / (yhi - ylo) + 0.5) * (yhi - ylo); + dz = fabs(atom->x[i][2] - target[2]); + dz -= static_cast(1.0 * dz / (zhi - zlo) + 0.5) * (zhi - zlo); + distance_check = dx * dx + dy * dy + dz * dz; + if ((distance_check < rd * rd) && atom->type[i] == ptype && + fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) { + ptype_ID[count_local] = i; + count_local++; + } + } + } + count_global = count_local; + count_before = count_local; + MPI_Allreduce(&count_local, &count_global, 1, MPI_INT, MPI_SUM, world); + MPI_Scan(&count_local, &count_before, 1, MPI_INT, MPI_SUM, world); + count_before -= count_local; + + npart_xrd = count_global; // save the number of particles, for use in MC acceptance ratio + if (count_global > 0) { + const int ID_global = floor(random_equal->uniform() * count_global); + if ((ID_global >= count_before) && (ID_global < (count_before + count_local))) { + const int ID_local = ID_global - count_before; + m = ptype_ID[ID_local]; // local ID of the chosen particle + return m; + } + } + return -1; +} + +double FixChargeRegulation::energy_full() { + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + comm->exchange(); + atom->nghost = 0; + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal + atom->nghost); + if (modify->n_pre_neighbor) modify->pre_neighbor(); + neighbor->build(1); + int eflag = 1; + int vflag = 0; + if (overlap_flag) { + int overlaptestall; + int overlaptest = 0; + double delx, dely, delz, rsq; + double **x = atom->x; + int nall = atom->nlocal + atom->nghost; + for (int i = 0; i < atom->nlocal; i++) { + for (int j = i + 1; j < nall; j++) { + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq < overlap_cutoffsq) { + overlaptest = 1; + break; + } + } + if (overlaptest) break; + } + overlaptestall = overlaptest; + MPI_Allreduce(&overlaptest, &overlaptestall, 1, + MPI_INT, MPI_MAX, world); + if (overlaptestall) return MAXENERGYSIGNAL; + } + size_t nbytes = sizeof(double) * (atom->nlocal + atom->nghost); + if (nbytes) memset(&atom->f[0][0], 0, 3 * nbytes); + + if (modify->n_pre_force) modify->pre_force(vflag); + + if (force->pair) force->pair->compute(eflag, vflag); + + if (atom->molecular) { + if (force->bond) force->bond->compute(eflag, vflag); + if (force->angle) force->angle->compute(eflag, vflag); + if (force->dihedral) force->dihedral->compute(eflag, vflag); + if (force->improper) force->improper->compute(eflag, vflag); + } + + if (force->kspace) force->kspace->compute(eflag, vflag); + + if (modify->n_pre_reverse) modify->pre_reverse(eflag,vflag); + if (modify->n_post_force) modify->post_force(vflag); + if (modify->n_end_of_step) modify->end_of_step(); + update->eflag_global = update->ntimestep; + double total_energy = c_pe->compute_scalar(); + return total_energy; +} + +int FixChargeRegulation::particle_number_xrd(int ptype, double charge, double rd, double *target) { + + int count = 0; + if (rd < SMALL) { + for (int i = 0; i < atom->nlocal; i++) { + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) + count++; + } + } else { + double dx, dy, dz, distance_check; + for (int i = 0; i < atom->nlocal; i++) { + dx = fabs(atom->x[i][0] - target[0]); + dx -= static_cast(1.0 * dx / (xhi - xlo) + 0.5) * (xhi - xlo); + dy = fabs(atom->x[i][1] - target[1]); + dy -= static_cast(1.0 * dy / (yhi - ylo) + 0.5) * (yhi - ylo); + dz = fabs(atom->x[i][2] - target[2]); + dz -= static_cast(1.0 * dz / (zhi - zlo) + 0.5) * (zhi - zlo); + distance_check = dx * dx + dy * dy + dz * dz; + if ((distance_check < rd * rd) && atom->type[i] == ptype && + fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) { + count++; + } + } + } + int count_sum = count; + MPI_Allreduce(&count, &count_sum, 1, MPI_INT, MPI_SUM, world); + return count_sum; +} + +int FixChargeRegulation::particle_number(int ptype, double charge) { + + int count = 0; + for (int i = 0; i < atom->nlocal; i++) { + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) + count = count + 1; + } + int count_sum = count; + MPI_Allreduce(&count, &count_sum, 1, MPI_INT, MPI_SUM, world); + return count_sum; +} + +double FixChargeRegulation::compute_vector(int n) { + if (n == 0) { + return nacid_attempts + nbase_attempts + nsalt_attempts; + } else if (n == 1) { + return nacid_successes + nbase_successes + nsalt_successes; + } else if (n == 2) { + return particle_number(acid_type, 0); + } else if (n == 3) { + return particle_number(acid_type, -1); + } else if (n == 4) { + return particle_number(base_type, 0); + } else if (n == 5) { + return particle_number(base_type, 1); + } else if (n == 6) { + return particle_number(cation_type, salt_charge[0]); + } else if (n == 7) { + return particle_number(anion_type, salt_charge[1]); + } + return 0.0; +} + +void FixChargeRegulation::setThermoTemperaturePointer() { + int ifix = -1; + ifix = modify->find_fix(idftemp); + if (ifix == -1) { + error->all(FLERR, + "fix charge/regulation regulation could not find a temperature fix id provided by tempfixid\n"); + } + Fix *temperature_fix = modify->fix[ifix]; + int dim; + target_temperature_tcp = (double *) temperature_fix->extract("t_target", dim); + +} + +void FixChargeRegulation::assign_tags() { + // Assign tags to ions with zero tags + if (atom->tag_enable) { + tagint *tag = atom->tag; + tagint maxtag_all = 0; + tagint maxtag = 0; + for (int i = 0; i < atom->nlocal; i++) maxtag = MAX(maxtag, tag[i]); + maxtag_all = maxtag; + MPI_Allreduce(&maxtag, &maxtag_all, 1, MPI_LMP_TAGINT, MPI_MAX, world); + if (maxtag_all >= MAXTAGINT) + error->all(FLERR, "New atom IDs exceed maximum allowed ID"); + + tagint notag = 0; + tagint notag_all; + for (int i = 0; i < atom->nlocal; i++) + if (tag[i] == 0 && (atom->type[i] == cation_type || atom->type[i] == anion_type))notag++; + notag_all = notag; + MPI_Allreduce(¬ag, ¬ag_all, 1, MPI_LMP_TAGINT, MPI_SUM, world); + if (notag_all >= MAXTAGINT) + error->all(FLERR, "New atom IDs exceed maximum allowed ID"); + + tagint notag_sum = notag; + MPI_Scan(¬ag, ¬ag_sum, 1, MPI_LMP_TAGINT, MPI_SUM, world); + // itag = 1st new tag that my untagged atoms should use + + tagint itag = maxtag_all + notag_sum - notag + 1; + for (int i = 0; i < atom->nlocal; i++) { + if (tag[i] == 0 && (atom->type[i] == cation_type || atom->type[i] == anion_type)) { + tag[i] = itag++; + } + } + if (atom->map_style) atom->map_init(); + atom->nghost = 0; + comm->borders(); + } +} + +/* ---------------------------------------------------------------------- + parse input options +------------------------------------------------------------------------- */ + +void FixChargeRegulation::options(int narg, char **arg) { + if (narg < 0) error->all(FLERR, "Illegal fix charge/regulation command"); + + // defaults + + pH = 7.0; + pI_plus = 5; + pI_minus = 5; + acid_type = -1; + base_type = -1; + pKa = 100; + pKb = 100; + pKs = 14.0; + nevery = 100; + nmc = 100; + pmcmoves[0] = pmcmoves[1] = pmcmoves[2] = THIRD; + llength_unit_in_nm= 0.71; // Default set to Bjerrum length in water at 20 degrees C [nm] + + reservoir_temperature = 1.0; + reaction_distance = 0; + seed = 0; + target_temperature_tcp = &reservoir_temperature; + add_tags_flag = false; + only_salt_flag = false; + salt_charge[0] = 1; // cation charge + salt_charge[1] = -1; // anion charge + + exclusion_group = 0; + exclusion_group_bit = 0; + ngroups = 0; + int ngroupsmax = 0; + groupstrings = nullptr; + + int iarg = 0; + while (iarg < narg) { + + if (strcmp(arg[iarg], "lunit_nm") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + llength_unit_in_nm = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "acid_type") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + acid_type = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "base_type") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + base_type = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pH") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pH = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pIp") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pI_plus = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pIm") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pI_minus = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pKa") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pKa = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pKb") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pKb = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + + } else if (strcmp(arg[iarg], "temp") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + reservoir_temperature = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pKs") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pKs = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "tempfixid") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + idftemp = utils::strdup(arg[iarg+1]); + setThermoTemperaturePointer(); + iarg += 2; + } else if (strcmp(arg[iarg], "rxd") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + reaction_distance = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + if ((reaction_distance > domain->prd_half[0]) || + (reaction_distance > domain->prd_half[1]) || + (reaction_distance > domain->prd_half[2])) { + if (comm->me == 0) + error->warning(FLERR,"reaction distance (rxd) is larger than half " + "the box dimension, resetting default: xrd = 0."); + reaction_distance = 0; + } + iarg += 2; + } else if (strcmp(arg[iarg], "nevery") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + nevery = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "nmc") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + nmc = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "pmcmoves") == 0) { + if (iarg + 4 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + pmcmoves[0] = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + pmcmoves[1] = utils::numeric(FLERR, arg[iarg + 2], false, lmp); + pmcmoves[2] = utils::numeric(FLERR, arg[iarg + 3], false, lmp); + iarg += 4; + } else if (strcmp(arg[iarg], "seed") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + seed = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + iarg += 2; + } else if (strcmp(arg[iarg], "tag") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + if (strcmp(arg[iarg + 1], "yes") == 0) { + add_tags_flag = true; + } else if (strcmp(arg[iarg + 1], "no") == 0) { + add_tags_flag = false; + } else error->all(FLERR, "Illegal fix charge/regulation command"); + iarg += 2; + } else if (strcmp(arg[iarg], "onlysalt") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + if (strcmp(arg[iarg + 1], "yes") == 0) { + only_salt_flag = true; + // need to specify salt charge + if (iarg + 4 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); + salt_charge[0] = utils::inumeric(FLERR, arg[iarg + 2], false, lmp); + salt_charge[1] = utils::inumeric(FLERR, arg[iarg + 3], false, lmp); + iarg += 4; + } else if (strcmp(arg[iarg + 1], "no") == 0) { + only_salt_flag = false; + iarg += 2; + } else error->all(FLERR, "Illegal fix charge/regulation command"); + + } else if (strcmp(arg[iarg], "group") == 0) { + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix fix charge/regulation command"); + if (ngroups >= ngroupsmax) { + ngroupsmax = ngroups + 1; + groupstrings = (char **) + memory->srealloc(groupstrings, + ngroupsmax * sizeof(char *), + "fix_charge_regulation:groupstrings"); + } + groupstrings[ngroups] = utils::strdup(arg[iarg+1]); + ngroups++; + iarg += 2; + } else error->all(FLERR, "Illegal fix charge/regulation command"); + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double FixChargeRegulation::memory_usage() { + return (double)cr_nmax * sizeof(int); +} diff --git a/src/MC/fix_charge_regulation.h b/src/MC/fix_charge_regulation.h new file mode 100644 index 0000000000..3afaffddb7 --- /dev/null +++ b/src/MC/fix_charge_regulation.h @@ -0,0 +1,118 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Tine Curk (tcurk5@gmail.com) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(charge/regulation,FixChargeRegulation) + +#else + +#ifndef LMP_FIX_CHARGE_REGULATION_H +#define LMP_FIX_CHARGE_REGULATION_H + +#include "fix.h" + +namespace LAMMPS_NS { + + class FixChargeRegulation : public Fix { + public: + FixChargeRegulation(class LAMMPS *, int, char **); + ~FixChargeRegulation(); + int setmask(); + void init(); + void pre_exchange(); + void forward_acid(); + void backward_acid(); + void forward_base(); + void backward_base(); + void forward_ions(); + void forward_ions_multival(); + void backward_ions(); + void backward_ions_multival(); + int get_random_particle(int, double, double, double *); + int insert_particle(int, double, double, double *); + double energy_full(); + int particle_number(int, double); + int particle_number_xrd(int, double, double, double *); + double compute_vector(int n); + void assign_tags(); + void options(int, char **); + void setThermoTemperaturePointer(); + double memory_usage(); + + private: + int exclusion_group, exclusion_group_bit; + int nevery, seed; // begin MC cycle every nevery MD timesteps, random seed + int nmc; // MC move attempts per cycle + double llength_unit_in_nm ; // LAMMPS unit of length in nm, needed since chemical potentials are in units of mol/l + double pH, pKa, pKb, pKs, pI_plus, pI_minus; // chemical potentials and equilibrium constant in log10 base + double c10pH, c10pKa, c10pKb, c10pOH, c10pI_plus, c10pI_minus; // 10 raised to chemical potential value, in units of concentration [mol/liter] + double pmcmoves[3]; // mc move attempt probability: acid, base, ion pair exchange + double pmcc; // mc move cumulative attempt probability + int npart_xrd; // # of particles (ions) within xrd + int npart_xrd2; // # of particles (ions) within xrd + double vlocal_xrd; // # local volume within xrd + bool only_salt_flag; // true if performing only salt insertion/deletion, no acid/base dissociation. + bool add_tags_flag; // true if each inserted atom gets its unique atom tag + int groupbitall; // group bitmask for inserted atoms + int ngroups; // number of group-ids for inserted atoms + char **groupstrings; // list of group-ids for inserted atoms + + // counters + unsigned long int nacid_attempts, nacid_successes, nbase_attempts, nbase_successes, nsalt_attempts, nsalt_successes; + int nacid_neutral, nacid_charged, nbase_neutral, nbase_charged, ncation, nanion; // particle type counts + int cr_nmax; // max number of local particles + double reservoir_temperature; + double beta, sigma, volume, volume_rx; // inverse temperature, speed, total volume, reacting volume + int salt_charge[2]; // charge of salt ions: [0] - cation, [1] - anion + int salt_charge_ratio; // charge ratio when using multivalent ion exchange + double xlo, xhi, ylo, yhi, zlo, zhi; // box size + double energy_stored; // full energy of old/current configuration + int triclinic; // 0 = orthog box, 1 = triclinic + double *sublo, *subhi; // triclinic size + int *ptype_ID; // particle ID array + double overlap_cutoffsq; // square distance cutoff for overlap + int overlap_flag; + int acid_type, cation_type, base_type, anion_type; // reacting atom types + int reaction_distance_flag; // radial reaction restriction flag + double reaction_distance; // max radial distance from acid/base for ion insertion + + + class Pair *pair; + class Compute *c_pe; // energy compute pointer + class RanPark *random_equal; // random number generator + class RanPark *random_unequal; // random number generator + char *idftemp; // pointer to the temperature fix + double *target_temperature_tcp; // current temperature of the thermostat + + }; +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +Self-explanatory. + +*/