source: sasmodels/sasmodels/models/hayter_msa.py @ 5f3c534

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 5f3c534 was 5f3c534, checked in by smk78, 5 years ago

Tweaks to docs for all S(q) models as described in #1187

  • Property mode set to 100644
File size: 6.7 KB
Line 
1# Note: model title and parameter table are inserted automatically
2r"""
3Calculates the interparticle structure factor for a system of charged,
4spheroidal, objects in a dielectric medium [1,2]. When combined with an
5appropriate form factor $P(q)$, this allows for inclusion of the
6interparticle interference effects due to screened Coulombic
7repulsion between the charged particles.
8
9.. note::
10
11   This routine only works for charged particles! If the charge is set
12   to zero the routine may self-destruct! For uncharged particles use
13   the :ref:`hardsphere` $S(q)$ instead.
14   
15.. note::
16
17   Earlier versions of SasView did not incorporate the so-called
18   $\beta(q)$ ("beta") correction [3] for polydispersity and non-sphericity.
19   This is only available in SasView versions 4.2.2 and higher.
20
21The salt concentration is used to compute the ionic strength of the solution
22which in turn is used to compute the Debye screening length. There is no
23provision for entering the ionic strength directly. **At present the
24counterions are assumed to be monovalent**, though it should be possible
25to simulate the effect of multivalent counterions by increasing the salt
26concentration.
27
28Over the range 0 - 100 C the dielectric constant $\kappa$ of water may be
29approximated with a maximum deviation of 0.01 units by the empirical
30formula [4]
31
32.. math::
33
34    \kappa = 87.740 - 0.40008 T + 9.398x10^{-4} T^2 - 1.410x10^{-6} T^3
35   
36where $T$ is the temperature in celsius.
37
38In SasView the effective radius may be calculated from the parameters
39used in the form factor $P(q)$ that this $S(q)$ is combined with.
40
41The computation uses a Taylor series expansion at very small rescaled $qR$, to
42avoid some serious rounding error issues, this may result in a minor artefact
43in the transition region under some circumstances.
44
45For 2D data, the scattering intensity is calculated in the same way as 1D,
46where the $q$ vector is defined as
47
48.. math::
49
50    q = \sqrt{q_x^2 + q_y^2}
51
52
53References
54----------
55
56.. [#] J B Hayter and J Penfold, *Molecular Physics*, 42 (1981) 109-118
57
58.. [#] J P Hansen and J B Hayter, *Molecular Physics*, 46 (1982) 651-656
59
60.. [#] M Kotlarchyk and S-H Chen, *J. Chem. Phys.*, 79 (1983) 2461-2469
61
62.. [#] C G Malmberg and A A Maryott, *J. Res. Nat. Bureau Standards*, 56 (1956) 2641
63
64Source
65------
66
67`hayter_msa.py <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/hayter_msa.py>`_
68
69`hayter_msa.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/hayter_msa.c>`_
70
71Authorship and Verification
72----------------------------
73
74* **Author:**
75* **Last Modified by:**
76* **Last Reviewed by:** Steve King **Date:** March 27, 2019
77* **Source added by :** Steve King **Date:** March 25, 2019
78"""
79
80import numpy as np
81from numpy import inf
82
83category = "structure-factor"
84structure_factor = True
85single = False  # double precision only!
86
87#  dp[0] = 2.0*radius_effective();
88#  dp[1] = fabs(charge());
89#  dp[2] = volfraction();
90#  dp[3] = temperature();
91#  dp[4] = concentration_salt();
92#  dp[5] = dielectconst();
93
94
95
96
97name = "hayter_msa"
98title = "Hayter-Penfold Rescaled Mean Spherical Approximation (RMSA) structure factor for charged spheres"
99description = """\
100    [Hayter-Penfold RMSA charged sphere interparticle S(Q) structure factor]
101        Interparticle structure factor S(Q) for charged hard spheres.
102    This routine only works for charged particles! For uncharged particles
103    use the hardsphere S(q) instead. The "beta(q)" correction is available
104    in versions 4.2.2 and higher.
105"""
106
107
108# pylint: disable=bad-whitespace, line-too-long
109#             [ "name", "units", default, [lower, upper], "type", "description" ],
110parameters = [
111    ["radius_effective", "Ang", 20.75,   [0, inf],    "volume", "effective radius of charged sphere"],
112    ["volfraction",   "None",     0.0192, [0, 0.74],   "", "volume fraction of spheres"],
113    ["charge",        "e",   19.0,    [0, 200],    "", "charge on sphere (in electrons)"],
114    ["temperature",   "K",  318.16,   [0, 450],    "", "temperature, in Kelvin, for Debye length calculation"],
115    ["concentration_salt",      "M",    0.0,    [0, inf], "", "conc of salt, moles/litre, 1:1 electolyte, for Debye length"],
116    ["dielectconst",  "None",    71.08,   [-inf, inf], "", "dielectric constant (relative permittivity) of solvent, kappa, default water, for Debye length"]
117    ]
118# pylint: enable=bad-whitespace, line-too-long
119
120source = ["hayter_msa.c"]
121# No volume normalization despite having a volume parameter
122# This should perhaps be volume normalized?
123form_volume = """
124    return 1.0;
125    """
126
127def random():
128    """Return a random parameter set for the model."""
129    # TODO: too many failures for random hayter_msa parameters
130    pars = dict(
131        scale=1, background=0,
132        radius_effective=10**np.random.uniform(1, 4.7),
133        volfraction=10**np.random.uniform(-2, 0),  # high volume fraction
134        charge=min(int(10**np.random.uniform(0, 1.3)+0.5), 200),
135        temperature=10**np.random.uniform(0, np.log10(450)), # max T = 450
136        #concentration_salt=10**np.random.uniform(-3, 1),
137        dialectconst=10**np.random.uniform(0, 6),
138        #charge=10,
139        #temperature=318.16,
140        concentration_salt=0.0,
141        #dielectconst=71.08,
142    )
143    return pars
144
145# default parameter set,  use  compare.sh -midQ -linear
146# note the calculation varies in different limiting cases so a wide range of
147# parameters will be required for a thorough test!
148# odd that the default st has concentration_salt zero
149demo = dict(radius_effective=20.75,
150            charge=19.0,
151            volfraction=0.0192,
152            temperature=318.16,
153            concentration_salt=0.05,
154            dielectconst=71.08,
155            radius_effective_pd=0.1,
156            radius_effective_pd_n=40)
157#
158# attempt to use same values as old sasview unit test at Q=.001 was 0.0712928,
159# then add lots new ones assuming values from new model are OK, need some
160# low Q values to test the small Q Taylor expansion
161tests = [
162    [{'scale': 1.0,
163      'background': 0.0,
164      'radius_effective': 20.75,
165      'charge': 19.0,
166      'volfraction': 0.0192,
167      'temperature': 298.0,
168      'concentration_salt': 0,
169      'dielectconst': 78.0,
170      'radius_effective_pd': 0},
171     [0.00001, 0.0010, 0.01, 0.075], [0.0711646, 0.0712928, 0.0847006, 1.07150]],
172    [{'scale': 1.0,
173      'background': 0.0,
174      'radius_effective': 20.75,
175      'charge': 19.0,
176      'volfraction': 0.0192,
177      'temperature': 298.0,
178      'concentration_salt': 0.05,
179      'dielectconst': 78.0,
180      'radius_effective_pd': 0.1,
181      'radius_effective_pd_n': 40},
182     [0.00001, 0.0010, 0.01, 0.075], [0.450272, 0.450420, 0.465116, 1.039625]]
183    ]
184# ADDED by:  RKH  ON: 16Mar2016 converted from sasview, new Taylor expansion at smallest rescaled Q
Note: See TracBrowser for help on using the repository browser.