source: sasmodels/sasmodels/models/polymer_excl_volume.py @ b297ba9

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since b297ba9 was b297ba9, checked in by Paul Kienzle <pkienzle@…>, 5 years ago

lint

  • Property mode set to 100644
File size: 5.6 KB
RevLine 
[23d3b41]1r"""
[513efc5]2This model describes the scattering from polymer chains subject to excluded
3volume effects and has been used as a template for describing mass fractals.
[23d3b41]4
5Definition
6----------
7
[513efc5]8The form factor was originally presented in the following integral form
9(Benoit, 1957)
[23d3b41]10
11.. math::
12
13    P(Q)=2\int_0^{1}dx(1-x)exp\left[-\frac{Q^2a^2}{6}n^{2v}x^{2v}\right]
14
15where $\nu$ is the excluded volume parameter
16(which is related to the Porod exponent $m$ as $\nu=1/m$ ),
17$a$ is the statistical segment length of the polymer chain,
18and $n$ is the degree of polymerization.
[a2ca6e5]19
[547c6f0]20This integral was put into an almost analytical form as follows
[513efc5]21(Hammouda, 1993)
[23d3b41]22
23.. math::
24
[547c6f0]25    P(Q)=\frac{1}{\nu U^{1/2\nu}}
26    \left\{
27        \gamma\left(\frac{1}{2\nu},U\right) -
28        \frac{1}{U^{1/2\nu}}\gamma\left(\frac{1}{\nu},U\right)
29    \right\}
[a2ca6e5]30
[547c6f0]31and later recast as (for example, Hore, 2013; Hammouda & Kim, 2017)
[a2ca6e5]32
33.. math::
34
35    P(Q)=\frac{1}{\nu U^{1/2\nu}}\gamma\left(\frac{1}{2\nu},U\right) -
[23d3b41]36    \frac{1}{\nu U^{1/\nu}}\gamma\left(\frac{1}{\nu},U\right)
37
38where $\gamma(x,U)$ is the incomplete gamma function
39
40.. math::
41
[547c6f0]42    \gamma(x,U)=\int_0^{U}dt\ \exp(-t)t^{x-1}
[23d3b41]43
44and the variable $U$ is given in terms of the scattering vector $Q$ as
45
46.. math::
47
48    U=\frac{Q^2a^2n^{2\nu}}{6} = \frac{Q^2R_{g}^2(2\nu+1)(2\nu+2)}{6}
49
[a2ca6e5]50The two analytic forms are equivalent. In the 1993 paper
51
52.. math::
53
54    \frac{1}{\nu U^{1/2\nu}}
55
56has been factored out.
57
58**SasView implements the 1993 expression**.
59
[23d3b41]60The square of the radius-of-gyration is defined as
61
62.. math::
63
64    R_{g}^2 = \frac{a^2n^{2\nu}}{(2\nu+1)(2\nu+2)}
65
[a2ca6e5]66.. note::
67    This model applies only in the mass fractal range (ie, $5/3<=m<=3$ )
68    and **does not apply** to surface fractals ( $3<m<=4$ ).
69    It also does not reproduce the rigid rod limit (m=1) because it assumes chain
70    flexibility from the outset. It may cover a portion of the semi-flexible chain
71    range ( $1<m<5/3$ ).
[23d3b41]72
[513efc5]73A low-Q expansion yields the Guinier form and a high-Q expansion yields the
74Porod form which is given by
[23d3b41]75
76.. math::
77
[513efc5]78    P(Q\rightarrow \infty) = \frac{1}{\nu U^{1/2\nu}}\Gamma\left(
79    \frac{1}{2\nu}\right) - \frac{1}{\nu U^{1/\nu}}\Gamma\left(
80    \frac{1}{\nu}\right)
[23d3b41]81
82Here $\Gamma(x) = \gamma(x,\infty)$ is the gamma function.
83
84The asymptotic limit is dominated by the first term
85
86.. math::
87
88    P(Q\rightarrow \infty) \sim \frac{1}{\nu U^{1/2\nu}}\Gamma\left(\frac{1}{2\nu}\right) =
89    \frac{m}{\left(QR_{g}\right)^m}\left[\frac{6}{(2\nu +1)(2\nu +2)} \right]^{m/2}
90    \Gamma (m/2)
91
[bf59527]92The special case when $\nu=0.5$ (or $m=1/\nu=2$ ) corresponds to Gaussian chains for
[23d3b41]93which the form factor is given by the familiar Debye function.
94
95.. math::
96
[547c6f0]97    P(Q) = \frac{2}{Q^4R_{g}^4} \left[\exp(-Q^2R_{g}^2) - 1 + Q^2R_{g}^2 \right]
[23d3b41]98
99For 2D data: The 2D scattering intensity is calculated in the same way as 1D,
100where the $q$ vector is defined as
101
102.. math::
103
104    q = \sqrt{q_x^2 + q_y^2}
105
106
107References
108----------
109
110H Benoit, *Comptes Rendus*, 245 (1957) 2244-2247
111
112B Hammouda, *SANS from Homogeneous Polymer Mixtures - A Unified Overview,
[a2ca6e5]113Advances in Polym. Sci.* 106 (1993) 87-133
114
[547c6f0]115M Hore et al, *Co-Nonsolvency of Poly(n-isopropylacrylamide) in Deuterated
[a2ca6e5]116Water/Ethanol Mixtures* 46 (2013) 7894-7901
117
118B Hammouda & M-H Kim, *The empirical core-chain model* 247 (2017) 434-440
[23d3b41]119"""
120
[2d81cfe]121import numpy as np
[2c74c11]122from numpy import inf, power, errstate
[23d3b41]123from scipy.special import gammainc, gamma
124
125name = "polymer_excl_volume"
126title = "Polymer Excluded Volume model"
[513efc5]127description = """Compute the scattering intensity from polymers with excluded
128                volume effects.
[23d3b41]129                rg:         radius of gyration
130                porod_exp:  Porod exponent
131              """
132category = "shape-independent"
133
[168052c]134# pylint: disable=bad-whitespace, line-too-long
[40a87fa]135#   ["name", "units", default, [lower, upper], "type", "description"],
136parameters = [
[404ebbd]137    ["rg",        "Ang", 60.0, [0, inf], "", "Radius of Gyration"],
138    ["porod_exp", "",     3.0, [0, inf], "", "Porod exponent"],
[40a87fa]139]
[168052c]140# pylint: enable=bad-whitespace, line-too-long
[23d3b41]141
142
[416609b]143def Iq(q, rg=60.0, porod_exp=3.0):
[23d3b41]144    """
145    :param q:         Input q-value (float or [float, float])
146    :param rg:        Radius of gyration
147    :param porod_exp: Porod exponent
148    :return:          Calculated intensity
149    """
[40a87fa]150    usub = (q*rg)**2 * (2.0/porod_exp + 1.0) * (2.0/porod_exp + 2.0)/6.0
[2c74c11]151    with errstate(divide='ignore', invalid='ignore'):
[40a87fa]152        upow = power(usub, -0.5*porod_exp)
[aa90015]153        # Note: scipy gammainc is "regularized", being gamma(s,x)/Gamma(s),
154        # so need to scale by Gamma(s) to recover gamma(s, x).
[2d81cfe]155        result = (porod_exp*upow *
156                  (gamma(0.5*porod_exp)*gammainc(0.5*porod_exp, usub) -
157                   upow*gamma(porod_exp)*gammainc(porod_exp, usub)))
[40a87fa]158    result[q <= 0] = 1.0
[23d3b41]159
[40a87fa]160    return result
[23d3b41]161
162Iq.vectorized = True  # Iq accepts an array of q values
163
[404ebbd]164def random():
[b297ba9]165    """Return a random parameter set for the model."""
[404ebbd]166    rg = 10**np.random.uniform(0, 4)
167    porod_exp = np.random.uniform(1e-3, 6)
168    scale = 10**np.random.uniform(1, 5)
169    pars = dict(
170        #background=0,
171        scale=scale,
172        rg=rg,
173        porod_exp=porod_exp,
174    )
175    return pars
176
[07a6700]177tests = [
[168052c]178    # Accuracy tests based on content in test/polyexclvol_default_igor.txt
[6dd90c1]179    [{'rg': 60, 'porod_exp': 3.0}, 0.001, 0.999801],
180    [{'rg': 60, 'porod_exp': 3.0}, 0.105363, 0.0172751],
181    [{'rg': 60, 'porod_exp': 3.0, 'background': 0.0}, 0.665075, 6.56261e-05],
[168052c]182
183    # Additional tests with larger range of parameters
[6dd90c1]184    [{'rg': 10, 'porod_exp': 4.0}, 0.1, 0.724436675809],
[168052c]185    [{'rg': 2.2, 'porod_exp': 22.0, 'background': 100.0}, 5.0, 100.0],
186    [{'rg': 1.1, 'porod_exp': 1, 'background': 10.0, 'scale': 1.25},
187     20000., 10.0000712097]
188    ]
Note: See TracBrowser for help on using the repository browser.