From 606b33ea03e824ef9061c5d2f7aa87d0df793c8e Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 16:05:37 -0600 Subject: [PATCH 01/22] Added fix_charge_regulation source code and documentation. --- doc/src/fix_charge_regulation.rst | 184 +++ examples/USER/misc/charge_regulation/README | 7 + .../misc/charge_regulation/data_acid.chreg | 235 +++ .../misc/charge_regulation/data_polymer.chreg | 264 ++++ .../USER/misc/charge_regulation/in_acid.chreg | 40 + .../misc/charge_regulation/in_polymer.chreg | 35 + .../misc/charge_regulation/log_acid.lammps | 163 ++ .../misc/charge_regulation/log_polymer.lammps | 181 +++ src/USER-MISC/README | 1 + src/USER-MISC/fix_charge_regulation.cpp | 1335 +++++++++++++++++ src/USER-MISC/fix_charge_regulation.h | 117 ++ 11 files changed, 2562 insertions(+) create mode 100644 doc/src/fix_charge_regulation.rst create mode 100644 examples/USER/misc/charge_regulation/README create mode 100644 examples/USER/misc/charge_regulation/data_acid.chreg create mode 100644 examples/USER/misc/charge_regulation/data_polymer.chreg create mode 100644 examples/USER/misc/charge_regulation/in_acid.chreg create mode 100644 examples/USER/misc/charge_regulation/in_polymer.chreg create mode 100644 examples/USER/misc/charge_regulation/log_acid.lammps create mode 100644 examples/USER/misc/charge_regulation/log_polymer.lammps create mode 100644 src/USER-MISC/fix_charge_regulation.cpp create mode 100644 src/USER-MISC/fix_charge_regulation.h diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst new file mode 100644 index 0000000000..585761e8a9 --- /dev/null +++ b/doc/src/fix_charge_regulation.rst @@ -0,0 +1,184 @@ + +.. Yuan documentation master file, created by + sphinx-quickstart on Sat Jan 30 14:06:22 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + tc387: Multiple text additions/changes, Feb 2 2021 +.. index:: fix 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 tempfixid fT tag yes onlysalt yes 2 -1 + +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 discreet, 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 simultanously 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 temprature *lunit_nm* = 0.72nm). 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 cumulative 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 acid atoms +* 7 = current # of free cations +* 8 = current # of free anions + + +Restrictions +"""""""""""" +This fix is part of the USER-MISC 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. + +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.72; temp = 1.0; nevery = 100; nmc = 100; xrd = 0; seed = 2345; tag = no; onlysalt = no, pmcmoves = 0.33 0.33 0.33, 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/examples/USER/misc/charge_regulation/README b/examples/USER/misc/charge_regulation/README new file mode 100644 index 0000000000..e0be86d7e4 --- /dev/null +++ b/examples/USER/misc/charge_regulation/README @@ -0,0 +1,7 @@ +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_acid.chreg` 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 `log_acid.lammps`. + +The script `in_polymer.chreg` sets up a weak polyelectrolyte chain of N=80 beads. Each bead is a weak acid with pKa=5 and solution has pH=7 and salt 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 `log_polymer.lammps`. + diff --git a/examples/USER/misc/charge_regulation/data_acid.chreg b/examples/USER/misc/charge_regulation/data_acid.chreg new file mode 100644 index 0000000000..edc7082ad0 --- /dev/null +++ b/examples/USER/misc/charge_regulation/data_acid.chreg @@ -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_polymer.chreg b/examples/USER/misc/charge_regulation/data_polymer.chreg new file mode 100644 index 0000000000..2c5bd3e1ed --- /dev/null +++ b/examples/USER/misc/charge_regulation/data_polymer.chreg @@ -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_acid.chreg b/examples/USER/misc/charge_regulation/in_acid.chreg new file mode 100644 index 0000000000..32beeda732 --- /dev/null +++ b/examples/USER/misc/charge_regulation/in_acid.chreg @@ -0,0 +1,40 @@ +# Charge regulation lammps for simple weak electrolyte + +units lj +atom_style charge +dimension 3 +boundary p p p +processors * * * +neighbor 3.0 bin +read_data data_acid.chreg + +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 ${cut_lj} # charges +kspace_style ewald 1.0e-3 +dielectric 1.0 +pair_modify shift no + +######### 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 10000 diff --git a/examples/USER/misc/charge_regulation/in_polymer.chreg b/examples/USER/misc/charge_regulation/in_polymer.chreg new file mode 100644 index 0000000000..4dc72a8156 --- /dev/null +++ b/examples/USER/misc/charge_regulation/in_polymer.chreg @@ -0,0 +1,35 @@ +# Charge regulation lammps for a polymer chain +units lj +atom_style full +dimension 3 +boundary p p p +processors * * * +neighbor 3.0 bin +read_data data_polymer.chreg + +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 no +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 +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 +fix chareg3 all charge_regulation 4 3 pIp 7.0 pIm 3.0 temp 1.0 nmc 20 + +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 10000 diff --git a/examples/USER/misc/charge_regulation/log_acid.lammps b/examples/USER/misc/charge_regulation/log_acid.lammps new file mode 100644 index 0000000000..cbc3661eb1 --- /dev/null +++ b/examples/USER/misc/charge_regulation/log_acid.lammps @@ -0,0 +1,163 @@ +LAMMPS (24 Dec 2020) +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.001 seconds +Ewald initialization ... + using 12-bit tables for long-range coulomb (../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 Fix_CR: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 = 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 +Setting up Verlet run ... + Unit style : lj + Current step : 0 + Time step : 0.005 +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.054228269 1 0 0 1 99 0 0 109 10 + 100 -0.058672881 0.99159291 100 71 16 84 0 0 92 8 + 200 -0.05399313 0.92006523 200 154 26 74 0 0 85 11 + 300 -0.047035343 0.92728143 300 240 22 78 0 0 85 7 + 400 -0.049597809 1.0617937 400 319 16 84 0 0 92 8 + 500 -0.052409835 1.0006148 500 404 12 88 0 0 97 9 + 600 -0.056012172 0.98059344 600 481 15 85 0 0 92 7 + 700 -0.053639989 0.99572709 700 561 16 84 0 0 94 10 + 800 -0.060026132 0.95764632 800 639 22 78 0 0 84 6 + 900 -0.050785422 0.98399084 900 719 28 72 0 0 82 10 + 1000 -0.062294743 0.97200068 1000 797 26 74 0 0 82 8 + 1100 -0.051269402 1.0064376 1100 877 25 75 0 0 84 9 + 1200 -0.077744839 1.0159098 1200 955 23 77 0 0 88 11 + 1300 -0.084889696 1.1230485 1300 1037 20 80 0 0 90 10 + 1400 -0.059361445 0.96735845 1400 1120 18 82 0 0 93 11 + 1500 -0.052926174 0.95579188 1500 1199 24 76 0 0 86 10 + 1600 -0.052376649 0.99376378 1600 1284 22 78 0 0 89 11 + 1700 -0.052480188 0.96085964 1700 1361 27 73 0 0 84 11 + 1800 -0.065884306 0.96747971 1800 1441 21 79 0 0 84 5 + 1900 -0.054315859 0.95873145 1900 1521 23 77 0 0 84 7 + 2000 -0.037161802 0.93562039 2000 1604 27 73 0 0 79 6 + 2100 -0.034977265 0.97177103 2100 1684 26 74 0 0 85 11 + 2200 -0.047434868 0.97897613 2200 1762 17 83 0 0 93 10 + 2300 -0.047392634 0.96570672 2300 1837 18 82 0 0 92 10 + 2400 -0.044879306 0.98620033 2400 1910 19 81 0 0 89 8 + 2500 -0.069690496 1.0690505 2500 1988 16 84 0 0 91 7 + 2600 -0.081588407 0.97711054 2600 2067 17 83 0 0 92 9 + 2700 -0.06341681 1.0386711 2700 2146 20 80 0 0 85 5 + 2800 -0.045290012 1.0402055 2800 2230 18 82 0 0 91 9 + 2900 -0.046875012 1.0609775 2900 2317 24 76 0 0 86 10 + 3000 -0.031258722 0.93861202 3000 2400 24 76 0 0 85 9 + 3100 -0.04673342 0.90800583 3100 2485 25 75 0 0 90 15 + 3200 -0.054354227 0.94493881 3200 2567 16 84 0 0 94 10 + 3300 -0.053647746 0.92321446 3300 2641 17 83 0 0 94 11 + 3400 -0.031751732 0.93735127 3400 2725 22 78 0 0 92 14 + 3500 -0.053806113 0.98798136 3500 2795 28 72 0 0 84 12 + 3600 -0.040751349 0.84291639 3600 2873 28 72 0 0 84 12 + 3700 -0.051747138 1.072448 3700 2951 24 76 0 0 92 16 + 3800 -0.043420594 1.0076309 3800 3030 26 74 0 0 79 5 + 3900 -0.050845848 1.0250023 3900 3103 29 71 0 0 76 5 + 4000 -0.039837847 1.064111 4000 3182 29 71 0 0 83 12 + 4100 -0.045638995 1.1249685 4100 3262 28 72 0 0 81 9 + 4200 -0.047956491 0.92255907 4200 3348 26 74 0 0 87 13 + 4300 -0.054052822 1.006239 4300 3423 19 81 0 0 90 9 + 4400 -0.053148034 1.0028887 4400 3506 24 76 0 0 83 7 + 4500 -0.062132076 1.0317847 4500 3587 23 77 0 0 82 5 + 4600 -0.04616043 0.99066453 4600 3673 28 72 0 0 82 10 + 4700 -0.066990889 1.0242064 4700 3755 18 82 0 0 90 8 + 4800 -0.0564736 0.91765628 4800 3832 22 78 0 0 91 13 + 4900 -0.052301294 0.95348659 4900 3912 28 72 0 0 81 9 + 5000 -0.062630677 1.0336579 5000 3989 18 82 0 0 92 10 + 5100 -0.053645908 1.0314613 5100 4062 20 80 0 0 85 5 + 5200 -0.062189568 1.0504732 5200 4133 23 77 0 0 84 7 + 5300 -0.049092746 1.0310832 5300 4217 24 76 0 0 82 6 + 5400 -0.051859257 0.99600428 5400 4299 27 73 0 0 80 7 + 5500 -0.065540815 0.98012128 5500 4381 19 81 0 0 92 11 + 5600 -0.071018582 0.9252814 5600 4455 23 77 0 0 84 7 + 5700 -0.066954185 1.0325214 5700 4535 26 74 0 0 82 8 + 5800 -0.064847249 1.0313536 5800 4617 21 79 0 0 90 11 + 5900 -0.063173056 0.95455853 5900 4703 18 82 0 0 92 10 + 6000 -0.064807837 0.97182222 6000 4790 21 79 0 0 91 12 + 6100 -0.07067683 0.91775921 6100 4875 16 84 0 0 94 10 + 6200 -0.071400842 1.0162225 6200 4952 17 83 0 0 87 4 + 6300 -0.078479449 1.0106706 6300 5033 21 79 0 0 84 5 + 6400 -0.083167651 1.0246584 6400 5111 18 82 0 0 90 8 + 6500 -0.092611537 1.0766467 6500 5195 20 80 0 0 88 8 + 6600 -0.096710071 1.0246648 6600 5274 15 85 0 0 91 6 + 6700 -0.073399857 0.94939392 6700 5351 17 83 0 0 92 9 + 6800 -0.062479375 0.9393967 6800 5434 18 82 0 0 93 11 + 6900 -0.065391043 0.93475954 6900 5514 22 78 0 0 89 11 + 7000 -0.045655499 0.98688239 7000 5601 21 79 0 0 90 11 + 7100 -0.061186309 1.0309063 7100 5684 22 78 0 0 87 9 + 7200 -0.074737514 1.0516593 7200 5769 25 75 0 0 80 5 + 7300 -0.075228979 1.0167704 7300 5847 21 79 0 0 86 7 + 7400 -0.06660147 1.0947107 7400 5930 25 75 0 0 87 12 + 7500 -0.071915247 1.10542 7500 6009 24 76 0 0 84 8 + 7600 -0.029974303 0.99202697 7600 6095 28 72 0 0 80 8 + 7700 -0.029024004 1.0390995 7700 6182 28 72 0 0 83 11 + 7800 -0.056250746 0.96393961 7800 6260 18 82 0 0 91 9 + 7900 -0.072178944 0.9833919 7900 6339 21 79 0 0 86 7 + 8000 -0.070377248 1.021342 8000 6419 23 77 0 0 88 11 + 8100 -0.07753283 0.96194312 8100 6493 26 74 0 0 86 12 + 8200 -0.075617309 0.9715344 8200 6576 25 75 0 0 89 14 + 8300 -0.077480013 0.99106705 8300 6662 20 80 0 0 91 11 + 8400 -0.079901928 0.89855112 8400 6744 23 77 0 0 91 14 + 8500 -0.069192745 1.0606791 8500 6822 19 81 0 0 91 10 + 8600 -0.058657202 1.1270217 8600 6898 15 85 0 0 95 10 + 8700 -0.044985397 1.0367419 8700 6979 27 73 0 0 84 11 + 8800 -0.064266376 0.91557003 8800 7060 21 79 0 0 89 10 + 8900 -0.068680533 0.95963643 8900 7133 19 81 0 0 88 7 + 9000 -0.051736144 1.0398547 9000 7213 13 87 0 0 94 7 + 9100 -0.058381436 0.98047663 9100 7290 17 83 0 0 89 6 + 9200 -0.05531014 0.92541631 9200 7368 22 78 0 0 85 7 + 9300 -0.04386907 0.9339658 9300 7454 22 78 0 0 89 11 + 9400 -0.052293168 0.94314034 9400 7539 22 78 0 0 86 8 + 9500 -0.050362046 1.0489028 9500 7617 18 82 0 0 90 8 + 9600 -0.054272227 1.0879161 9600 7697 11 89 0 0 96 7 + 9700 -0.042514179 1.0051505 9700 7771 22 78 0 0 84 6 + 9800 -0.045365018 0.95363669 9800 7850 25 75 0 0 77 2 + 9900 -0.064287274 0.91994667 9900 7928 27 73 0 0 81 8 + 10000 -0.05689162 0.99963208 10000 8011 22 78 0 0 84 6 +Loop time of 19.4452 on 1 procs for 10000 steps with 190 atoms + +Performance: 222162.510 tau/day, 514.265 timesteps/s +99.9% 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.68864 | 0.68864 | 0.68864 | 0.0 | 3.54 +Kspace | 6.7893 | 6.7893 | 6.7893 | 0.0 | 34.92 +Neigh | 0.060782 | 0.060782 | 0.060782 | 0.0 | 0.31 +Comm | 0.047035 | 0.047035 | 0.047035 | 0.0 | 0.24 +Output | 0.0027227 | 0.0027227 | 0.0027227 | 0.0 | 0.01 +Modify | 11.838 | 11.838 | 11.838 | 0.0 | 60.88 +Other | | 0.01878 | | | 0.10 + +Nlocal: 190.000 ave 190 max 190 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 592.000 ave 592 max 592 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2194.00 ave 2194 max 2194 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2194 +Ave neighs/atom = 11.547368 +Neighbor list builds = 10287 +Dangerous builds = 0 +Total wall time: 0:00:19 \ No newline at end of file diff --git a/examples/USER/misc/charge_regulation/log_polymer.lammps b/examples/USER/misc/charge_regulation/log_polymer.lammps new file mode 100644 index 0000000000..87cab63a6c --- /dev/null +++ b/examples/USER/misc/charge_regulation/log_polymer.lammps @@ -0,0 +1,181 @@ +LAMMPS (24 Dec 2020) +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.000 seconds + read_data CPU = 0.004 seconds +PPPM initialization ... + using 12-bit tables for long-range coulomb (../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 KISS FFT + 3d grid and FFT values/proc = 2197 512 +0 atoms in group Fix_CR:exclusion_group:chareg1 +0 atoms in group Fix_CR:exclusion_group:chareg2 +0 atoms in group Fix_CR:exclusion_group:chareg3 +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 = 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 +Setting up Verlet run ... + Unit style : lj + Current step : 0 + Time step : 0.005 +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.49903297 1 0 80 80 0 0 0 + 100 0.63380666 0.87307225 8 72 77 6 1 0 + 200 0.5865464 1.0048645 16 64 81 16 0 1 + 300 0.55802913 1.0499142 19 61 91 29 0 1 + 400 0.44734087 1.0838048 24 56 98 41 0 1 + 500 0.47010775 1.005226 23 57 106 48 0 1 + 600 0.3452105 0.97814306 28 52 109 56 0 1 + 700 0.29208955 0.99766419 32 48 115 67 0 0 + 800 0.27821915 1.0091641 31 49 128 80 1 0 + 900 0.28943788 0.93619239 26 54 145 91 0 0 + 1000 0.22963142 1.0162138 27 53 150 97 0 0 + 1100 0.24238916 0.99146577 31 49 149 100 0 0 + 1200 0.17029095 1.0406453 38 42 144 102 0 0 + 1300 0.15830969 0.94661447 34 46 155 109 0 0 + 1400 0.16698712 1.0116563 35 45 159 114 0 0 + 1500 0.15432936 0.95600941 36 44 162 118 0 0 + 1600 0.16973501 0.98326602 31 49 171 122 0 0 + 1700 0.19725116 0.9915273 33 47 175 128 0 0 + 1800 0.15278999 1.0304873 29 51 193 142 0 0 + 1900 0.17418479 0.99490216 30 50 194 144 0 0 + 2000 0.14238391 0.9638301 32 48 189 141 0 0 + 2100 0.13054378 0.97164976 32 48 192 144 0 0 + 2200 0.092083069 1.0112059 40 40 191 151 0 0 + 2300 0.085175091 1.0070667 39 41 200 159 0 0 + 2400 0.083367076 0.9934796 35 45 208 163 0 0 + 2500 0.11494744 0.97650855 31 49 220 172 1 0 + 2600 0.10796032 0.97047046 34 46 221 175 0 0 + 2700 0.11080141 0.93570013 36 44 223 179 0 0 + 2800 0.096699277 0.97702627 35 45 223 178 0 0 + 2900 0.079403783 1.0870961 32 48 229 181 0 0 + 3000 0.08288836 1.0642515 35 45 231 186 0 0 + 3100 0.094000833 1.0241111 38 42 229 187 0 0 + 3200 0.10011052 1.043594 34 46 235 189 0 0 + 3300 0.096782103 0.99549134 34 46 234 188 0 0 + 3400 0.057703946 1.00292 34 46 236 190 0 0 + 3500 0.074345642 0.95064523 36 44 234 190 0 0 + 3600 0.085872341 0.9759514 35 45 238 192 0 1 + 3700 0.086427565 0.99843063 35 45 240 194 0 1 + 3800 0.076091357 0.98516844 32 48 252 203 0 1 + 3900 0.047187813 1.0063336 37 43 247 204 0 0 + 4000 0.068269223 1.0390369 35 45 248 203 0 0 + 4100 0.074209582 0.99912762 36 44 249 205 0 0 + 4200 0.087016078 1.050265 36 44 246 202 0 0 + 4300 0.081325479 1.0417103 35 45 245 200 0 0 + 4400 0.047345973 0.96517298 39 41 243 202 0 0 + 4500 0.041856955 0.94569673 38 42 245 203 0 0 + 4600 0.049588267 0.99046371 42 38 249 211 0 0 + 4700 0.043079897 1.0098538 43 37 245 208 0 0 + 4800 0.049122913 1.0229995 41 39 247 208 0 0 + 4900 0.059151797 1.0236679 36 44 249 205 0 0 + 5000 0.053806841 1.0308397 42 38 243 205 0 0 + 5100 0.053623833 1.0638841 39 41 246 205 0 0 + 5200 0.086215806 1.0027613 37 43 243 200 0 0 + 5300 0.031422797 1.0338154 38 42 245 203 0 0 + 5400 0.051341116 0.92205149 34 46 246 200 0 0 + 5500 0.039292708 0.97530704 32 48 251 203 0 0 + 5600 0.035215415 1.023123 33 47 246 199 0 0 + 5700 0.054553598 0.95833063 30 50 253 203 0 0 + 5800 0.035699456 1.0721613 37 43 248 205 0 0 + 5900 0.062426908 1.0612245 38 42 252 210 0 0 + 6000 0.056362902 1.0002968 36 44 248 204 0 0 + 6100 0.061550208 0.97270904 38 42 245 203 0 0 + 6200 0.051825485 0.98187623 36 44 253 209 0 0 + 6300 0.052137885 0.98906723 36 44 253 210 1 0 + 6400 0.068218075 1.0511584 36 44 256 212 0 0 + 6500 0.080167413 0.97270144 36 44 252 208 0 0 + 6600 0.052169204 1.0160108 41 39 249 210 0 0 + 6700 0.057313326 0.98033894 38 42 251 209 0 0 + 6800 0.073008094 0.96239565 35 45 256 211 0 0 + 6900 0.060159599 1.0063892 37 43 264 221 0 0 + 7000 0.061738744 1.0031443 39 41 259 218 0 0 + 7100 0.043263424 1.0425248 44 36 255 219 0 0 + 7200 0.052179167 0.99512151 39 41 261 220 0 0 + 7300 0.053258707 1.0171204 43 37 256 219 0 0 + 7400 0.026037532 0.93786837 45 35 259 224 0 0 + 7500 0.029731213 1.0172281 46 34 250 216 0 0 + 7600 0.023118288 0.95628439 42 38 262 224 0 0 + 7700 0.037021854 0.99991854 42 38 263 225 0 0 + 7800 0.050404736 1.0130826 40 40 260 220 0 0 + 7900 0.035658921 0.95772506 40 40 259 219 0 0 + 8000 0.034426806 1.0028052 40 40 254 214 0 0 + 8100 0.041427611 1.0347682 40 40 256 216 0 0 + 8200 0.05986843 0.9804614 38 42 262 220 0 0 + 8300 0.041419023 1.0613186 37 43 264 221 0 0 + 8400 0.065701758 1.0511531 40 40 256 216 0 0 + 8500 0.091954526 0.97190676 37 43 257 214 0 0 + 8600 0.056982532 1.017813 35 45 252 207 0 0 + 8700 0.075615111 1.0148527 29 51 263 212 0 0 + 8800 0.066070082 1.0259454 33 47 260 213 0 0 + 8900 0.055054194 1.0183535 37 43 247 204 0 0 + 9000 0.063070816 1.0266115 39 41 244 203 0 0 + 9100 0.10174156 0.99457684 34 46 246 200 0 0 + 9200 0.071667261 1.033159 33 47 249 202 0 0 + 9300 0.05520096 0.99821492 38 42 243 201 0 0 + 9400 0.050355422 0.99148522 37 43 243 200 0 0 + 9500 0.062314961 1.0042937 36 44 252 208 0 0 + 9600 0.061148899 1.0052132 37 43 254 211 0 0 + 9700 0.078695273 1.0175164 37 43 252 209 0 0 + 9800 0.067487202 1.0110138 35 45 258 213 0 0 + 9900 0.070340779 0.99640142 31 49 263 214 0 0 + 10000 0.037252172 0.99863894 32 48 259 211 0 0 +Loop time of 23.0419 on 1 procs for 10000 steps with 550 atoms + +Performance: 187484.206 tau/day, 433.991 timesteps/s +100.0% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.5444 | 2.5444 | 2.5444 | 0.0 | 11.04 +Bond | 0.025075 | 0.025075 | 0.025075 | 0.0 | 0.11 +Kspace | 4.7385 | 4.7385 | 4.7385 | 0.0 | 20.56 +Neigh | 0.2058 | 0.2058 | 0.2058 | 0.0 | 0.89 +Comm | 0.073087 | 0.073087 | 0.073087 | 0.0 | 0.32 +Output | 0.003464 | 0.003464 | 0.003464 | 0.0 | 0.02 +Modify | 15.417 | 15.417 | 15.417 | 0.0 | 66.91 +Other | | 0.03479 | | | 0.15 + +Nlocal: 550.000 ave 550 max 550 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1023.00 ave 1023 max 1023 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 9644.00 ave 9644 max 9644 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 9644 +Ave neighs/atom = 17.534545 +Ave special neighs/atom = 0.85090909 +Neighbor list builds = 7576 +Dangerous builds = 0 +Total wall time: 0:00:23 \ No newline at end of file diff --git a/src/USER-MISC/README b/src/USER-MISC/README index 314fe6146e..ef25a0c116 100644 --- a/src/USER-MISC/README +++ b/src/USER-MISC/README @@ -53,6 +53,7 @@ dihedral_style table/cut, Mike Salerno, ksalerno@pha.jhu.edu, 11 May 18 fix accelerate/cos, Zheng Gong (ENS de Lyon), z.gong@outlook.com, 24 Apr 20 fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11 fix ave/correlate/long, Jorge Ramirez (UPM Madrid), jorge.ramirez at upm.es, 21 Oct 2015 +fix charge_regulation, Tine Curk and Jiaxing Yuan, tcurk5@gmail.com, 02 Feb 2021 fix electron/stopping/fit, James Stewart (SNL), jstewa .at. sandia.gov, 23 Sep 2020 fix electron/stopping, Konstantin Avchaciov, k.avchachov at gmail.com, 26 Feb 2019 fix ffl, David Wilkins (EPFL Lausanne), david.wilkins @ epfl.ch, 28 Sep 2018 diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp new file mode 100644 index 0000000000..3bb9de1b27 --- /dev/null +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -0,0 +1,1335 @@ +/* ---------------------------------------------------------------------- + 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 +#include +#include +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "comm.h" +#include "compute.h" +#include "group.h" +#include "domain.h" +#include "region.h" +#include "random_park.h" +#include "force.h" +#include "pair.h" +#include "bond.h" +#include "angle.h" +#include "dihedral.h" +#include "improper.h" +#include "kspace.h" +#include "math_extra.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" +#include "neighbor.h" + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +// large energy value used to signal overlap +#define MAXENERGYSIGNAL 1.0e100 +#define MAXENERGYTEST 1.0e50 +#define small 0.0000001 +#define PI 3.1415926 + +/* ---------------------------------------------------------------------- */ +Fix_charge_regulation::Fix_charge_regulation(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), + ngroups(0), groupstrings(NULL), + random_equal(NULL), random_unequal(NULL), + idftemp(NULL), ptype_ID(NULL) { + + // 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) error->all(FLERR, "Illegal fix charge_regulation command"); + if (nmc < 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (llength_unit_in_nm < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (*target_temperature_tcp < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (seed <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (cation_type <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (anion_type <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (reaction_distance < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (salt_charge[0] <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (salt_charge[1] >= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + 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; +} + +Fix_charge_regulation::~Fix_charge_regulation() { + + memory->destroy(ptype_ID); + + delete random_equal; + delete random_unequal; + + if (group) { + int igroupall = group->find("all"); + neighbor->exclusion_group_group_delete(exclusion_group, igroupall); + } +} + +int Fix_charge_regulation::setmask() { + int mask = 0; + mask |= PRE_EXCHANGE; + return mask; +} + +void Fix_charge_regulation::init() { + + triclinic = domain->triclinic; + + char *id_pe = (char *) "thermo_pe"; + int ipe = modify->find_compute(id_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) { + char **group_arg = new char *[4]; + + // create unique group name for atoms to be excluded + int len = strlen(id) + 30; + group_arg[0] = new char[len]; + sprintf(group_arg[0], "Fix_CR:exclusion_group:%s", id); + group_arg[1] = (char *) "subtract"; + group_arg[2] = (char *) "all"; + group_arg[3] = (char *) "all"; + group->assign(4, group_arg); + exclusion_group = group->find(group_arg[0]); + if (exclusion_group == -1) + error->all(FLERR, "Could not find fix CR 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] = group_arg[0]; + arg[3] = (char *) "all"; + neighbor->modify_params(narg, arg); + delete[] group_arg[0]; + delete[] group_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 do 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 specified fix charge regulation group ID"); + groupbitall |= group->bitmask[jgroup]; + } +} + +void Fix_charge_regulation::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) + error->warning(FLERR, "Energy of old configuration in fix charge_regulation is > MAXENERGYTEST."); + + if ((reaction_distance > fabs(domain->boxhi[0] - domain->boxlo[0]) / 2) || + (reaction_distance > fabs(domain->boxhi[1] - domain->boxlo[1]) / 2) || + (reaction_distance > fabs(domain->boxhi[2] - domain->boxlo[2]) / 2)) { + 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) * pow(llength_unit_in_nm, 3) * 0.602214; + if (reaction_distance < small) { + vlocal_xrd = volume_rx; + } else { + vlocal_xrd = 4.0 * PI * pow(reaction_distance, 3) / 3.0 * pow(llength_unit_in_nm, 3) * 0.602214; + } + beta = 1.0 / (force->boltz * *target_temperature_tcp); + + // 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 Fix_charge_regulation::forward_acid() { + + double energy_before = energy_stored; + double factor; + double *dummyp; + 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 * pow(10, -pKa) + * (1 + pow(10, pH - pI_plus)) / ((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 Fix_charge_regulation::backward_acid() { + + double energy_before = energy_stored; + double factor; + int mask_tmp; + double *dummyp; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m1_all = -1, m2 = -1, m2_all = -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 * pow(10, -pKa) + * (1 + pow(10, pH - pI_plus)) / (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 Fix_charge_regulation::forward_base() { + + double energy_before = energy_stored; + double factor; + double *dummyp; + double pos[3]; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; // acid/base particle position + double pos_all[3]; + int m1 = -1, m1_all = -1, m2 = -1, m2_all = -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 * pow(10, -pKb) + * (1 + pow(10, pKs - pH - pI_minus)) / + ((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 Fix_charge_regulation::backward_base() { + + double energy_before = energy_stored; + double factor; + double *dummyp; + 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, m1_all = -1, m2 = -1, m2_all = -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 * pow(10, -pKb) + * (1 + pow(10, pKs - pH - pI_minus)) / (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 Fix_charge_regulation::forward_ions() { + + double energy_before = energy_stored; + double factor; + double *dummyp; + int m1 = -1, m2 = -1; + factor = volume_rx * volume_rx * (pow(10, -pH) + pow(10, -pI_plus)) + * (pow(10, -pKs + pH) + pow(10, -pI_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 Fix_charge_regulation::backward_ions() { + + double energy_before = energy_stored; + double factor; + int mask1_tmp, mask2_tmp; + double *dummyp; // dummy pointer + 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 * (pow(10, -pH) + pow(10, -pI_plus)) * + (pow(10, -pKs + pH) + pow(10, -pI_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; + } + } + } else { + // reassign original charge and mask + if (m1 >= 0) { + atom->q[m1] = 1; + atom->mask[m1] = mask1_tmp; + } + } + } +} + +void Fix_charge_regulation::forward_ions_multival() { + + double energy_before = energy_stored; + double factor = 1; + double *dummyp; + 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 * pow(10, -pI_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 * pow(10, -pI_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 * pow(10, -pI_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 * pow(10, -pI_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 Fix_charge_regulation::backward_ions_multival() { + + double energy_before = energy_stored; + double factor = 1; + double *dummyp; // 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 * pow(10, -pI_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 * pow(10, -pI_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 * pow(10, -pI_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 * pow(10, -pI_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 Fix_charge_regulation::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 { + double radius = reaction_distance * random_equal->uniform(); + double theta = random_equal->uniform() * PI; + double phi = random_equal->uniform() * 2 * PI; + coord[0] = target[0] + radius * sin(theta) * cos(phi); + coord[1] = target[1] + radius * sin(theta) * sin(phi); + coord[2] = target[2] + radius * cos(theta); + 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 Fix_charge_regulation::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 geometry 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 Fix_charge_regulation::energy_full() { + int imolecule; + 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; + tagint *molecule = atom->molecule; + 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_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 Fix_charge_regulation::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 Fix_charge_regulation::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 Fix_charge_regulation::compute_vector(int n) { + double count_temp = 0; + 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 Fix_charge_regulation::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 Fix_charge_regulation::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 Fix_charge_regulation::options(int narg, char **arg) { + if (narg < 0) error->all(FLERR, "Illegal fix charge regulation command"); + + // defaults + + pH = 7.0; + pI_plus = 100; + pI_minus = 100; + acid_type = -1; + base_type = -1; + pKa = 100; + pKb = 100; + pKs = 14.0; + nevery = 100; + nmc = 100; + pmcmoves[0] = pmcmoves[1] = pmcmoves[2] = 0.33; + llength_unit_in_nm= 0.72; + + reservoir_temperature = 1.0; + reaction_distance = 0; + seed = 12345; + 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 = NULL; + + 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"); + int n = strlen(arg[iarg + 1]) + 1; + delete[] idftemp; + idftemp = new char[n]; + strcpy(idftemp, 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 > fabs(domain->boxhi[0] - domain->boxlo[0]) / 2) || + (reaction_distance > fabs(domain->boxhi[1] - domain->boxlo[1]) / 2) || + (reaction_distance > fabs(domain->boxhi[2] - domain->boxlo[2]) / 2)) { + 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::numeric(FLERR, arg[iarg + 2], false, lmp); + salt_charge[1] = utils::numeric(FLERR, arg[iarg + 3], false, lmp); + if (fabs(salt_charge[0] - utils::inumeric(FLERR, arg[iarg + 2], false, lmp)) > small) + error->all(FLERR, "Illegal fix charge regulation command, cation charge must be an integer"); + if (fabs(salt_charge[1] - utils::inumeric(FLERR, arg[iarg + 3], false, lmp)) > small) + error->all(FLERR, "Illegal fix charge regulation command, anion charge must be an integer"); + 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"); + } + int n = strlen(arg[iarg + 1]) + 1; + groupstrings[ngroups] = new char[n]; + strcpy(groupstrings[ngroups], arg[iarg + 1]); + ngroups++; + iarg += 2; + } else { error->all(FLERR, "Illegal fix charge regulation command"); } + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double Fix_charge_regulation::memory_usage() { + double bytes = cr_nmax * sizeof(int); + return bytes; +} diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/USER-MISC/fix_charge_regulation.h new file mode 100644 index 0000000000..280a6c0d49 --- /dev/null +++ b/src/USER-MISC/fix_charge_regulation.h @@ -0,0 +1,117 @@ +/* -*- 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 (curk@northwestern.edu) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(charge_regulation,Fix_charge_regulation) + +#else + +#ifndef LMP_FIX_charge_regulation_H +#define LMP_FIX_charge_regulation_H + +#include "fix.h" + +namespace LAMMPS_NS { + + class Fix_charge_regulation : public Fix { + public: + Fix_charge_regulation(class LAMMPS *, int, char **); + ~Fix_charge_regulation(); + 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 ngcmc_type, nevery, seed; + int nmc; // mc moves 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 + double pmcmoves[3]; // mc move attempt probability, acid, base, salt; and comulative + 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; + 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; + double reaction_distance; // max radial distance for atom 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. + +*/ From 6d862569ea8ab8f44e68207bd41adfe8a28a5e2b Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 16:24:55 -0600 Subject: [PATCH 02/22] Updated emails --- src/USER-MISC/fix_charge_regulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/USER-MISC/fix_charge_regulation.h index 280a6c0d49..f0151390e6 100644 --- a/src/USER-MISC/fix_charge_regulation.h +++ b/src/USER-MISC/fix_charge_regulation.h @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Tine Curk (curk@northwestern.edu) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) + Contributing author: Tine Curk (tcurk5@gmail.com) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) ------------------------------------------------------------------------- */ #ifdef FIX_CLASS From d62ba49f1a431b920cb29e0dce8f23b4a9815f26 Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 16:57:00 -0600 Subject: [PATCH 03/22] added minor comments --- src/USER-MISC/fix_charge_regulation.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/USER-MISC/fix_charge_regulation.h index f0151390e6..e64ea6b63f 100644 --- a/src/USER-MISC/fix_charge_regulation.h +++ b/src/USER-MISC/fix_charge_regulation.h @@ -60,7 +60,7 @@ namespace LAMMPS_NS { int nmc; // mc moves 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 - double pmcmoves[3]; // mc move attempt probability, acid, base, salt; and comulative + 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 @@ -70,6 +70,7 @@ namespace LAMMPS_NS { 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 @@ -77,7 +78,7 @@ namespace LAMMPS_NS { 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; + int salt_charge_ratio; // charge ration 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 @@ -86,16 +87,15 @@ namespace LAMMPS_NS { 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; - double reaction_distance; // max radial distance for atom insertion + 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 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 - + char *idftemp; // pointer to the temperature fix double *target_temperature_tcp; // current temperature of the thermostat }; From 0bc31fad0922d3f3f76ec5fdd894714112a75826 Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 17:03:15 -0600 Subject: [PATCH 04/22] header file minor cleanup --- src/USER-MISC/fix_charge_regulation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/USER-MISC/fix_charge_regulation.h index e64ea6b63f..d698bd6bb7 100644 --- a/src/USER-MISC/fix_charge_regulation.h +++ b/src/USER-MISC/fix_charge_regulation.h @@ -56,8 +56,8 @@ namespace LAMMPS_NS { private: int exclusion_group, exclusion_group_bit; - int ngcmc_type, nevery, seed; - int nmc; // mc moves per cycle + 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 double pmcmoves[3]; // mc move attempt probability: acid, base, ion pair exchange From 2f5588733bf752bef213e0ea47e6c04cc9516df1 Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 18:47:04 -0600 Subject: [PATCH 05/22] fixed doc Latex error --- doc/src/fix_charge_regulation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst index 585761e8a9..d2384fdc13 100644 --- a/doc/src/fix_charge_regulation.rst +++ b/doc/src/fix_charge_regulation.rst @@ -70,7 +70,7 @@ The last type of reaction performs grand canonical MC exchange of ion pairs with 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. +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 From 4421843604c090ef8e776ca32bdab2a6da74f33b Mon Sep 17 00:00:00 2001 From: tc387 Date: Fri, 5 Feb 2021 19:00:33 -0600 Subject: [PATCH 06/22] fixed Latex doc error #2 --- doc/src/fix_charge_regulation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst index d2384fdc13..a98288eb51 100644 --- a/doc/src/fix_charge_regulation.rst +++ b/doc/src/fix_charge_regulation.rst @@ -106,7 +106,7 @@ If neither the acid or the base type is specified, for example, 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. +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: From 60113a6ddf92566d4eee3ba03dc960795f1471c5 Mon Sep 17 00:00:00 2001 From: tc387 Date: Wed, 10 Feb 2021 13:24:30 -0600 Subject: [PATCH 07/22] Applied edits/optimizations suggested by Axel. Further simplifified/fixed MC acceptance equations, few clarifications to documentation. --- doc/src/fix_charge_regulation.rst | 38 ++- examples/USER/misc/charge_regulation/README | 5 +- .../USER/misc/charge_regulation/in_acid.chreg | 7 +- .../misc/charge_regulation/in_polymer.chreg | 12 +- src/USER-MISC/fix_charge_regulation.cpp | 282 ++++++++++-------- src/USER-MISC/fix_charge_regulation.h | 17 +- 6 files changed, 193 insertions(+), 168 deletions(-) diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst index a98288eb51..cb9f55c7cd 100644 --- a/doc/src/fix_charge_regulation.rst +++ b/doc/src/fix_charge_regulation.rst @@ -1,22 +1,18 @@ -.. Yuan documentation master file, created by - sphinx-quickstart on Sat Jan 30 14:06:22 2021. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - tc387: Multiple text additions/changes, Feb 2 2021 -.. index:: fix fix_charge_regulation +.. index:: fix charge/regulation -fix_charge_regulation command +fix charge/regulation command ============================= + Syntax """""" .. parsed-literal:: - fix ID group-ID charge_regulation cation_type anion_type keyword value(s) + 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 +* charge/regulation = style name of this fix command * cation_type = atom type of free cations * anion_type = atom type of free anions @@ -51,9 +47,9 @@ 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 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 tempfixid fT tag yes onlysalt yes 2 -1 + fix chareg all charge/regulation 1 2 pIp 3 pIm 3 onlysalt yes 2 -1 seed 123 tag yes temp 1.0 Description """"""""""" @@ -75,7 +71,7 @@ An acid ionization reaction (:math:`\mathrm{A} \rightleftharpoons \mathrm{A}^-+\ .. 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 + 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. @@ -85,7 +81,7 @@ 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 + 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. @@ -94,14 +90,14 @@ where particles of atom type 4 and 5 are the salt cations and anions, both at ch .. 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 + 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 + 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. @@ -119,7 +115,7 @@ Note that LAMMPS implicitly assumes a constant number of particles (degrees of f 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 temprature *lunit_nm* = 0.72nm). For example, in the dilute ideal solution limit, the concentration of free ions +must be specified via *lunit_nm* (default is set to the Bjerrum length in water at room temprature *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*. @@ -138,14 +134,14 @@ The *group* keyword can be used to add inserted particles to a specific group-ID 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 cumulative quantities: +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 acid atoms +* 6 = current # of +1 charged base atoms * 7 = current # of free cations * 8 = current # of free anions @@ -157,6 +153,8 @@ 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 @@ -167,7 +165,7 @@ Related commands 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.72; temp = 1.0; nevery = 100; nmc = 100; xrd = 0; seed = 2345; tag = no; onlysalt = no, pmcmoves = 0.33 0.33 0.33, group-ID = all +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 ---------- @@ -181,4 +179,4 @@ pH = 7.0; pKa = 100.0; pKb = 100.0; pIp = 5.0; pIm = 5.0; pKs=14.0; acid_type = .. _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). +**(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/examples/USER/misc/charge_regulation/README b/examples/USER/misc/charge_regulation/README index e0be86d7e4..5666d6d025 100644 --- a/examples/USER/misc/charge_regulation/README +++ b/examples/USER/misc/charge_regulation/README @@ -2,6 +2,7 @@ This directory has two input scripts that illustrates how to use fix charge_regu The script `in_acid.chreg` 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 `log_acid.lammps`. -The script `in_polymer.chreg` sets up a weak polyelectrolyte chain of N=80 beads. Each bead is a weak acid with pKa=5 and solution has pH=7 and salt 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 `log_polymer.lammps`. +The script `in_polymer.chreg` sets up a weak polyelectrolyte 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 `log_polymer.lammps`. diff --git a/examples/USER/misc/charge_regulation/in_acid.chreg b/examples/USER/misc/charge_regulation/in_acid.chreg index 32beeda732..73a40f7389 100644 --- a/examples/USER/misc/charge_regulation/in_acid.chreg +++ b/examples/USER/misc/charge_regulation/in_acid.chreg @@ -24,7 +24,7 @@ pair_style lj/cut/coul/long ${cut_lj} ${cut_long} pair_coeff * * 1.0 1.0 ${cut_lj} # charges kspace_style ewald 1.0e-3 dielectric 1.0 -pair_modify shift no +pair_modify shift yes ######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### fix fnve all nve @@ -33,8 +33,9 @@ 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 ${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] +log log_acid.lammps timestep 0.005 -run 10000 +run 20000 diff --git a/examples/USER/misc/charge_regulation/in_polymer.chreg b/examples/USER/misc/charge_regulation/in_polymer.chreg index 4dc72a8156..e35ba28661 100644 --- a/examples/USER/misc/charge_regulation/in_polymer.chreg +++ b/examples/USER/misc/charge_regulation/in_polymer.chreg @@ -14,7 +14,7 @@ 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 no +pair_modify shift yes dielectric 1.0 ######### VERLET INTEGRATION WITH LANGEVIN THERMOSTAT ########### @@ -24,12 +24,14 @@ 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 -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 -fix chareg3 all charge_regulation 4 3 pIp 7.0 pIm 3.0 temp 1.0 nmc 20 +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] +log log_polymer.lammps + timestep 0.005 -run 10000 +run 20000 diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp index 3bb9de1b27..c43a509f61 100644 --- a/src/USER-MISC/fix_charge_regulation.cpp +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -15,50 +15,56 @@ Contributing author: Tine Curk (tcurk5@gmail.com) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) ------------------------------------------------------------------------- */ #include "fix_charge_regulation.h" -#include -#include -#include + +#include "angle.h" #include "atom.h" #include "atom_vec.h" -#include "molecule.h" -#include "update.h" -#include "modify.h" -#include "fix.h" +#include "bond.h" #include "comm.h" #include "compute.h" -#include "group.h" -#include "domain.h" -#include "region.h" -#include "random_park.h" -#include "force.h" -#include "pair.h" -#include "bond.h" -#include "angle.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_extra.h" #include "math_const.h" +#include "math_extra.h" +#include "math_special.h" #include "memory.h" -#include "error.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 PI 3.1415926 +#define SMALL 0.0000001 +#define NA_RHO0 0.602214 // Avogadro's constant times reference concentration (N_A * mol / liter) [nm^-3] /* ---------------------------------------------------------------------- */ -Fix_charge_regulation::Fix_charge_regulation(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - ngroups(0), groupstrings(NULL), - random_equal(NULL), random_unequal(NULL), - idftemp(NULL), ptype_ID(NULL) { + +FixChargeRegulation::FixChargeRegulation(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), + ngroups(0), groupstrings(NULL), + random_equal(NULL), random_unequal(NULL), + idftemp(NULL), ptype_ID(NULL) + { // Region restrictions not yet implemented .. @@ -79,28 +85,28 @@ Fix_charge_regulation::Fix_charge_regulation(LAMMPS *lmp, int narg, char **arg) // set defaults and read optional arguments options(narg - 5, &arg[5]); - if (nevery <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (nmc < 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (llength_unit_in_nm < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (*target_temperature_tcp < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (seed <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (cation_type <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (anion_type <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (reaction_distance < 0.0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (salt_charge[0] <= 0) error->all(FLERR, "Illegal fix charge_regulation command"); - if (salt_charge[1] >= 0) error->all(FLERR, "Illegal fix charge_regulation command"); + if (nevery <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (nmc < 0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (llength_unit_in_nm < 0.0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (*target_temperature_tcp < 0.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 (cation_type <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (anion_type <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (reaction_distance < 0.0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (salt_charge[0] <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); + if (salt_charge[1] >= 0) error->all(FLERR, "Illegal fix charge/regulation command"); 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, " + "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"); + 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"); + if (psum <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); pmcmoves[0] /= psum; pmcmoves[1] /= psum; pmcmoves[2] /= psum; @@ -117,7 +123,7 @@ Fix_charge_regulation::Fix_charge_regulation(LAMMPS *lmp, int narg, char **arg) nsalt_successes = 0; } -Fix_charge_regulation::~Fix_charge_regulation() { +FixChargeRegulation::~FixChargeRegulation() { memory->destroy(ptype_ID); @@ -130,18 +136,16 @@ Fix_charge_regulation::~Fix_charge_regulation() { } } -int Fix_charge_regulation::setmask() { +int FixChargeRegulation::setmask() { int mask = 0; mask |= PRE_EXCHANGE; return mask; } -void Fix_charge_regulation::init() { +void FixChargeRegulation::init() { - triclinic = domain->triclinic; - - char *id_pe = (char *) "thermo_pe"; - int ipe = modify->find_compute(id_pe); + triclinic = domain->triclinic; + int ipe = modify->find_compute("thermo_pe"); c_pe = modify->compute[ipe]; if (atom->molecule_flag) { @@ -165,34 +169,27 @@ void Fix_charge_regulation::init() { // skip if already exists from previous init() if (!exclusion_group_bit) { - char **group_arg = new char *[4]; // create unique group name for atoms to be excluded - int len = strlen(id) + 30; - group_arg[0] = new char[len]; - sprintf(group_arg[0], "Fix_CR:exclusion_group:%s", id); - group_arg[1] = (char *) "subtract"; - group_arg[2] = (char *) "all"; - group_arg[3] = (char *) "all"; - group->assign(4, group_arg); - exclusion_group = group->find(group_arg[0]); + + auto group_id = std::string("FixChargeRegulation:CR_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 CR exclusion group ID"); + 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];; + char **arg = new char*[narg];; arg[0] = (char *) "exclude"; arg[1] = (char *) "group"; - arg[2] = group_arg[0]; + arg[2] = (char *) group_id.c_str(); arg[3] = (char *) "all"; - neighbor->modify_params(narg, arg); - delete[] group_arg[0]; - delete[] group_arg; - delete[] arg; + neighbor->modify_params(narg,arg); + delete [] arg; } // check that no deletable atoms are in atom->firstgroup @@ -226,7 +223,7 @@ void Fix_charge_regulation::init() { } } -void Fix_charge_regulation::pre_exchange() { +void FixChargeRegulation::pre_exchange() { if (next_reneighbor != update->ntimestep) return; xlo = domain->boxlo[0]; @@ -263,14 +260,22 @@ void Fix_charge_regulation::pre_exchange() { reaction_distance = 0; } // volume in units of (N_A * mol / liter) - volume_rx = (xhi - xlo) * (yhi - ylo) * (zhi - zlo) * pow(llength_unit_in_nm, 3) * 0.602214; - if (reaction_distance < small) { + 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 * PI * pow(reaction_distance, 3) / 3.0 * pow(llength_unit_in_nm, 3) * 0.602214; + 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); @@ -337,7 +342,7 @@ void Fix_charge_regulation::pre_exchange() { next_reneighbor = update->ntimestep + nevery; } -void Fix_charge_regulation::forward_acid() { +void FixChargeRegulation::forward_acid() { double energy_before = energy_stored; double factor; @@ -360,7 +365,7 @@ void Fix_charge_regulation::forward_acid() { pos[2] = atom->x[m1][2]; } npart_xrd2 = ncation; - if (reaction_distance >= small) { + if (reaction_distance >= SMALL) { pos_all[0] = pos[0]; pos_all[1] = pos[1]; pos_all[2] = pos[2]; @@ -368,8 +373,8 @@ void Fix_charge_regulation::forward_acid() { 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 * pow(10, -pKa) - * (1 + pow(10, pH - pI_plus)) / ((1 + nacid_charged) * (1 + npart_xrd2)); + factor = nacid_neutral * vlocal_xrd * c10pKa * c10pI_plus / + (c10pH * (1 + nacid_charged) * (1 + npart_xrd2)); double energy_after = energy_full(); @@ -395,7 +400,7 @@ void Fix_charge_regulation::forward_acid() { } } -void Fix_charge_regulation::backward_acid() { +void FixChargeRegulation::backward_acid() { double energy_before = energy_stored; double factor; @@ -418,7 +423,7 @@ void Fix_charge_regulation::backward_acid() { pos[1] = atom->x[m1][1]; pos[2] = atom->x[m1][2]; } - if (reaction_distance >= small) { + if (reaction_distance >= SMALL) { pos_all[0] = pos[0]; pos_all[1] = pos[1]; pos_all[2] = pos[2]; @@ -433,8 +438,8 @@ void Fix_charge_regulation::backward_acid() { mask_tmp = atom->mask[m2]; // remember group bits. atom->mask[m2] = exclusion_group_bit; } - factor = (1 + nacid_neutral) * vlocal_xrd * pow(10, -pKa) - * (1 + pow(10, pH - pI_plus)) / (nacid_charged * npart_xrd); + factor = (1 + nacid_neutral) * vlocal_xrd * c10pKa * c10pI_plus / + (c10pH * nacid_charged * npart_xrd); double energy_after = energy_full(); @@ -468,7 +473,7 @@ void Fix_charge_regulation::backward_acid() { } } -void Fix_charge_regulation::forward_base() { +void FixChargeRegulation::forward_base() { double energy_before = energy_stored; double factor; @@ -491,16 +496,15 @@ void Fix_charge_regulation::forward_base() { pos[2] = atom->x[m1][2]; } npart_xrd2 = nanion; - if (reaction_distance >= small) { + 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 * pow(10, -pKb) - * (1 + pow(10, pKs - pH - pI_minus)) / - ((1 + nbase_charged) * (1 + npart_xrd2)); + 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(); @@ -526,7 +530,7 @@ void Fix_charge_regulation::forward_base() { } } -void Fix_charge_regulation::backward_base() { +void FixChargeRegulation::backward_base() { double energy_before = energy_stored; double factor; @@ -549,7 +553,7 @@ void Fix_charge_regulation::backward_base() { pos[1] = atom->x[m1][1]; pos[2] = atom->x[m1][2]; } - if (reaction_distance >= small) { + if (reaction_distance >= SMALL) { pos_all[0] = pos[0]; pos_all[1] = pos[1]; pos_all[2] = pos[2]; @@ -563,8 +567,8 @@ void Fix_charge_regulation::backward_base() { mask_tmp = atom->mask[m2]; // remember group bits. atom->mask[m2] = exclusion_group_bit; } - factor = (1 + nbase_neutral) * vlocal_xrd * pow(10, -pKb) - * (1 + pow(10, pKs - pH - pI_minus)) / (nbase_charged * npart_xrd); + factor = (1 + nbase_neutral) * vlocal_xrd * c10pKb * c10pI_minus / + (c10pOH * nbase_charged * npart_xrd); double energy_after = energy_full(); @@ -598,20 +602,20 @@ void Fix_charge_regulation::backward_base() { } } -void Fix_charge_regulation::forward_ions() { +void FixChargeRegulation::forward_ions() { double energy_before = energy_stored; double factor; double *dummyp; int m1 = -1, m2 = -1; - factor = volume_rx * volume_rx * (pow(10, -pH) + pow(10, -pI_plus)) - * (pow(10, -pKs + pH) + pow(10, -pI_minus)) / + 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))) { + if (energy_after < MAXENERGYTEST && + random_equal->uniform() < factor * exp(beta * (energy_before - energy_after))) { energy_stored = energy_after; nsalt_successes += 1; ncation++; @@ -632,7 +636,7 @@ void Fix_charge_regulation::forward_ions() { } -void Fix_charge_regulation::backward_ions() { +void FixChargeRegulation::backward_ions() { double energy_before = energy_stored; double factor; @@ -659,8 +663,7 @@ void Fix_charge_regulation::backward_ions() { mask2_tmp = atom->mask[m2]; atom->mask[m2] = exclusion_group_bit; } - factor = (volume_rx * volume_rx * (pow(10, -pH) + pow(10, -pI_plus)) * - (pow(10, -pKs + pH) + pow(10, -pI_minus))) / (ncation * nanion); + factor = volume_rx * volume_rx * c10pI_plus * c10pI_minus / (ncation * nanion); double energy_after = energy_full(); if (energy_after < MAXENERGYTEST && @@ -717,7 +720,7 @@ void Fix_charge_regulation::backward_ions() { } } -void Fix_charge_regulation::forward_ions_multival() { +void FixChargeRegulation::forward_ions_multival() { double energy_before = energy_stored; double factor = 1; @@ -728,19 +731,19 @@ void Fix_charge_regulation::forward_ions_multival() { // insert one anion and (salt_charge_ratio) cations mm[0] = insert_particle(anion_type, salt_charge[1], 0, dummyp); - factor *= volume_rx * pow(10, -pI_minus) / (1 + nanion); + 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 * pow(10, -pI_plus) / (1 + ncation + i); + 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 * pow(10, -pI_plus) / (1 + ncation); + 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 * pow(10, -pI_minus) / (1 + nanion + i); + factor *= volume_rx * c10pI_minus / (1 + nanion + i); } } @@ -771,7 +774,7 @@ void Fix_charge_regulation::forward_ions_multival() { } } -void Fix_charge_regulation::backward_ions_multival() { +void FixChargeRegulation::backward_ions_multival() { double energy_before = energy_stored; double factor = 1; @@ -786,7 +789,7 @@ void Fix_charge_regulation::backward_ions_multival() { 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 * pow(10, -pI_minus) / (nanion); + factor *= volume_rx * c10pI_minus / (nanion); if (mm[0] >= 0) { qq[0] = atom->q[mm[0]]; atom->q[mm[0]] = 0; @@ -796,7 +799,7 @@ void Fix_charge_regulation::backward_ions_multival() { 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 * pow(10, -pI_plus) / (ncation - i); + 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; @@ -810,7 +813,7 @@ void Fix_charge_regulation::backward_ions_multival() { 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 * pow(10, -pI_plus) / (ncation); + factor *= volume_rx * c10pI_plus / (ncation); if (mm[0] >= 0) { qq[0] = atom->q[mm[0]]; atom->q[mm[0]] = 0; @@ -826,7 +829,7 @@ void Fix_charge_regulation::backward_ions_multival() { mask_tmp[i + 1] = atom->mask[mm[i + 1]]; atom->mask[mm[i + 1]] = exclusion_group_bit; } - factor *= volume_rx * pow(10, -pI_minus) / (nanion - i); + factor *= volume_rx * c10pI_minus / (nanion - i); } } @@ -840,7 +843,7 @@ void Fix_charge_regulation::backward_ions_multival() { 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). + // 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) { @@ -883,23 +886,42 @@ void Fix_charge_regulation::backward_ions_multival() { } } -int Fix_charge_regulation::insert_particle(int ptype, double charge, double rd, double *target) { +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) { + 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 { - double radius = reaction_distance * random_equal->uniform(); - double theta = random_equal->uniform() * PI; - double phi = random_equal->uniform() * 2 * PI; - coord[0] = target[0] + radius * sin(theta) * cos(phi); - coord[1] = target[1] + radius * sin(theta) * sin(phi); - coord[2] = target[2] + radius * cos(theta); + // 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); @@ -926,7 +948,7 @@ int Fix_charge_regulation::insert_particle(int ptype, double charge, double rd, return m; } -int Fix_charge_regulation::get_random_particle(int ptype, double charge, double rd, double *target) { +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) @@ -947,9 +969,9 @@ int Fix_charge_regulation::get_random_particle(int ptype, double charge, double count_global = 0; count_before = 0; - if (rd < small) { //reaction_distance < small: No geometry constraint on random particle choice + 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 && + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) { ptype_ID[count_local] = i; count_local++; @@ -966,7 +988,7 @@ int Fix_charge_regulation::get_random_particle(int ptype, double charge, double 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) { + fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) { ptype_ID[count_local] = i; count_local++; } @@ -990,7 +1012,7 @@ int Fix_charge_regulation::get_random_particle(int ptype, double charge, double return -1; } -double Fix_charge_regulation::energy_full() { +double FixChargeRegulation::energy_full() { int imolecule; if (triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); @@ -1050,12 +1072,12 @@ double Fix_charge_regulation::energy_full() { return total_energy; } -int Fix_charge_regulation::particle_number_xrd(int ptype, double charge, double rd, double *target) { +int FixChargeRegulation::particle_number_xrd(int ptype, double charge, double rd, double *target) { int count = 0; - if (rd < small) { + 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) + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) count++; } } else { @@ -1069,7 +1091,7 @@ int Fix_charge_regulation::particle_number_xrd(int ptype, double charge, double 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) { + fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) { count++; } } @@ -1079,11 +1101,11 @@ int Fix_charge_regulation::particle_number_xrd(int ptype, double charge, double return count_sum; } -int Fix_charge_regulation::particle_number(int ptype, double charge) { +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) + if (atom->type[i] == ptype && fabs(atom->q[i] - charge) < SMALL && atom->mask[i] != exclusion_group_bit) count = count + 1; } int count_sum = count; @@ -1091,7 +1113,7 @@ int Fix_charge_regulation::particle_number(int ptype, double charge) { return count_sum; } -double Fix_charge_regulation::compute_vector(int n) { +double FixChargeRegulation::compute_vector(int n) { double count_temp = 0; if (n == 0) { return nacid_attempts + nbase_attempts + nsalt_attempts; @@ -1113,7 +1135,7 @@ double Fix_charge_regulation::compute_vector(int n) { return 0.0; } -void Fix_charge_regulation::setThermoTemperaturePointer() { +void FixChargeRegulation::setThermoTemperaturePointer() { int ifix = -1; ifix = modify->find_fix(idftemp); if (ifix == -1) { @@ -1126,7 +1148,7 @@ void Fix_charge_regulation::setThermoTemperaturePointer() { } -void Fix_charge_regulation::assign_tags() { +void FixChargeRegulation::assign_tags() { // Assign tags to ions with zero tags if (atom->tag_enable) { tagint *tag = atom->tag; @@ -1167,14 +1189,14 @@ void Fix_charge_regulation::assign_tags() { parse input options ------------------------------------------------------------------------- */ -void Fix_charge_regulation::options(int narg, char **arg) { +void FixChargeRegulation::options(int narg, char **arg) { if (narg < 0) error->all(FLERR, "Illegal fix charge regulation command"); // defaults pH = 7.0; - pI_plus = 100; - pI_minus = 100; + pI_plus = 5; + pI_minus = 5; acid_type = -1; base_type = -1; pKa = 100; @@ -1182,12 +1204,12 @@ void Fix_charge_regulation::options(int narg, char **arg) { pKs = 14.0; nevery = 100; nmc = 100; - pmcmoves[0] = pmcmoves[1] = pmcmoves[2] = 0.33; - llength_unit_in_nm= 0.72; + 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 = 12345; + seed = 0; target_temperature_tcp = &reservoir_temperature; add_tags_flag = false; only_salt_flag = false; @@ -1297,9 +1319,9 @@ void Fix_charge_regulation::options(int narg, char **arg) { if (iarg + 4 > narg) error->all(FLERR, "Illegal fix charge regulation command"); salt_charge[0] = utils::numeric(FLERR, arg[iarg + 2], false, lmp); salt_charge[1] = utils::numeric(FLERR, arg[iarg + 3], false, lmp); - if (fabs(salt_charge[0] - utils::inumeric(FLERR, arg[iarg + 2], false, lmp)) > small) + if (fabs(salt_charge[0] - utils::inumeric(FLERR, arg[iarg + 2], false, lmp)) > SMALL) error->all(FLERR, "Illegal fix charge regulation command, cation charge must be an integer"); - if (fabs(salt_charge[1] - utils::inumeric(FLERR, arg[iarg + 3], false, lmp)) > small) + if (fabs(salt_charge[1] - utils::inumeric(FLERR, arg[iarg + 3], false, lmp)) > SMALL) error->all(FLERR, "Illegal fix charge regulation command, anion charge must be an integer"); iarg += 4; } else if (strcmp(arg[iarg + 1], "no") == 0) { @@ -1329,7 +1351,7 @@ void Fix_charge_regulation::options(int narg, char **arg) { memory usage of local atom-based arrays ------------------------------------------------------------------------- */ -double Fix_charge_regulation::memory_usage() { +double FixChargeRegulation::memory_usage() { double bytes = cr_nmax * sizeof(int); return bytes; } diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/USER-MISC/fix_charge_regulation.h index d698bd6bb7..3afaffddb7 100644 --- a/src/USER-MISC/fix_charge_regulation.h +++ b/src/USER-MISC/fix_charge_regulation.h @@ -17,21 +17,21 @@ #ifdef FIX_CLASS -FixStyle(charge_regulation,Fix_charge_regulation) +FixStyle(charge/regulation,FixChargeRegulation) #else -#ifndef LMP_FIX_charge_regulation_H -#define LMP_FIX_charge_regulation_H +#ifndef LMP_FIX_CHARGE_REGULATION_H +#define LMP_FIX_CHARGE_REGULATION_H #include "fix.h" namespace LAMMPS_NS { - class Fix_charge_regulation : public Fix { + class FixChargeRegulation : public Fix { public: - Fix_charge_regulation(class LAMMPS *, int, char **); - ~Fix_charge_regulation(); + FixChargeRegulation(class LAMMPS *, int, char **); + ~FixChargeRegulation(); int setmask(); void init(); void pre_exchange(); @@ -59,7 +59,8 @@ namespace LAMMPS_NS { 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 + 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 @@ -78,7 +79,7 @@ namespace LAMMPS_NS { 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 ration when using multivalent ion exchange + 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 From faa2407aa46805bea4caf9e90c768b5bd187a8ed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 07:04:19 -0500 Subject: [PATCH 08/22] plug memory leak --- src/USER-MISC/fix_charge_regulation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp index c43a509f61..0a9619096e 100644 --- a/src/USER-MISC/fix_charge_regulation.cpp +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -129,6 +129,7 @@ FixChargeRegulation::~FixChargeRegulation() { delete random_equal; delete random_unequal; + delete idftemp; if (group) { int igroupall = group->find("all"); From 8ee693204a7b7f3fb5071770dae1713b34dd8270 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 07:05:07 -0500 Subject: [PATCH 09/22] use nullptr instead of NULL to initialize pointers --- src/USER-MISC/fix_charge_regulation.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp index 0a9619096e..7608849190 100644 --- a/src/USER-MISC/fix_charge_regulation.cpp +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -61,10 +61,10 @@ using namespace MathSpecial; FixChargeRegulation::FixChargeRegulation(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), - ngroups(0), groupstrings(NULL), - random_equal(NULL), random_unequal(NULL), - idftemp(NULL), ptype_ID(NULL) - { + ngroups(0), groupstrings(nullptr), ptype_ID(nullptr), + random_equal(nullptr), random_unequal(nullptr), + idftemp(nullptr) +{ // Region restrictions not yet implemented .. @@ -1221,7 +1221,7 @@ void FixChargeRegulation::options(int narg, char **arg) { exclusion_group_bit = 0; ngroups = 0; int ngroupsmax = 0; - groupstrings = NULL; + groupstrings = nullptr; int iarg = 0; while (iarg < narg) { From 9671ba79003171d7d50e8bc3c385c99d78d05774 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 07:05:28 -0500 Subject: [PATCH 10/22] silence compiler warnings --- src/USER-MISC/fix_charge_regulation.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp index 7608849190..8a6530ef2b 100644 --- a/src/USER-MISC/fix_charge_regulation.cpp +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -347,7 +347,7 @@ void FixChargeRegulation::forward_acid() { double energy_before = energy_stored; double factor; - double *dummyp; + double *dummyp = nullptr; double pos[3]; pos[0] = 0; pos[1] = 0; @@ -406,13 +406,13 @@ void FixChargeRegulation::backward_acid() { double energy_before = energy_stored; double factor; int mask_tmp; - double *dummyp; + 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, m1_all = -1, m2 = -1, m2_all = -1; + 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"); @@ -478,13 +478,13 @@ void FixChargeRegulation::forward_base() { double energy_before = energy_stored; double factor; - double *dummyp; + 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, m1_all = -1, m2 = -1, m2_all = -1; + 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"); @@ -535,14 +535,14 @@ void FixChargeRegulation::backward_base() { double energy_before = energy_stored; double factor; - double *dummyp; + 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, m1_all = -1, m2 = -1, m2_all = -1; + 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"); @@ -607,7 +607,7 @@ void FixChargeRegulation::forward_ions() { double energy_before = energy_stored; double factor; - double *dummyp; + double *dummyp = nullptr; int m1 = -1, m2 = -1; factor = volume_rx * volume_rx * c10pI_plus * c10pI_minus / ((1 + ncation) * (1 + nanion)); @@ -642,7 +642,7 @@ void FixChargeRegulation::backward_ions() { double energy_before = energy_stored; double factor; int mask1_tmp, mask2_tmp; - double *dummyp; // dummy pointer + double *dummyp = nullptr; int m1 = -1, m2 = -1; m1 = get_random_particle(cation_type, +1, 0, dummyp); @@ -1014,7 +1014,6 @@ int FixChargeRegulation::get_random_particle(int ptype, double charge, double rd } double FixChargeRegulation::energy_full() { - int imolecule; if (triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); comm->exchange(); @@ -1030,7 +1029,6 @@ double FixChargeRegulation::energy_full() { int overlaptest = 0; double delx, dely, delz, rsq; double **x = atom->x; - tagint *molecule = atom->molecule; int nall = atom->nlocal + atom->nghost; for (int i = 0; i < atom->nlocal; i++) { for (int j = i + 1; j < nall; j++) { @@ -1115,7 +1113,6 @@ int FixChargeRegulation::particle_number(int ptype, double charge) { } double FixChargeRegulation::compute_vector(int n) { - double count_temp = 0; if (n == 0) { return nacid_attempts + nbase_attempts + nsalt_attempts; } else if (n == 1) { From 676191f3303751c39ce4a36bcb964f7d079d527d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 07:28:15 -0500 Subject: [PATCH 11/22] various cosmetic changes - print warnings only on MPI rank 0 - use the fix name charge/regulation consistently - use domain->prd_half for half box length instead of computing it - use utils::inumeric() to guarantee integer charge input - LAMMPS coding style adjustments --- src/USER-MISC/fix_charge_regulation.cpp | 194 ++++++++++++++---------- 1 file changed, 114 insertions(+), 80 deletions(-) diff --git a/src/USER-MISC/fix_charge_regulation.cpp b/src/USER-MISC/fix_charge_regulation.cpp index 8a6530ef2b..5479082158 100644 --- a/src/USER-MISC/fix_charge_regulation.cpp +++ b/src/USER-MISC/fix_charge_regulation.cpp @@ -85,25 +85,27 @@ FixChargeRegulation::FixChargeRegulation(LAMMPS *lmp, int narg, char **arg) : // set defaults and read optional arguments options(narg - 5, &arg[5]); - if (nevery <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (nmc < 0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (llength_unit_in_nm < 0.0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (*target_temperature_tcp < 0.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 (cation_type <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (anion_type <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (reaction_distance < 0.0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (salt_charge[0] <= 0) error->all(FLERR, "Illegal fix charge/regulation command"); - if (salt_charge[1] >= 0) error->all(FLERR, "Illegal fix charge/regulation command"); - 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 ((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"); @@ -159,11 +161,12 @@ void FixChargeRegulation::init() { 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"); + 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"); + error->all(FLERR, "Cannot use fix charge/regulation in a 2d simulation"); // create a new group for interaction exclusions // used for attempted atom deletions @@ -173,11 +176,12 @@ void FixChargeRegulation::init() { // create unique group name for atoms to be excluded - auto group_id = std::string("FixChargeRegulation:CR_exclusion_group:") + id; + 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"); + error->all(FLERR,"Could not find fix charge/regulation exclusion " + "group ID"); exclusion_group_bit = group->bitmask[exclusion_group]; // neighbor list exclusion setup @@ -208,7 +212,8 @@ void FixChargeRegulation::init() { MPI_Allreduce(&flag, &flagall, 1, MPI_INT, MPI_SUM, world); if (flagall) - error->all(FLERR, "Cannot do Fix charge regulation on atoms in atom_modify first group"); + error->all(FLERR, "Cannot use fix charge/regulation on atoms " + "in atom_modify first group"); } // construct group bitmask for all new atoms @@ -219,7 +224,7 @@ void FixChargeRegulation::init() { for (int igroup = 0; igroup < ngroups; igroup++) { int jgroup = group->find(groupstrings[igroup]); if (jgroup == -1) - error->all(FLERR, "Could not find specified fix charge regulation group ID"); + error->all(FLERR, "Could not find fix charge/regulation group ID"); groupbitall |= group->bitmask[jgroup]; } } @@ -250,22 +255,26 @@ void FixChargeRegulation::pre_exchange() { if (triclinic) domain->lamda2x(atom->nlocal + atom->nghost); energy_stored = energy_full(); - if (energy_stored > MAXENERGYTEST) - error->warning(FLERR, "Energy of old configuration in fix charge_regulation is > MAXENERGYTEST."); + if ((energy_stored > MAXENERGYTEST) && (comm->me == 0)) + error->warning(FLERR, "Energy of old configuration in fix " + "charge/regulation is > MAXENERGYTEST."); - if ((reaction_distance > fabs(domain->boxhi[0] - domain->boxlo[0]) / 2) || - (reaction_distance > fabs(domain->boxhi[1] - domain->boxlo[1]) / 2) || - (reaction_distance > fabs(domain->boxhi[2] - domain->boxlo[2]) / 2)) { - error->warning(FLERR, - "reaction distance (rxd) is larger than half the box dimension, resetting default: xrd = 0."); + 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; + 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; + 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); @@ -356,7 +365,7 @@ void FixChargeRegulation::forward_acid() { 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 (npart_xrd != nacid_neutral) error->all(FLERR, "fix charge/regulation acid count inconsistent"); if (nacid_neutral > 0) { if (m1 >= 0) { @@ -415,7 +424,8 @@ void FixChargeRegulation::backward_acid() { 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 (npart_xrd != nacid_charged) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); if (nacid_charged > 0) { if (m1 >= 0) { @@ -487,7 +497,8 @@ void FixChargeRegulation::forward_base() { 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 (npart_xrd != nbase_neutral) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); if (nbase_neutral > 0) { if (m1 >= 0) { @@ -545,7 +556,8 @@ void FixChargeRegulation::backward_base() { 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 (npart_xrd != nbase_charged) + error->all(FLERR, "fix charge/regulation acid count inconsistent"); if (nbase_charged > 0) { if (m1 >= 0) { @@ -646,10 +658,12 @@ void FixChargeRegulation::backward_ions() { 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 (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 (npart_xrd != nanion) + error->all(FLERR, "fix charge/regulation salt count inconsistent"); if (nanion > 0) { // attempt deletion @@ -789,7 +803,8 @@ void FixChargeRegulation::backward_ions_multival() { 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"); + 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]]; @@ -799,7 +814,8 @@ void FixChargeRegulation::backward_ions_multival() { } 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"); + 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]]; @@ -813,7 +829,8 @@ void FixChargeRegulation::backward_ions_multival() { 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"); + 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]]; @@ -823,7 +840,8 @@ void FixChargeRegulation::backward_ions_multival() { } 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 (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; @@ -1138,7 +1156,7 @@ void FixChargeRegulation::setThermoTemperaturePointer() { 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 charge/regulation regulation could not find a temperature fix id provided by tempfixid\n"); } Fix *temperature_fix = modify->fix[ifix]; int dim; @@ -1188,7 +1206,7 @@ void FixChargeRegulation::assign_tags() { ------------------------------------------------------------------------- */ void FixChargeRegulation::options(int narg, char **arg) { - if (narg < 0) error->all(FLERR, "Illegal fix charge regulation command"); + if (narg < 0) error->all(FLERR, "Illegal fix charge/regulation command"); // defaults @@ -1224,48 +1242,59 @@ void FixChargeRegulation::options(int narg, char **arg) { while (iarg < narg) { if (strcmp(arg[iarg], "lunit_nm") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Illegal fix charge regulation command"); + 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"); + 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"); + 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"); + 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"); + 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"); + 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"); + 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"); + 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"); + 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"); + 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"); + if (iarg + 2 > narg) + error->all(FLERR, "Illegal fix charge/regulation command"); int n = strlen(arg[iarg + 1]) + 1; delete[] idftemp; idftemp = new char[n]; @@ -1273,75 +1302,81 @@ void FixChargeRegulation::options(int narg, char **arg) { setThermoTemperaturePointer(); iarg += 2; } else if (strcmp(arg[iarg], "rxd") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Illegal fix charge regulation command"); + 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 > fabs(domain->boxhi[0] - domain->boxlo[0]) / 2) || - (reaction_distance > fabs(domain->boxhi[1] - domain->boxlo[1]) / 2) || - (reaction_distance > fabs(domain->boxhi[2] - domain->boxlo[2]) / 2)) { - error->warning(FLERR, - "reaction distance (rxd) is larger than half the box dimension, resetting default: xrd = 0."); + 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"); + 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"); + 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"); + 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"); + 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 (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"); } + } 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 (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::numeric(FLERR, arg[iarg + 2], false, lmp); - salt_charge[1] = utils::numeric(FLERR, arg[iarg + 3], false, lmp); - if (fabs(salt_charge[0] - utils::inumeric(FLERR, arg[iarg + 2], false, lmp)) > SMALL) - error->all(FLERR, "Illegal fix charge regulation command, cation charge must be an integer"); - if (fabs(salt_charge[1] - utils::inumeric(FLERR, arg[iarg + 3], false, lmp)) > SMALL) - error->all(FLERR, "Illegal fix charge regulation command, anion charge must be an integer"); + 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 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 (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"); + memory->srealloc(groupstrings, + ngroupsmax * sizeof(char *), + "fix_charge_regulation:groupstrings"); } int n = strlen(arg[iarg + 1]) + 1; groupstrings[ngroups] = new char[n]; strcpy(groupstrings[ngroups], arg[iarg + 1]); ngroups++; iarg += 2; - } else { error->all(FLERR, "Illegal fix charge regulation command"); } + } else error->all(FLERR, "Illegal fix charge/regulation command"); } } @@ -1350,6 +1385,5 @@ void FixChargeRegulation::options(int narg, char **arg) { ------------------------------------------------------------------------- */ double FixChargeRegulation::memory_usage() { - double bytes = cr_nmax * sizeof(int); - return bytes; + return (double)cr_nmax * sizeof(int); } From 6c2abf4739a2ba78dc35d122d0697b826405ab9b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 07:53:19 -0500 Subject: [PATCH 12/22] update fix charge/regulation input example to follow LAMMPS conventions closer --- examples/USER/misc/charge_regulation/README | 38 +++- .../{data_acid.chreg => data.chreg-acid} | 0 ...{data_polymer.chreg => data.chreg-polymer} | 0 .../{in_acid.chreg => in.chreg-acid} | 41 ++--- .../misc/charge_regulation/in.chreg-polymer | 33 ++++ .../misc/charge_regulation/in_polymer.chreg | 37 ---- .../misc/charge_regulation/log_acid.lammps | 163 ------------------ 7 files changed, 84 insertions(+), 228 deletions(-) rename examples/USER/misc/charge_regulation/{data_acid.chreg => data.chreg-acid} (100%) rename examples/USER/misc/charge_regulation/{data_polymer.chreg => data.chreg-polymer} (100%) rename examples/USER/misc/charge_regulation/{in_acid.chreg => in.chreg-acid} (52%) create mode 100644 examples/USER/misc/charge_regulation/in.chreg-polymer delete mode 100644 examples/USER/misc/charge_regulation/in_polymer.chreg delete mode 100644 examples/USER/misc/charge_regulation/log_acid.lammps diff --git a/examples/USER/misc/charge_regulation/README b/examples/USER/misc/charge_regulation/README index 5666d6d025..c704b67dea 100644 --- a/examples/USER/misc/charge_regulation/README +++ b/examples/USER/misc/charge_regulation/README @@ -1,8 +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. +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_acid.chreg` 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 `log_acid.lammps`. +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_polymer.chreg` sets up a weak polyelectrolyte 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 `log_polymer.lammps`. +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_acid.chreg b/examples/USER/misc/charge_regulation/data.chreg-acid similarity index 100% rename from examples/USER/misc/charge_regulation/data_acid.chreg rename to examples/USER/misc/charge_regulation/data.chreg-acid diff --git a/examples/USER/misc/charge_regulation/data_polymer.chreg b/examples/USER/misc/charge_regulation/data.chreg-polymer similarity index 100% rename from examples/USER/misc/charge_regulation/data_polymer.chreg rename to examples/USER/misc/charge_regulation/data.chreg-polymer diff --git a/examples/USER/misc/charge_regulation/in_acid.chreg b/examples/USER/misc/charge_regulation/in.chreg-acid similarity index 52% rename from examples/USER/misc/charge_regulation/in_acid.chreg rename to examples/USER/misc/charge_regulation/in.chreg-acid index 73a40f7389..68ef5e1b7c 100644 --- a/examples/USER/misc/charge_regulation/in_acid.chreg +++ b/examples/USER/misc/charge_regulation/in.chreg-acid @@ -1,12 +1,9 @@ # Charge regulation lammps for simple weak electrolyte -units lj -atom_style charge -dimension 3 -boundary p p p -processors * * * -neighbor 3.0 bin -read_data data_acid.chreg +units lj +atom_style charge +neighbor 3.0 bin +read_data data.chreg-acid variable cut_long equal 12.5 variable nevery equal 100 @@ -16,26 +13,24 @@ 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 +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 ${cut_lj} # charges -kspace_style ewald 1.0e-3 -dielectric 1.0 -pair_modify shift yes +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 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 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] -log log_acid.lammps -timestep 0.005 -run 20000 +timestep 0.005 +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/in_polymer.chreg b/examples/USER/misc/charge_regulation/in_polymer.chreg deleted file mode 100644 index e35ba28661..0000000000 --- a/examples/USER/misc/charge_regulation/in_polymer.chreg +++ /dev/null @@ -1,37 +0,0 @@ -# Charge regulation lammps for a polymer chain -units lj -atom_style full -dimension 3 -boundary p p p -processors * * * -neighbor 3.0 bin -read_data data_polymer.chreg - -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] -log log_polymer.lammps - -timestep 0.005 -run 20000 diff --git a/examples/USER/misc/charge_regulation/log_acid.lammps b/examples/USER/misc/charge_regulation/log_acid.lammps deleted file mode 100644 index cbc3661eb1..0000000000 --- a/examples/USER/misc/charge_regulation/log_acid.lammps +++ /dev/null @@ -1,163 +0,0 @@ -LAMMPS (24 Dec 2020) -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.001 seconds -Ewald initialization ... - using 12-bit tables for long-range coulomb (../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 Fix_CR: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 = 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 -Setting up Verlet run ... - Unit style : lj - Current step : 0 - Time step : 0.005 -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.054228269 1 0 0 1 99 0 0 109 10 - 100 -0.058672881 0.99159291 100 71 16 84 0 0 92 8 - 200 -0.05399313 0.92006523 200 154 26 74 0 0 85 11 - 300 -0.047035343 0.92728143 300 240 22 78 0 0 85 7 - 400 -0.049597809 1.0617937 400 319 16 84 0 0 92 8 - 500 -0.052409835 1.0006148 500 404 12 88 0 0 97 9 - 600 -0.056012172 0.98059344 600 481 15 85 0 0 92 7 - 700 -0.053639989 0.99572709 700 561 16 84 0 0 94 10 - 800 -0.060026132 0.95764632 800 639 22 78 0 0 84 6 - 900 -0.050785422 0.98399084 900 719 28 72 0 0 82 10 - 1000 -0.062294743 0.97200068 1000 797 26 74 0 0 82 8 - 1100 -0.051269402 1.0064376 1100 877 25 75 0 0 84 9 - 1200 -0.077744839 1.0159098 1200 955 23 77 0 0 88 11 - 1300 -0.084889696 1.1230485 1300 1037 20 80 0 0 90 10 - 1400 -0.059361445 0.96735845 1400 1120 18 82 0 0 93 11 - 1500 -0.052926174 0.95579188 1500 1199 24 76 0 0 86 10 - 1600 -0.052376649 0.99376378 1600 1284 22 78 0 0 89 11 - 1700 -0.052480188 0.96085964 1700 1361 27 73 0 0 84 11 - 1800 -0.065884306 0.96747971 1800 1441 21 79 0 0 84 5 - 1900 -0.054315859 0.95873145 1900 1521 23 77 0 0 84 7 - 2000 -0.037161802 0.93562039 2000 1604 27 73 0 0 79 6 - 2100 -0.034977265 0.97177103 2100 1684 26 74 0 0 85 11 - 2200 -0.047434868 0.97897613 2200 1762 17 83 0 0 93 10 - 2300 -0.047392634 0.96570672 2300 1837 18 82 0 0 92 10 - 2400 -0.044879306 0.98620033 2400 1910 19 81 0 0 89 8 - 2500 -0.069690496 1.0690505 2500 1988 16 84 0 0 91 7 - 2600 -0.081588407 0.97711054 2600 2067 17 83 0 0 92 9 - 2700 -0.06341681 1.0386711 2700 2146 20 80 0 0 85 5 - 2800 -0.045290012 1.0402055 2800 2230 18 82 0 0 91 9 - 2900 -0.046875012 1.0609775 2900 2317 24 76 0 0 86 10 - 3000 -0.031258722 0.93861202 3000 2400 24 76 0 0 85 9 - 3100 -0.04673342 0.90800583 3100 2485 25 75 0 0 90 15 - 3200 -0.054354227 0.94493881 3200 2567 16 84 0 0 94 10 - 3300 -0.053647746 0.92321446 3300 2641 17 83 0 0 94 11 - 3400 -0.031751732 0.93735127 3400 2725 22 78 0 0 92 14 - 3500 -0.053806113 0.98798136 3500 2795 28 72 0 0 84 12 - 3600 -0.040751349 0.84291639 3600 2873 28 72 0 0 84 12 - 3700 -0.051747138 1.072448 3700 2951 24 76 0 0 92 16 - 3800 -0.043420594 1.0076309 3800 3030 26 74 0 0 79 5 - 3900 -0.050845848 1.0250023 3900 3103 29 71 0 0 76 5 - 4000 -0.039837847 1.064111 4000 3182 29 71 0 0 83 12 - 4100 -0.045638995 1.1249685 4100 3262 28 72 0 0 81 9 - 4200 -0.047956491 0.92255907 4200 3348 26 74 0 0 87 13 - 4300 -0.054052822 1.006239 4300 3423 19 81 0 0 90 9 - 4400 -0.053148034 1.0028887 4400 3506 24 76 0 0 83 7 - 4500 -0.062132076 1.0317847 4500 3587 23 77 0 0 82 5 - 4600 -0.04616043 0.99066453 4600 3673 28 72 0 0 82 10 - 4700 -0.066990889 1.0242064 4700 3755 18 82 0 0 90 8 - 4800 -0.0564736 0.91765628 4800 3832 22 78 0 0 91 13 - 4900 -0.052301294 0.95348659 4900 3912 28 72 0 0 81 9 - 5000 -0.062630677 1.0336579 5000 3989 18 82 0 0 92 10 - 5100 -0.053645908 1.0314613 5100 4062 20 80 0 0 85 5 - 5200 -0.062189568 1.0504732 5200 4133 23 77 0 0 84 7 - 5300 -0.049092746 1.0310832 5300 4217 24 76 0 0 82 6 - 5400 -0.051859257 0.99600428 5400 4299 27 73 0 0 80 7 - 5500 -0.065540815 0.98012128 5500 4381 19 81 0 0 92 11 - 5600 -0.071018582 0.9252814 5600 4455 23 77 0 0 84 7 - 5700 -0.066954185 1.0325214 5700 4535 26 74 0 0 82 8 - 5800 -0.064847249 1.0313536 5800 4617 21 79 0 0 90 11 - 5900 -0.063173056 0.95455853 5900 4703 18 82 0 0 92 10 - 6000 -0.064807837 0.97182222 6000 4790 21 79 0 0 91 12 - 6100 -0.07067683 0.91775921 6100 4875 16 84 0 0 94 10 - 6200 -0.071400842 1.0162225 6200 4952 17 83 0 0 87 4 - 6300 -0.078479449 1.0106706 6300 5033 21 79 0 0 84 5 - 6400 -0.083167651 1.0246584 6400 5111 18 82 0 0 90 8 - 6500 -0.092611537 1.0766467 6500 5195 20 80 0 0 88 8 - 6600 -0.096710071 1.0246648 6600 5274 15 85 0 0 91 6 - 6700 -0.073399857 0.94939392 6700 5351 17 83 0 0 92 9 - 6800 -0.062479375 0.9393967 6800 5434 18 82 0 0 93 11 - 6900 -0.065391043 0.93475954 6900 5514 22 78 0 0 89 11 - 7000 -0.045655499 0.98688239 7000 5601 21 79 0 0 90 11 - 7100 -0.061186309 1.0309063 7100 5684 22 78 0 0 87 9 - 7200 -0.074737514 1.0516593 7200 5769 25 75 0 0 80 5 - 7300 -0.075228979 1.0167704 7300 5847 21 79 0 0 86 7 - 7400 -0.06660147 1.0947107 7400 5930 25 75 0 0 87 12 - 7500 -0.071915247 1.10542 7500 6009 24 76 0 0 84 8 - 7600 -0.029974303 0.99202697 7600 6095 28 72 0 0 80 8 - 7700 -0.029024004 1.0390995 7700 6182 28 72 0 0 83 11 - 7800 -0.056250746 0.96393961 7800 6260 18 82 0 0 91 9 - 7900 -0.072178944 0.9833919 7900 6339 21 79 0 0 86 7 - 8000 -0.070377248 1.021342 8000 6419 23 77 0 0 88 11 - 8100 -0.07753283 0.96194312 8100 6493 26 74 0 0 86 12 - 8200 -0.075617309 0.9715344 8200 6576 25 75 0 0 89 14 - 8300 -0.077480013 0.99106705 8300 6662 20 80 0 0 91 11 - 8400 -0.079901928 0.89855112 8400 6744 23 77 0 0 91 14 - 8500 -0.069192745 1.0606791 8500 6822 19 81 0 0 91 10 - 8600 -0.058657202 1.1270217 8600 6898 15 85 0 0 95 10 - 8700 -0.044985397 1.0367419 8700 6979 27 73 0 0 84 11 - 8800 -0.064266376 0.91557003 8800 7060 21 79 0 0 89 10 - 8900 -0.068680533 0.95963643 8900 7133 19 81 0 0 88 7 - 9000 -0.051736144 1.0398547 9000 7213 13 87 0 0 94 7 - 9100 -0.058381436 0.98047663 9100 7290 17 83 0 0 89 6 - 9200 -0.05531014 0.92541631 9200 7368 22 78 0 0 85 7 - 9300 -0.04386907 0.9339658 9300 7454 22 78 0 0 89 11 - 9400 -0.052293168 0.94314034 9400 7539 22 78 0 0 86 8 - 9500 -0.050362046 1.0489028 9500 7617 18 82 0 0 90 8 - 9600 -0.054272227 1.0879161 9600 7697 11 89 0 0 96 7 - 9700 -0.042514179 1.0051505 9700 7771 22 78 0 0 84 6 - 9800 -0.045365018 0.95363669 9800 7850 25 75 0 0 77 2 - 9900 -0.064287274 0.91994667 9900 7928 27 73 0 0 81 8 - 10000 -0.05689162 0.99963208 10000 8011 22 78 0 0 84 6 -Loop time of 19.4452 on 1 procs for 10000 steps with 190 atoms - -Performance: 222162.510 tau/day, 514.265 timesteps/s -99.9% 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.68864 | 0.68864 | 0.68864 | 0.0 | 3.54 -Kspace | 6.7893 | 6.7893 | 6.7893 | 0.0 | 34.92 -Neigh | 0.060782 | 0.060782 | 0.060782 | 0.0 | 0.31 -Comm | 0.047035 | 0.047035 | 0.047035 | 0.0 | 0.24 -Output | 0.0027227 | 0.0027227 | 0.0027227 | 0.0 | 0.01 -Modify | 11.838 | 11.838 | 11.838 | 0.0 | 60.88 -Other | | 0.01878 | | | 0.10 - -Nlocal: 190.000 ave 190 max 190 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 592.000 ave 592 max 592 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 2194.00 ave 2194 max 2194 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 2194 -Ave neighs/atom = 11.547368 -Neighbor list builds = 10287 -Dangerous builds = 0 -Total wall time: 0:00:19 \ No newline at end of file From 7f8e8c635c10f0c99343c0f31565b91ac2de951b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 08:00:59 -0500 Subject: [PATCH 13/22] create new reference log files --- .../log.10Feb21.chreg-acid.g++.1 | 125 ++++++++++++ .../log.10Feb21.chreg-acid.g++.4 | 125 ++++++++++++ .../log.10Feb21.chreg-polymer.g++.1 | 131 +++++++++++++ .../log.10Feb21.chreg-polymer.g++.4 | 131 +++++++++++++ .../misc/charge_regulation/log_polymer.lammps | 181 ------------------ 5 files changed, 512 insertions(+), 181 deletions(-) create mode 100644 examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.1 create mode 100644 examples/USER/misc/charge_regulation/log.10Feb21.chreg-acid.g++.4 create mode 100644 examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.1 create mode 100644 examples/USER/misc/charge_regulation/log.10Feb21.chreg-polymer.g++.4 delete mode 100644 examples/USER/misc/charge_regulation/log_polymer.lammps 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_polymer.lammps b/examples/USER/misc/charge_regulation/log_polymer.lammps deleted file mode 100644 index 87cab63a6c..0000000000 --- a/examples/USER/misc/charge_regulation/log_polymer.lammps +++ /dev/null @@ -1,181 +0,0 @@ -LAMMPS (24 Dec 2020) -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.000 seconds - read_data CPU = 0.004 seconds -PPPM initialization ... - using 12-bit tables for long-range coulomb (../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 KISS FFT - 3d grid and FFT values/proc = 2197 512 -0 atoms in group Fix_CR:exclusion_group:chareg1 -0 atoms in group Fix_CR:exclusion_group:chareg2 -0 atoms in group Fix_CR:exclusion_group:chareg3 -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 = 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 -Setting up Verlet run ... - Unit style : lj - Current step : 0 - Time step : 0.005 -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.49903297 1 0 80 80 0 0 0 - 100 0.63380666 0.87307225 8 72 77 6 1 0 - 200 0.5865464 1.0048645 16 64 81 16 0 1 - 300 0.55802913 1.0499142 19 61 91 29 0 1 - 400 0.44734087 1.0838048 24 56 98 41 0 1 - 500 0.47010775 1.005226 23 57 106 48 0 1 - 600 0.3452105 0.97814306 28 52 109 56 0 1 - 700 0.29208955 0.99766419 32 48 115 67 0 0 - 800 0.27821915 1.0091641 31 49 128 80 1 0 - 900 0.28943788 0.93619239 26 54 145 91 0 0 - 1000 0.22963142 1.0162138 27 53 150 97 0 0 - 1100 0.24238916 0.99146577 31 49 149 100 0 0 - 1200 0.17029095 1.0406453 38 42 144 102 0 0 - 1300 0.15830969 0.94661447 34 46 155 109 0 0 - 1400 0.16698712 1.0116563 35 45 159 114 0 0 - 1500 0.15432936 0.95600941 36 44 162 118 0 0 - 1600 0.16973501 0.98326602 31 49 171 122 0 0 - 1700 0.19725116 0.9915273 33 47 175 128 0 0 - 1800 0.15278999 1.0304873 29 51 193 142 0 0 - 1900 0.17418479 0.99490216 30 50 194 144 0 0 - 2000 0.14238391 0.9638301 32 48 189 141 0 0 - 2100 0.13054378 0.97164976 32 48 192 144 0 0 - 2200 0.092083069 1.0112059 40 40 191 151 0 0 - 2300 0.085175091 1.0070667 39 41 200 159 0 0 - 2400 0.083367076 0.9934796 35 45 208 163 0 0 - 2500 0.11494744 0.97650855 31 49 220 172 1 0 - 2600 0.10796032 0.97047046 34 46 221 175 0 0 - 2700 0.11080141 0.93570013 36 44 223 179 0 0 - 2800 0.096699277 0.97702627 35 45 223 178 0 0 - 2900 0.079403783 1.0870961 32 48 229 181 0 0 - 3000 0.08288836 1.0642515 35 45 231 186 0 0 - 3100 0.094000833 1.0241111 38 42 229 187 0 0 - 3200 0.10011052 1.043594 34 46 235 189 0 0 - 3300 0.096782103 0.99549134 34 46 234 188 0 0 - 3400 0.057703946 1.00292 34 46 236 190 0 0 - 3500 0.074345642 0.95064523 36 44 234 190 0 0 - 3600 0.085872341 0.9759514 35 45 238 192 0 1 - 3700 0.086427565 0.99843063 35 45 240 194 0 1 - 3800 0.076091357 0.98516844 32 48 252 203 0 1 - 3900 0.047187813 1.0063336 37 43 247 204 0 0 - 4000 0.068269223 1.0390369 35 45 248 203 0 0 - 4100 0.074209582 0.99912762 36 44 249 205 0 0 - 4200 0.087016078 1.050265 36 44 246 202 0 0 - 4300 0.081325479 1.0417103 35 45 245 200 0 0 - 4400 0.047345973 0.96517298 39 41 243 202 0 0 - 4500 0.041856955 0.94569673 38 42 245 203 0 0 - 4600 0.049588267 0.99046371 42 38 249 211 0 0 - 4700 0.043079897 1.0098538 43 37 245 208 0 0 - 4800 0.049122913 1.0229995 41 39 247 208 0 0 - 4900 0.059151797 1.0236679 36 44 249 205 0 0 - 5000 0.053806841 1.0308397 42 38 243 205 0 0 - 5100 0.053623833 1.0638841 39 41 246 205 0 0 - 5200 0.086215806 1.0027613 37 43 243 200 0 0 - 5300 0.031422797 1.0338154 38 42 245 203 0 0 - 5400 0.051341116 0.92205149 34 46 246 200 0 0 - 5500 0.039292708 0.97530704 32 48 251 203 0 0 - 5600 0.035215415 1.023123 33 47 246 199 0 0 - 5700 0.054553598 0.95833063 30 50 253 203 0 0 - 5800 0.035699456 1.0721613 37 43 248 205 0 0 - 5900 0.062426908 1.0612245 38 42 252 210 0 0 - 6000 0.056362902 1.0002968 36 44 248 204 0 0 - 6100 0.061550208 0.97270904 38 42 245 203 0 0 - 6200 0.051825485 0.98187623 36 44 253 209 0 0 - 6300 0.052137885 0.98906723 36 44 253 210 1 0 - 6400 0.068218075 1.0511584 36 44 256 212 0 0 - 6500 0.080167413 0.97270144 36 44 252 208 0 0 - 6600 0.052169204 1.0160108 41 39 249 210 0 0 - 6700 0.057313326 0.98033894 38 42 251 209 0 0 - 6800 0.073008094 0.96239565 35 45 256 211 0 0 - 6900 0.060159599 1.0063892 37 43 264 221 0 0 - 7000 0.061738744 1.0031443 39 41 259 218 0 0 - 7100 0.043263424 1.0425248 44 36 255 219 0 0 - 7200 0.052179167 0.99512151 39 41 261 220 0 0 - 7300 0.053258707 1.0171204 43 37 256 219 0 0 - 7400 0.026037532 0.93786837 45 35 259 224 0 0 - 7500 0.029731213 1.0172281 46 34 250 216 0 0 - 7600 0.023118288 0.95628439 42 38 262 224 0 0 - 7700 0.037021854 0.99991854 42 38 263 225 0 0 - 7800 0.050404736 1.0130826 40 40 260 220 0 0 - 7900 0.035658921 0.95772506 40 40 259 219 0 0 - 8000 0.034426806 1.0028052 40 40 254 214 0 0 - 8100 0.041427611 1.0347682 40 40 256 216 0 0 - 8200 0.05986843 0.9804614 38 42 262 220 0 0 - 8300 0.041419023 1.0613186 37 43 264 221 0 0 - 8400 0.065701758 1.0511531 40 40 256 216 0 0 - 8500 0.091954526 0.97190676 37 43 257 214 0 0 - 8600 0.056982532 1.017813 35 45 252 207 0 0 - 8700 0.075615111 1.0148527 29 51 263 212 0 0 - 8800 0.066070082 1.0259454 33 47 260 213 0 0 - 8900 0.055054194 1.0183535 37 43 247 204 0 0 - 9000 0.063070816 1.0266115 39 41 244 203 0 0 - 9100 0.10174156 0.99457684 34 46 246 200 0 0 - 9200 0.071667261 1.033159 33 47 249 202 0 0 - 9300 0.05520096 0.99821492 38 42 243 201 0 0 - 9400 0.050355422 0.99148522 37 43 243 200 0 0 - 9500 0.062314961 1.0042937 36 44 252 208 0 0 - 9600 0.061148899 1.0052132 37 43 254 211 0 0 - 9700 0.078695273 1.0175164 37 43 252 209 0 0 - 9800 0.067487202 1.0110138 35 45 258 213 0 0 - 9900 0.070340779 0.99640142 31 49 263 214 0 0 - 10000 0.037252172 0.99863894 32 48 259 211 0 0 -Loop time of 23.0419 on 1 procs for 10000 steps with 550 atoms - -Performance: 187484.206 tau/day, 433.991 timesteps/s -100.0% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 2.5444 | 2.5444 | 2.5444 | 0.0 | 11.04 -Bond | 0.025075 | 0.025075 | 0.025075 | 0.0 | 0.11 -Kspace | 4.7385 | 4.7385 | 4.7385 | 0.0 | 20.56 -Neigh | 0.2058 | 0.2058 | 0.2058 | 0.0 | 0.89 -Comm | 0.073087 | 0.073087 | 0.073087 | 0.0 | 0.32 -Output | 0.003464 | 0.003464 | 0.003464 | 0.0 | 0.02 -Modify | 15.417 | 15.417 | 15.417 | 0.0 | 66.91 -Other | | 0.03479 | | | 0.15 - -Nlocal: 550.000 ave 550 max 550 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 1023.00 ave 1023 max 1023 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 9644.00 ave 9644 max 9644 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 9644 -Ave neighs/atom = 17.534545 -Ave special neighs/atom = 0.85090909 -Neighbor list builds = 7576 -Dangerous builds = 0 -Total wall time: 0:00:23 \ No newline at end of file From f705d49d4557014e6af45a45fff89606799ac61e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 11 Feb 2021 09:17:14 -0500 Subject: [PATCH 14/22] reformat docs, correct spelling errors, and update false positives list --- doc/src/fix_charge_regulation.rst | 202 ++++++++++++++------ doc/utils/sphinx-config/false_positives.txt | 28 ++- 2 files changed, 172 insertions(+), 58 deletions(-) diff --git a/doc/src/fix_charge_regulation.rst b/doc/src/fix_charge_regulation.rst index cb9f55c7cd..fb63c8d7a5 100644 --- a/doc/src/fix_charge_regulation.rst +++ b/doc/src/fix_charge_regulation.rst @@ -8,21 +8,21 @@ 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* + + 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 + *pKa* value = acid dissociation constant *pKb* value = base dissociation constant *pIp* value = chemical potential of free cations *pIm* value = chemical potential of free anions @@ -30,7 +30,7 @@ Syntax *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 + *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 @@ -38,124 +38,212 @@ Syntax *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. + *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) + *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 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 discreet, ionizable groups or surface sites. +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. +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^-}`. +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 +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. +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 +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. +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 simultanously added a base ionization reaction (:math:`\mathrm{B} \rightleftharpoons \mathrm{B}^++\mathrm{OH}^-`) + 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, + +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 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. +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: +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 + 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 temprature *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 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 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. +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. +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 *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 *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*. +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: + +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 +* 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 USER-MISC 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. +This fix is part of the USER-MISC package. It is only enabled if LAMMPS +was built with that package. See the :doc:`Build package +` doc page for more info. -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*. +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. -Note: Region restrictions are not yet implemented. +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 """""""""""""""" diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 9937a98850..3a3729eefa 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -260,6 +260,7 @@ bitmask bitrate bitrates Bitzek +Bjerrum Blaise blanchedalmond blocksize @@ -500,6 +501,8 @@ coulgauss coulombic Coulombic Coulombics +counterion +counterions Courant covalent covalently @@ -728,6 +731,7 @@ DRUDE dsf dsmc dt +dtemp dtgrow dtheta dtshrink @@ -876,6 +880,7 @@ equilibrates equilibrating equilibration Equilibria +equilibria equilization equipartitioning Ercolessi @@ -1210,6 +1215,7 @@ hbnewflag hbond hcp heatconduction +Hebbeker Hebenstreit Hecht Heenen @@ -1277,6 +1283,7 @@ hy hydrophobicity hydrostatic hydrostatically +hydroxyl Hynninen Hyoungki hyperdynamics @@ -1367,6 +1374,7 @@ ints inv invariants inversed +ionizable ionocovalent iostreams iparam @@ -1546,6 +1554,7 @@ Koning Kooser Korn Koskinen +Kosovan Koster Kosztin Kp @@ -1591,6 +1600,7 @@ Lamoureux Lanczos Lande Landron +Landsgesell langevin Langevin Langston @@ -1728,10 +1738,13 @@ lpsapi lrt lsfftw ltbbmalloc +Lua lubricateU lucy -Lua Luding +Luijten +lunit +Lunkad Lussetti Lustig lval @@ -2015,6 +2028,7 @@ multiscale multisectioning multithreading Multithreading +multivalent Mundy Murdick Murtola @@ -2060,6 +2074,7 @@ Nanoletters nanomechanics nanometer nanometers +nanoparticle nanoparticles Nanotube nanotube @@ -2167,6 +2182,7 @@ nm Nm Nmax nmax +nmc Nmin nmin Nmols @@ -2299,6 +2315,7 @@ omp OMP onelevel oneway +onlysalt onn ons OO @@ -2380,6 +2397,8 @@ pbc pc pchain Pchain +pcmoves +pmcmoves Pdamp pdb pdf @@ -2424,6 +2443,7 @@ phosphide Phs Physica physik +pI Piaggi picocoulomb picocoulombs @@ -2435,7 +2455,9 @@ pid piecewise Pieniazek Pieter +pIm pimd +pIp Piola Pisarev Pishevar @@ -2450,6 +2472,9 @@ ploop PloS plt plumedfile +pKa +pKb +pKs pmb Pmolrotate Pmoltrans @@ -2768,6 +2793,7 @@ rst rstyle Rubensson Rubia +Rud Rudd Rudra Rudranarayan From d81f03706cb8783020c990f6701933036c05e16f Mon Sep 17 00:00:00 2001 From: tc387 Date: Mon, 12 Apr 2021 01:30:36 -0500 Subject: [PATCH 15/22] Added an example using real units. --- .../charge_regulation/data.chreg-acid-real | 235 ++++++++++++++++++ .../misc/charge_regulation/in.chreg-acid-real | 44 ++++ .../log.11Apr21.chreg-acid-real.g++.1 | 145 +++++++++++ .../log.11Apr21.chreg-acid-real.g++.4 | 145 +++++++++++ 4 files changed, 569 insertions(+) create mode 100644 examples/USER/misc/charge_regulation/data.chreg-acid-real create mode 100644 examples/USER/misc/charge_regulation/in.chreg-acid-real create mode 100644 examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.1 create mode 100644 examples/USER/misc/charge_regulation/log.11Apr21.chreg-acid-real.g++.4 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/in.chreg-acid-real b/examples/USER/misc/charge_regulation/in.chreg-acid-real new file mode 100644 index 0000000000..195b163d96 --- /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 3.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/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..3b766d662d --- /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 3.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 = 93 + ghost atom cutoff = 93 + binsize = 46.5, 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.707 | 3.707 | 3.707 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 297.69733 1000 810 25 75 0 0 83 8 + 1100 -8.9364878 292.52429 1100 891 22 78 0 0 88 10 + 1200 -8.733737 316.79814 1200 963 21 79 0 0 88 9 + 1300 -8.0946506 350.85016 1300 1043 21 79 0 0 88 9 + 1400 -7.1835794 283.90836 1400 1128 17 83 0 0 93 10 + 1500 -6.5673667 306.70066 1500 1208 23 77 0 0 87 10 + 1600 -7.0819412 272.07245 1600 1288 21 79 0 0 89 10 + 1700 -5.8907481 301.00694 1700 1365 28 72 0 0 84 12 + 1800 -4.9932405 282.95729 1800 1447 24 76 0 0 82 6 + 1900 -4.3273176 296.96436 1900 1527 22 78 0 0 86 8 + 2000 -4.4859306 299.76741 2000 1600 26 74 0 0 81 7 +Loop time of 1.15911 on 1 procs for 2000 steps with 188 atoms + +Performance: 1490.798 ns/day, 0.016 hours/ns, 1725.460 timesteps/s +99.5% 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.036171 | 0.036171 | 0.036171 | 0.0 | 3.12 +Kspace | 0.37716 | 0.37716 | 0.37716 | 0.0 | 32.54 +Neigh | 0.022399 | 0.022399 | 0.022399 | 0.0 | 1.93 +Comm | 0.005311 | 0.005311 | 0.005311 | 0.0 | 0.46 +Output | 0.000745 | 0.000745 | 0.000745 | 0.0 | 0.06 +Modify | 0.71566 | 0.71566 | 0.71566 | 0.0 | 61.74 +Other | | 0.001663 | | | 0.14 + +Nlocal: 188.000 ave 188 max 188 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 411.000 ave 411 max 411 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1268.00 ave 1268 max 1268 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 1268 +Ave neighs/atom = 6.7446809 +Neighbor list builds = 2195 +Dangerous builds = 15 +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..7ab22c1f36 --- /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 3.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 = 93 + ghost atom cutoff = 93 + binsize = 46.5, 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.9144028 317.49717 100 73 15 85 0 0 94 9 + 200 -5.9183735 315.31348 200 157 24 76 0 0 86 10 + 300 -6.7851544 295.82718 300 243 21 79 0 0 86 7 + 400 -6.3777493 297.53619 400 316 16 84 0 0 91 7 + 500 -6.0281518 287.62012 500 398 15 85 0 0 93 8 + 600 -8.4403907 301.30302 600 483 14 86 0 0 94 8 + 700 -9.6450828 305.33793 700 563 15 85 0 0 96 11 + 800 -6.1034312 307.18396 800 646 20 80 0 0 85 5 + 900 -7.3098915 295.21039 900 729 24 76 0 0 86 10 + 1000 -6.721795 316.34459 1000 803 25 75 0 0 84 9 + 1100 -7.389073 326.53025 1100 882 23 77 0 0 87 10 + 1200 -9.6721231 327.15878 1200 958 20 80 0 0 89 9 + 1300 -7.4738885 295.09338 1300 1045 20 80 0 0 88 8 + 1400 -7.8136191 297.62074 1400 1127 18 82 0 0 92 10 + 1500 -7.6522652 284.20977 1500 1204 24 76 0 0 85 9 + 1600 -8.473883 293.37704 1600 1283 22 78 0 0 92 14 + 1700 -5.7030629 327.53233 1700 1366 26 74 0 0 83 9 + 1800 -6.1817998 278.22073 1800 1447 21 79 0 0 84 5 + 1900 -5.3113964 293.69193 1900 1526 24 76 0 0 85 9 + 2000 -5.5827334 307.91424 2000 1599 26 74 0 0 80 6 +Loop time of 0.547632 on 4 procs for 2000 steps with 186 atoms + +Performance: 3155.407 ns/day, 0.008 hours/ns, 3652.091 timesteps/s +99.5% 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.008417 | 0.01004 | 0.010817 | 1.0 | 1.83 +Kspace | 0.17103 | 0.17157 | 0.17208 | 0.1 | 31.33 +Neigh | 0.004536 | 0.0052815 | 0.005857 | 0.7 | 0.96 +Comm | 0.023141 | 0.02398 | 0.02617 | 0.8 | 4.38 +Output | 0.000556 | 0.00063325 | 0.000864 | 0.0 | 0.12 +Modify | 0.33403 | 0.33441 | 0.33471 | 0.1 | 61.07 +Other | | 0.001711 | | | 0.31 + +Nlocal: 46.5000 ave 48 max 44 min +Histogram: 1 0 0 0 0 1 0 0 0 2 +Nghost: 241.500 ave 244 max 238 min +Histogram: 1 0 0 0 0 1 0 0 1 1 +Neighs: 303.750 ave 333 max 286 min +Histogram: 2 0 0 0 1 0 0 0 0 1 + +Total # of neighbors = 1215 +Ave neighs/atom = 6.5322581 +Neighbor list builds = 2196 +Dangerous builds = 12 +Total wall time: 0:00:00 From 7d95943b7e2ddb500addba2f69e78d7821eed3b5 Mon Sep 17 00:00:00 2001 From: tc387 Date: Mon, 12 Apr 2021 01:46:39 -0500 Subject: [PATCH 16/22] increased bin size in example input file to avoid dangerous builds --- .../misc/charge_regulation/in.chreg-acid-real | 2 +- .../log.11Apr21.chreg-acid-real.g++.1 | 66 +++++++------- .../log.11Apr21.chreg-acid-real.g++.4 | 88 +++++++++---------- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/examples/USER/misc/charge_regulation/in.chreg-acid-real b/examples/USER/misc/charge_regulation/in.chreg-acid-real index 195b163d96..d7225f33ea 100644 --- a/examples/USER/misc/charge_regulation/in.chreg-acid-real +++ b/examples/USER/misc/charge_regulation/in.chreg-acid-real @@ -2,7 +2,7 @@ units real atom_style charge -neighbor 3.0 bin +neighbor 10.0 bin read_data data.chreg-acid-real #real units 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 index 3b766d662d..6e50ea5ef3 100644 --- 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 @@ -3,7 +3,7 @@ LAMMPS (10 Feb 2021) units real atom_style charge -neighbor 3.0 bin +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) @@ -83,16 +83,16 @@ WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulo Neighbor list info ... update every 1 steps, delay 10 steps, check yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 93 - ghost atom cutoff = 93 - binsize = 46.5, bins = 8 8 8 + 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.707 | 3.707 | 3.707 Mbytes +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 @@ -104,42 +104,42 @@ Step PotEng c_dtemp f_chareg[1] f_chareg[2] f_chareg[3] f_chareg[4] f_chareg[5] 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 297.69733 1000 810 25 75 0 0 83 8 - 1100 -8.9364878 292.52429 1100 891 22 78 0 0 88 10 - 1200 -8.733737 316.79814 1200 963 21 79 0 0 88 9 - 1300 -8.0946506 350.85016 1300 1043 21 79 0 0 88 9 - 1400 -7.1835794 283.90836 1400 1128 17 83 0 0 93 10 - 1500 -6.5673667 306.70066 1500 1208 23 77 0 0 87 10 - 1600 -7.0819412 272.07245 1600 1288 21 79 0 0 89 10 - 1700 -5.8907481 301.00694 1700 1365 28 72 0 0 84 12 - 1800 -4.9932405 282.95729 1800 1447 24 76 0 0 82 6 - 1900 -4.3273176 296.96436 1900 1527 22 78 0 0 86 8 - 2000 -4.4859306 299.76741 2000 1600 26 74 0 0 81 7 -Loop time of 1.15911 on 1 procs for 2000 steps with 188 atoms + 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: 1490.798 ns/day, 0.016 hours/ns, 1725.460 timesteps/s -99.5% CPU use with 1 MPI tasks x no OpenMP threads +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.036171 | 0.036171 | 0.036171 | 0.0 | 3.12 -Kspace | 0.37716 | 0.37716 | 0.37716 | 0.0 | 32.54 -Neigh | 0.022399 | 0.022399 | 0.022399 | 0.0 | 1.93 -Comm | 0.005311 | 0.005311 | 0.005311 | 0.0 | 0.46 -Output | 0.000745 | 0.000745 | 0.000745 | 0.0 | 0.06 -Modify | 0.71566 | 0.71566 | 0.71566 | 0.0 | 61.74 -Other | | 0.001663 | | | 0.14 +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: 188.000 ave 188 max 188 min +Nlocal: 187.000 ave 187 max 187 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 411.000 ave 411 max 411 min +Nghost: 437.000 ave 437 max 437 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 1268.00 ave 1268 max 1268 min +Neighs: 1500.00 ave 1500 max 1500 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Total # of neighbors = 1268 -Ave neighs/atom = 6.7446809 -Neighbor list builds = 2195 -Dangerous builds = 15 +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 index 7ab22c1f36..927e29c1f3 100644 --- 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 @@ -3,7 +3,7 @@ LAMMPS (10 Feb 2021) units real atom_style charge -neighbor 3.0 bin +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) @@ -83,9 +83,9 @@ WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulo Neighbor list info ... update every 1 steps, delay 10 steps, check yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 93 - ghost atom cutoff = 93 - binsize = 46.5, bins = 8 8 8 + 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 @@ -95,51 +95,51 @@ Neighbor list info ... 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.9144028 317.49717 100 73 15 85 0 0 94 9 - 200 -5.9183735 315.31348 200 157 24 76 0 0 86 10 - 300 -6.7851544 295.82718 300 243 21 79 0 0 86 7 - 400 -6.3777493 297.53619 400 316 16 84 0 0 91 7 - 500 -6.0281518 287.62012 500 398 15 85 0 0 93 8 - 600 -8.4403907 301.30302 600 483 14 86 0 0 94 8 - 700 -9.6450828 305.33793 700 563 15 85 0 0 96 11 - 800 -6.1034312 307.18396 800 646 20 80 0 0 85 5 - 900 -7.3098915 295.21039 900 729 24 76 0 0 86 10 - 1000 -6.721795 316.34459 1000 803 25 75 0 0 84 9 - 1100 -7.389073 326.53025 1100 882 23 77 0 0 87 10 - 1200 -9.6721231 327.15878 1200 958 20 80 0 0 89 9 - 1300 -7.4738885 295.09338 1300 1045 20 80 0 0 88 8 - 1400 -7.8136191 297.62074 1400 1127 18 82 0 0 92 10 - 1500 -7.6522652 284.20977 1500 1204 24 76 0 0 85 9 - 1600 -8.473883 293.37704 1600 1283 22 78 0 0 92 14 - 1700 -5.7030629 327.53233 1700 1366 26 74 0 0 83 9 - 1800 -6.1817998 278.22073 1800 1447 21 79 0 0 84 5 - 1900 -5.3113964 293.69193 1900 1526 24 76 0 0 85 9 - 2000 -5.5827334 307.91424 2000 1599 26 74 0 0 80 6 -Loop time of 0.547632 on 4 procs for 2000 steps with 186 atoms + 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: 3155.407 ns/day, 0.008 hours/ns, 3652.091 timesteps/s -99.5% CPU use with 4 MPI tasks x no OpenMP threads +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.008417 | 0.01004 | 0.010817 | 1.0 | 1.83 -Kspace | 0.17103 | 0.17157 | 0.17208 | 0.1 | 31.33 -Neigh | 0.004536 | 0.0052815 | 0.005857 | 0.7 | 0.96 -Comm | 0.023141 | 0.02398 | 0.02617 | 0.8 | 4.38 -Output | 0.000556 | 0.00063325 | 0.000864 | 0.0 | 0.12 -Modify | 0.33403 | 0.33441 | 0.33471 | 0.1 | 61.07 -Other | | 0.001711 | | | 0.31 +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: 46.5000 ave 48 max 44 min -Histogram: 1 0 0 0 0 1 0 0 0 2 -Nghost: 241.500 ave 244 max 238 min -Histogram: 1 0 0 0 0 1 0 0 1 1 -Neighs: 303.750 ave 333 max 286 min -Histogram: 2 0 0 0 1 0 0 0 0 1 +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 = 1215 -Ave neighs/atom = 6.5322581 -Neighbor list builds = 2196 -Dangerous builds = 12 +Total # of neighbors = 1614 +Ave neighs/atom = 8.5396825 +Neighbor list builds = 2081 +Dangerous builds = 0 Total wall time: 0:00:00 From bc25fa82688cb7506143454774115f0471dada1f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 09:59:02 -0400 Subject: [PATCH 17/22] full integration into documentation build system --- doc/src/Commands_fix.rst | 1 + doc/src/fix.rst | 1 + doc/src/fix_charge_regulation.rst | 14 ++++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) 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/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 index fb63c8d7a5..ef91db1e59 100644 --- a/doc/src/fix_charge_regulation.rst +++ b/doc/src/fix_charge_regulation.rst @@ -225,7 +225,7 @@ quantities: Restrictions """""""""""" -This fix is part of the USER-MISC package. It is only enabled if LAMMPS +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. @@ -243,7 +243,9 @@ 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. +.. note:: + + Region restrictions are not yet implemented. Related commands """""""""""""""" @@ -253,7 +255,11 @@ Related commands 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 + +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 ---------- @@ -267,4 +273,4 @@ pH = 7.0; pKa = 100.0; pKb = 100.0; pIp = 5.0; pIm = 5.0; pKs = 14.0; acid_type .. _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). +**(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). From 9658b8e645f1fb611e52e1771e3a4b4cd6be7224 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 10:05:52 -0400 Subject: [PATCH 18/22] move fix charge/regulation to MC package (examples stay in place for now) --- doc/src/Packages_details.rst | 6 +++++- src/{USER-MISC => MC}/fix_charge_regulation.cpp | 0 src/{USER-MISC => MC}/fix_charge_regulation.h | 0 src/USER-MISC/README | 1 - 4 files changed, 5 insertions(+), 2 deletions(-) rename src/{USER-MISC => MC}/fix_charge_regulation.cpp (100%) rename src/{USER-MISC => MC}/fix_charge_regulation.h (100%) diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index b662ae73c7..d5c011012d 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -585,7 +585,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:** @@ -593,8 +593,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/src/USER-MISC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp similarity index 100% rename from src/USER-MISC/fix_charge_regulation.cpp rename to src/MC/fix_charge_regulation.cpp diff --git a/src/USER-MISC/fix_charge_regulation.h b/src/MC/fix_charge_regulation.h similarity index 100% rename from src/USER-MISC/fix_charge_regulation.h rename to src/MC/fix_charge_regulation.h diff --git a/src/USER-MISC/README b/src/USER-MISC/README index ef25a0c116..314fe6146e 100644 --- a/src/USER-MISC/README +++ b/src/USER-MISC/README @@ -53,7 +53,6 @@ dihedral_style table/cut, Mike Salerno, ksalerno@pha.jhu.edu, 11 May 18 fix accelerate/cos, Zheng Gong (ENS de Lyon), z.gong@outlook.com, 24 Apr 20 fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11 fix ave/correlate/long, Jorge Ramirez (UPM Madrid), jorge.ramirez at upm.es, 21 Oct 2015 -fix charge_regulation, Tine Curk and Jiaxing Yuan, tcurk5@gmail.com, 02 Feb 2021 fix electron/stopping/fit, James Stewart (SNL), jstewa .at. sandia.gov, 23 Sep 2020 fix electron/stopping, Konstantin Avchaciov, k.avchachov at gmail.com, 26 Feb 2019 fix ffl, David Wilkins (EPFL Lausanne), david.wilkins @ epfl.ch, 28 Sep 2018 From 0c79673d931091f8628c2f705c5133c39a471fed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 10:14:31 -0400 Subject: [PATCH 19/22] make fix charge/regulation compatible with USER-INTEL package --- src/MC/fix_charge_regulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp index 5479082158..0aa3def153 100644 --- a/src/MC/fix_charge_regulation.cpp +++ b/src/MC/fix_charge_regulation.cpp @@ -45,7 +45,6 @@ #include #include - using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; @@ -1082,6 +1081,7 @@ double FixChargeRegulation::energy_full() { 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; From a572142e6f4088eddf0f48e8a5d76232a0ee23ec Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 10:25:10 -0400 Subject: [PATCH 20/22] fix inconsistent new/delete --- src/MC/fix_charge_regulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp index 0aa3def153..797d7fb5b0 100644 --- a/src/MC/fix_charge_regulation.cpp +++ b/src/MC/fix_charge_regulation.cpp @@ -130,7 +130,7 @@ FixChargeRegulation::~FixChargeRegulation() { delete random_equal; delete random_unequal; - delete idftemp; + delete[] idftemp; if (group) { int igroupall = group->find("all"); From 65ba022c2a0ce3ab6e4822bfdc279679e511822c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 10:25:24 -0400 Subject: [PATCH 21/22] simplify --- src/MC/fix_charge_regulation.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp index 797d7fb5b0..47adad3f6d 100644 --- a/src/MC/fix_charge_regulation.cpp +++ b/src/MC/fix_charge_regulation.cpp @@ -1295,10 +1295,7 @@ void FixChargeRegulation::options(int narg, char **arg) { } else if (strcmp(arg[iarg], "tempfixid") == 0) { if (iarg + 2 > narg) error->all(FLERR, "Illegal fix charge/regulation command"); - int n = strlen(arg[iarg + 1]) + 1; - delete[] idftemp; - idftemp = new char[n]; - strcpy(idftemp, arg[iarg + 1]); + idftemp = utils::strdup(arg[iarg+1]); setThermoTemperaturePointer(); iarg += 2; } else if (strcmp(arg[iarg], "rxd") == 0) { @@ -1371,9 +1368,7 @@ void FixChargeRegulation::options(int narg, char **arg) { ngroupsmax * sizeof(char *), "fix_charge_regulation:groupstrings"); } - int n = strlen(arg[iarg + 1]) + 1; - groupstrings[ngroups] = new char[n]; - strcpy(groupstrings[ngroups], arg[iarg + 1]); + groupstrings[ngroups] = utils::strdup(arg[iarg+1]); ngroups++; iarg += 2; } else error->all(FLERR, "Illegal fix charge/regulation command"); From 82e1c4fb121c7e5c33f40406b0ed0c6f1b831121 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Apr 2021 10:25:39 -0400 Subject: [PATCH 22/22] silence compiler warnings --- src/MC/fix_charge_regulation.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp index 47adad3f6d..34391b86fb 100644 --- a/src/MC/fix_charge_regulation.cpp +++ b/src/MC/fix_charge_regulation.cpp @@ -14,6 +14,7 @@ /* ---------------------------------------------------------------------- Contributing author: Tine Curk (tcurk5@gmail.com) and Jiaxing Yuan (yuanjiaxing123@hotmail.com) ------------------------------------------------------------------------- */ + #include "fix_charge_regulation.h" #include "angle.h" @@ -652,7 +653,7 @@ void FixChargeRegulation::backward_ions() { double energy_before = energy_stored; double factor; - int mask1_tmp, mask2_tmp; + int mask1_tmp = 0, mask2_tmp = 0; double *dummyp = nullptr; int m1 = -1, m2 = -1; @@ -724,12 +725,6 @@ void FixChargeRegulation::backward_ions() { atom->mask[m2] = mask2_tmp; } } - } else { - // reassign original charge and mask - if (m1 >= 0) { - atom->q[m1] = 1; - atom->mask[m1] = mask1_tmp; - } } } } @@ -738,7 +733,7 @@ void FixChargeRegulation::forward_ions_multival() { double energy_before = energy_stored; double factor = 1; - double *dummyp; + 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]) { @@ -792,7 +787,7 @@ void FixChargeRegulation::backward_ions_multival() { double energy_before = energy_stored; double factor = 1; - double *dummyp; // dummy pointer + 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