source: sasmodels/sasmodels/models/be_polyelectrolyte.py @ d8b4c5a

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since d8b4c5a was d8b4c5a, checked in by butler, 6 years ago

Fix typo, clarify validation text and add tests

Addresses PR comments: removed redundant information in Iq function: doc
string replaced as suggested with text pointing to table and remove
default values on each parameter in the function call.
Also added verbiage to validation section to hopefully clarify what was
happening and what was done, fixed typo, and added back unit tests with
salt along with comment that these are "self-validated" and need proper
tests at some point in the future

  • Property mode set to 100644
File size: 8.9 KB
Line 
1r"""
2Definition
3----------
4This model calculates the structure factor of a polyelectrolyte solution with
5the RPA expression derived by Borue and Erukhimovich\ [#Borue]_.  Note however
6that the fitting procedure here does not follow the notation in that reference
7as 's' and 't' are **not** decoupled. Instead the scattering intensity $I(q)$
8is calculated as
9
10.. math::
11
12    I(q) = K\frac{q^2+k^2}{4\pi L_b\alpha ^2}
13    \frac{1}{1+r_{0}^4(q^2+k^2)(q^2-12hC_a/b^2)} + background
14
15    k^2 = 4\pi L_b(2C_s + \alpha C_a)
16
17    r_{0}^2 = \frac{b}{\alpha \sqrt{C_a 48\pi L_b}}
18
19where
20
21$K$ is the contrast factor for the polymer which is defined differently than in
22other models and is given in barns where $1 barn = 10^{-24} cm^2$.  $K$ is
23defined as:
24
25.. math::
26
27    K = a^2
28
29    a = b_p - (v_p/v_s) b_s
30
31where $b_p$ and $b_s$ are sum of the scattering lengths of the atoms
32constituting the monomer of the polymer and the sum of the scattering lengths
33of the atoms constituting the solvent molecules respectively, and $v_p$ and
34$v_s$ are the partial molar volume of the polymer and the solvent respectively
35
36$L_b$ is the Bjerrum length(|Ang|) - **Note:** This parameter needs to be
37kept constant for a given solvent and temperature!
38
39$h$ is the virial parameter (|Ang^3|) - **Note:** See [#Borue]_ for the
40correct interpretation of this parameter.  It incorporates second and third
41virial coefficients and can be Negative.
42
43$b$ is the monomer length(|Ang|), $C_s$ is the concentration of monovalent
44salt(1/|Ang|- converted from mol/L), $\alpha$ is the ionization degree
45(ionization degree : ratio of charged monomers  to total number of monomers),
46$C_a$ is the polymer molar concentration(1/|Ang|- converted from mol/L),
47and $background$ is the incoherent background.
48
49For 2D data the scattering intensity is calculated in the same way as 1D,
50where the $\vec q$ vector is defined as
51
52.. math::
53
54    q = \sqrt{q_x^2 + q_y^2}
55
56Validation
57----------
58
59As of the last revision, this code is believed to be correct.  However it
60needs further validation and should be used with caution at this time.  The
61history of this code goes back to a 1998 implementation. It was recently noted
62that in that implementation, while both the polymer concentration and salt
63concentration were converted from experimental units of mol/L to more
64dimensionally useful units of 1/|Ang|^3, only the converted version of the
65polymer concentration was actually being used in the calculation while the
66unconverted salt concentration (still in units of mol/L) was being used.  This
67was carried through to sasmodels today (except that the line of code converting
68the salt concentration to the new units was dropped somewhere along the line).
69Simple dimensional analysis of the calculation shows that it is in fact the
70converted salt concentration must be used and the original code suggests that
71was the intention.  We therefore believe this is now correct.  Once better
72validation has been performed this note will be removed.
73
74References
75----------
76
77.. [#Borue] V Y Borue, I Y Erukhimovich, *Macromolecules*, 21 (1988) 3240
78.. [#] J F Joanny, L Leibler, *Journal de Physique*, 51 (1990) 545
79.. [#] A Moussaid, F Schosseler, J P Munch, S Candau, *J. Journal de Physique
80   II France*, 3 (1993) 573
81.. [#] E Raphael, J F Joanny, *Europhysics Letters*, 11 (1990) 179
82
83Authorship and Verification
84----------------------------
85
86* **Author:** NIST IGOR/DANSE **Date:** pre 2010
87* **Last Modified by:** Paul Butler **Date:** September 25, 2018
88* **Last Reviewed by:** Paul Butler **Date:** September 25, 2018
89"""
90
91import numpy as np
92from numpy import inf, pi, sqrt
93
94name = "be_polyelectrolyte"
95title = "Polyelectrolyte with the RPA expression derived by Borue and Erukhimovich"
96description = """
97            Evaluate
98            F(x) = K 1/(4 pi Lb (alpha)^(2)) (q^(2)+k2)/(1+(r02)^(2))
99                 (q^(2)+k2) (q^(2)-(12 h C/b^(2)))
100
101            has 3 internal parameters :
102                   The inverse Debye Length: K2 = 4 pi Lb (2 Cs+alpha C)
103                   r02 =1/alpha/Ca^(0.5) (B/(48 pi Lb)^(0.5))
104                   Ca = 6.022136e-4 C
105            """
106category = "shape-independent"
107
108# pylint: disable=bad-whitespace, line-too-long
109#   ["name", "units", default, [lower, upper], "type", "description"],
110parameters = [
111    ["contrast_factor",       "barns",   10.0,  [-inf, inf], "", "Contrast factor of the polymer"],
112    ["bjerrum_length",        "Ang",      7.1,  [0, inf],    "", "Bjerrum length"],
113    ["virial_param",          "Ang^3", 12.0,  [-inf, inf], "", "Virial parameter"],
114    ["monomer_length",        "Ang",     10.0,  [0, inf],    "", "Monomer length"],
115    ["salt_concentration",    "mol/L",    0.0,  [-inf, inf], "", "Concentration of monovalent salt"],
116    ["ionization_degree",     "",         0.05, [0, inf],    "", "Degree of ionization"],
117    ["polymer_concentration", "mol/L",    0.7,  [0, inf],    "", "Polymer molar concentration"],
118    ]
119# pylint: enable=bad-whitespace, line-too-long
120
121
122def Iq(q,
123       contrast_factor,
124       bjerrum_length,
125       virial_param,
126       monomer_length,
127       salt_concentration,
128       ionization_degree,
129       polymer_concentration):
130    """
131    :params: see parameter table
132    :return: 1-D form factor for polyelectrolytes in low salt
133   
134    parameter names, units, default values, and behavior (volume, sld etc) are
135    defined in the parameter table.  The concentrations are converted from
136    experimental mol/L to dimensionaly useful 1/A3 in first two lines
137    """
138
139    concentration_pol = polymer_concentration * 6.022136e-4
140    concentration_salt = salt_concentration * 6.022136e-4
141
142    k_square = 4.0 * pi * bjerrum_length * (2*concentration_salt +
143                                            ionization_degree * concentration_pol)
144
145    r0_square = 1.0/ionization_degree/sqrt(concentration_pol) * \
146                (monomer_length/sqrt((48.0*pi*bjerrum_length)))
147
148    term1 = contrast_factor/(4.0 * pi * bjerrum_length *
149                             ionization_degree**2) * (q**2 + k_square)
150
151    term2 = 1.0 + r0_square**2 * (q**2 + k_square) * \
152        (q**2 - (12.0 * virial_param * concentration_pol/(monomer_length**2)))
153
154    return term1/term2
155
156Iq.vectorized = True  # Iq accepts an array of q values
157
158def random():
159    # TODO: review random be_polyelectrolyte model generation
160    pars = dict(
161        scale=10000, #background=0,
162        #polymer_concentration=0.7,
163        polymer_concentration=np.random.beta(5, 3), # around 70%
164        #salt_concentration=0.0,
165        # keep salt concentration extremely low
166        # and use explicit molar to match polymer concentration
167        salt_concentration=np.random.beta(1, 100)*6.022136e-4,
168        #contrast_factor=10.0,
169        contrast_fact=np.random.uniform(1, 100),
170        #bjerrum_length=7.1,
171        bjerrum_length=np.random.uniform(1, 10),
172        #virial_param=12.0,
173        virial_param=np.random.uniform(-1000, 30),
174        #monomer_length=10.0,
175        monomer_length=10.0**(4*np.random.beta(1.5, 3)),
176        #ionization_degree=0.05,
177        ionization_degree=np.random.beta(1.5, 4),
178    )
179    return pars
180
181demo = dict(scale=1, background=0.1,
182            contrast_factor=10.0,
183            bjerrum_length=7.1,
184            virial_param=12.0,
185            monomer_length=10.0,
186            salt_concentration=0.0,
187            ionization_degree=0.05,
188            polymer_concentration=0.7)
189
190tests = [
191
192    # Accuracy tests based on content in test/utest_other_models.py
193    # Note that these should some day be validated beyond this self validation
194    # (circular reasoning). -- i.e. the "good value," at least for those with
195    # non zero salt concentrations, were obtained by running the current
196    # model in SasView and copying the appropriate result here.
197    #    PDB -- Sep 26, 2018
198    [{'contrast_factor':       10.0,
199      'bjerrum_length':         7.1,
200      'virial_param':          12.0,
201      'monomer_length':        10.0,
202      'salt_concentration':     0.0,
203      'ionization_degree':      0.05,
204      'polymer_concentration':  0.7,
205      'background':             0.001,
206     }, 0.001, 0.0948379],
207
208    [{'contrast_factor':       10.0,
209      'bjerrum_length':       100.0,
210      'virial_param':           3.0,
211      'monomer_length':         5.0,
212      'salt_concentration':     1.0,
213      'ionization_degree':      0.1,
214      'polymer_concentration':  1.0,
215      'background':             0.0,
216     }, 0.1, 0.253469484],
217
218    [{'contrast_factor':       10.0,
219      'bjerrum_length':       100.0,
220      'virial_param':           3.0,
221      'monomer_length':         5.0,
222      'salt_concentration':     1.0,
223      'ionization_degree':      0.1,
224      'polymer_concentration':  1.0,
225      'background':             1.0,
226     }, 0.05, 1.738358122],
227
228    [{'contrast_factor':     100.0,
229      'bjerrum_length':       10.0,
230      'virial_param':         12.0,
231      'monomer_length':       10.0,
232      'salt_concentration':    0.1,
233      'ionization_degree':     0.5,
234      'polymer_concentration': 0.1,
235      'background':           0.01,
236     }, 0.5, 0.012881893],
237    ]
Note: See TracBrowser for help on using the repository browser.