source: sasmodels/sasmodels/models/hardsphere.py @ d529d93

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since d529d93 was d529d93, checked in by richardh, 8 years ago

updated docs for several S(Q)

  • Property mode set to 100644
File size: 6.5 KB
Line 
1# Note: model title and parameter table are inserted automatically
2r"""Calculate the interparticle structure factor for monodisperse
3spherical particles interacting through hard sphere (excluded volume)
4interactions.
5May be a reasonable approximation for other shapes of particles that
6freely rotate, and for moderately polydisperse systems. Though strictly
7the maths needs to be modified (no \Beta(Q) correction yet in sasview).
8
9radius_effective is the effective hard sphere radius.
10volfraction is the volume fraction occupied by the spheres.
11
12In sasview the effective radius may be calculated from the parameters
13used in the form factor $P(q)$ that this $S(q)$ is combined with.
14
15For numerical stability the computation uses a Taylor series expansion
16at very small $qR$, there may be a very minor glitch at the transition point
17in some circumstances.
18
19The S(Q) uses the Percus-Yevick closure where the interparticle
20potential is
21
22.. math::
23
24    U(r) = \begin{cases}
25    \infty & r < 2R \\
26    0 & r \geq 2R
27    \end{cases}
28
29where $r$ is the distance from the center of the sphere of a radius $R$.
30
31For a 2D plot, the wave transfer is defined as
32
33.. math::
34
35    q = \sqrt{q_x^2 + q_y^2}
36
37
38.. figure:: img/hardSphere_1d.jpg
39
40    1D plot using the default values (in linear scale).
41
42References
43----------
44
45J K Percus, J Yevick, *J. Phys. Rev.*, 110, (1958) 1
46"""
47
48from numpy import inf
49
50name = "hardsphere"
51title = "Hard sphere structure factor, with Percus-Yevick closure"
52description = """\
53    [Hard sphere structure factor, with Percus-Yevick closure]
54        Interparticle S(Q) for random, non-interacting spheres.
55    May be a reasonable approximation for other shapes of
56    particles that freely rotate, and for moderately polydisperse
57        systems. Though strictly the maths needs to be modified -
58    which sasview does not do yet.
59    radius_effective is the hard sphere radius
60    volfraction is the volume fraction occupied by the spheres.
61"""
62category = "structure-factor"
63structure_factor = True
64
65#             ["name", "units", default, [lower, upper], "type","description"],
66parameters = [["radius_effective", "Ang", 50.0, [0, inf], "volume",
67               "effective radius of hard sphere"],
68              ["volfraction", "", 0.2, [0, 0.74], "",
69               "volume fraction of hard spheres"],
70             ]
71
72# No volume normalization despite having a volume parameter
73# This should perhaps be volume normalized?
74form_volume = """
75    return 1.0;
76    """
77
78Iq = """
79      double D,A,B,G,X,X2,X4,S,C,FF,HARDSPH;
80
81      if(fabs(radius_effective) < 1.E-12) {
82               HARDSPH=1.0;
83               return(HARDSPH);
84      }
85      // removing use of pow(xxx,2) and rearranging the calcs of A, B & G cut ~40% off execution time ( 0.5 to 0.3 msec)
86      X = 1.0/( 1.0 -volfraction);
87      D= X*X;
88      A= (1.+2.*volfraction)*D;
89      A *=A;
90      X=fabs(q*radius_effective*2.0);
91
92      if(X < 5.E-06) {
93                 HARDSPH=1./A;
94                 return(HARDSPH);
95      }
96      X2 =X*X;
97      B = (1.0 +0.5*volfraction)*D;
98      B *= B;
99      B *= -6.*volfraction;
100      G=0.5*volfraction*A;
101
102      if(X < 0.2) {
103      // RKH Feb 2016, use Taylor series expansion for small X, IT IS VERY PICKY ABOUT THE X CUT OFF VALUE, ought to be lower in double.
104      // else no obvious way to rearrange the equations to avoid needing a very high number of significant figures.
105      // Series expansion found using Mathematica software. Numerical test in .xls showed terms to X^2 are sufficient
106      // for 5 or 6 significant figures, but I put the X^4 one in anyway
107            //FF = 8*A +6*B + 4*G - (0.8*A +2.0*B/3.0 +0.5*G)*X2 +(A/35. +B/40. +G/50.)*X4;
108            // refactoring the polynomial makes it very slightly faster (0.5 not 0.6 msec)
109            //FF = 8*A +6*B + 4*G + ( -0.8*A -2.0*B/3.0 -0.5*G +(A/35. +B/40. +G/50.)*X2)*X2;
110
111            FF = 8.0*A +6.0*B + 4.0*G + ( -0.8*A -B/1.5 -0.5*G +(A/35. +0.0125*B +0.02*G)*X2)*X2;
112
113            // combining the terms makes things worse at smallest Q in single precision
114            //FF = (8-0.8*X2)*A +(3.0-X2/3.)*2*B + (4+0.5*X2)*G +(A/35. +B/40. +G/50.)*X4;
115            // note that G = -volfraction*A/2, combining this makes no further difference at smallest Q
116            //FF = (8 +2.*volfraction + ( volfraction/4. -0.8 +(volfraction/100. -1./35.)*X2 )*X2 )*A  + (3.0 -X2/3. +X4/40.)*2.*B;
117            HARDSPH= 1./(1. + volfraction*FF );
118            return(HARDSPH);
119      }
120      X4=X2*X2;
121      SINCOS(X,S,C);
122
123// RKH Feb 2016, use version FISH code as is better than original sasview one at small Q in single precision, and more than twice as fast in double.
124      //FF=A*(S-X*C)/X + B*(2.*X*S -(X2-2.)*C -2.)/X2 + G*( (4.*X2*X -24.*X)*S -(X4 -12.*X2 +24.)*C +24. )/X4;
125      // refactoring the polynomial here & above makes it slightly faster
126
127      FF=  (( G*( (4.*X2 -24.)*X*S -(X4 -12.*X2 +24.)*C +24. )/X2 + B*(2.*X*S -(X2-2.)*C -2.) )/X + A*(S-X*C))/X ;
128      HARDSPH= 1./(1. + 24.*volfraction*FF/X2 );
129
130      // changing /X and /X2 to *MX1 and *MX2, no significantg difference?
131      //MX=1.0/X;
132      //MX2=MX*MX;
133      //FF=  (( G*( (4.*X2 -24.)*X*S -(X4 -12.*X2 +24.)*C +24. )*MX2 + B*(2.*X*S -(X2-2.)*C -2.) )*MX + A*(S-X*C)) ;
134      //HARDSPH= 1./(1. + 24.*volfraction*FF*MX2*MX );
135
136// grouping the terms, was about same as sasmodels for single precision issues
137//     FF=A*(S/X-C) + B*(2.*S/X - C +2.0*(C-1.0)/X2) + G*( (4./X -24./X3)*S -(1.0 -12./X2 +24./X4)*C +24./X4 );
138//     HARDSPH= 1./(1. + 24.*volfraction*FF/X2 );
139// remove 1/X2 from final line, take more powers of X inside the brackets, stil bad
140//      FF=A*(S/X3-C/X2) + B*(2.*S/X3 - C/X2 +2.0*(C-1.0)/X4) + G*( (4./X -24./X3)*S -(1.0 -12./X2 +24./X4)*C +24./X4 )/X2;
141//      HARDSPH= 1./(1. + 24.*volfraction*FF );
142      return(HARDSPH);
143   """
144
145Iqxy = """
146    // never called since no orientation or magnetic parameters.
147    return Iq(sqrt(qx*qx+qy*qy), IQ_PARAMETERS);
148    """
149
150# ER defaults to 0.0
151# VR defaults to 1.0
152
153demo = dict(radius_effective=200, volfraction=0.2, radius_effective_pd=0.1, radius_effective_pd_n=40)
154oldname = 'HardsphereStructure'
155oldpars = dict(radius_effective="effect_radius",radius_effective_pd="effect_radius_pd",radius_effective_pd_n="effect_radius_pd_n")
156# Q=0.001 is in the Taylor series, low Q part, so add Q=0.1, assuming double precision sasview is correct
157tests = [
158        [ {'scale': 1.0, 'background' : 0.0, 'radius_effective' : 50.0, 'volfraction' : 0.2,
159           'radius_effective_pd' : 0}, [0.001,0.1], [0.209128,0.930587]]
160        ]
161# ADDED by: RKH  ON: 16Mar2016  using equations from FISH as better than orig sasview, see notes above. Added Taylor expansions at small Q,
Note: See TracBrowser for help on using the repository browser.