Changeset 7e0b281 in sasmodels for explore/bccpy.py


Ignore:
Timestamp:
Apr 17, 2017 6:34:52 PM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
64ca163
Parents:
cb038a2
Message:

adjust paracrystal equations to better match terminology in Matsuoka paper

File:
1 edited

Legend:

Unmodified
Added
Removed
  • explore/bccpy.py

    rcb038a2 r7e0b281  
    4747SLD_SOLVENT = 6.3 
    4848 
     49# Note: using Matsuoka 1990; this is different from what 
     50# is in the sasmodels/models code  (see bcc vs bcc_old). 
     51# The difference is that the sign of phi and theta seem to be 
     52# negative in the old vs. the new, yielding a pattern that is 
     53# swapped left to right and top to bottom. 
     54def sc(qa, qb, qc): 
     55    return qa, qb, qc 
     56 
     57def bcc(qa, qb, qc): 
     58    a1 = (+qa + qb + qc)/2 
     59    a2 = (-qa - qb + qc)/2 
     60    a3 = (-qa + qb - qc)/2 
     61    return a1, a2, a3 
     62 
     63def bcc_old(qa, qb, qc): 
     64    a1 = (+qa + qb - qc)/2.0 
     65    a2 = (+qa - qb + qc)/2.0 
     66    a3 = (-qa + qb + qc)/2.0 
     67    return a1, a2, a3 
     68 
     69def fcc(qa, qb, qc): 
     70    a1 = ( 0. + qb + qc)/2 
     71    a2 = (-qa + 0. + qc)/2 
     72    a3 = (-qa + qb + 0.)/2 
     73    return a1, a2, a3 
     74 
     75def fcc_old(qa, qb, qc): 
     76    a1 = ( qa + qb + 0.)/2 
     77    a2 = ( qa + 0. + qc)/2 
     78    a3 = ( 0. + qb + qc)/2 
     79    return a1, a2, a3 
     80 
     81KERNEL = bcc 
     82 
    4983def kernel(q, dnn, d_factor, theta, phi): 
    5084    """ 
     
    5690    qc = q*cos(theta) 
    5791 
    58     if 0: # sc 
    59         a1, a2, a3 = qa, qb, qc 
    60         dcos = dnn 
    61     if 1: # bcc 
    62         a1 = +qa - qc + qb 
    63         a2 = +qa + qc - qb 
    64         a3 = -qa + qc + qb 
    65         dcos = dnn/2 
    66     if 0: # fcc 
    67         a1 = qb + qa 
    68         a2 = qa + qc 
    69         a3 = qb + qc 
    70         dcos = dnn/2 
    71  
    72     arg = 0.5*square(dnn*d_factor)*(a1**2 + a2**2 + a3**2) 
    73     exp_arg = exp(-arg) 
    74     den = [((exp_arg - 2*cos(dcos*a))*exp_arg + 1.0) for a in (a1, a2, a3)] 
    75     Sq = -expm1(-2*arg)**3/np.prod(den, axis=0) 
    76     return Sq 
     92    a1, a2, a3 = KERNEL(qa, qb, qc) 
     93 
     94    # Note: paper says that different directions can have different distortion 
     95    # factors.  Easy enough to add to the code.  This would definitely break 
     96    # 8-fold symmetry. 
     97    arg = -0.5*square(dnn*d_factor)*(a1**2 + a2**2 + a3**2) 
     98    exp_arg = exp(arg) 
     99    den = [((exp_arg - 2*cos(dnn*a))*exp_arg + 1.0) for a in (a1, a2, a3)] 
     100    Zq = -expm1(2*arg)**3/np.prod(den, axis=0) 
     101    return Zq 
    77102 
    78103 
     
    85110    def integrand(theta, phi): 
    86111        evals[0] += 1 
    87         Sq = kernel(q=q, dnn=dnn, d_factor=d_factor, theta=theta, phi=phi) 
    88         return Sq*sin(theta) 
     112        Zq = kernel(q=q, dnn=dnn, d_factor=d_factor, theta=theta, phi=phi) 
     113        return Zq*sin(theta) 
    89114    ans = dblquad(integrand, 0, pi/2, lambda x: 0, lambda x: pi/2)[0]*8/(4*pi) 
    90115    print("dblquad evals =", evals[0]) 
     
    134159    Aw = w[None, :] * w[:, None] 
    135160    sin_theta = np.fmax(abs(sin(Atheta)), 1e-6) 
    136     Sq = kernel(q=q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
     161    Zq = kernel(q=q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
    137162    print("gauss %d evals ="%n, n**2) 
    138     return np.sum(Sq*Aw*sin_theta)*8/(4*pi) 
     163    return np.sum(Zq*Aw*sin_theta)*8/(4*pi) 
    139164 
    140165 
     
    148173    phi = np.linspace(0, pi/2, n) 
    149174    Atheta, Aphi = np.meshgrid(theta, phi) 
    150     Sq = kernel(q=Q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
    151     Sq *= abs(sin(Atheta)) 
     175    Zq = kernel(q=Q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
     176    Zq *= abs(sin(Atheta)) 
    152177    dx, dy = theta[1]-theta[0], phi[1]-phi[0] 
    153     print("rect", n, np.sum(Sq)*dx*dy*8/(4*pi)) 
    154     print("trapz", n, np.trapz(np.trapz(Sq, dx=dx), dx=dy)*8/(4*pi)) 
    155     print("simpson", n, simps(simps(Sq, dx=dx), dx=dy)*8/(4*pi)) 
    156     print("romb", n, romb(romb(Sq, dx=dx), dx=dy)*8/(4*pi)) 
     178    print("rect", n, np.sum(Zq)*dx*dy*8/(4*pi)) 
     179    print("trapz", n, np.trapz(np.trapz(Zq, dx=dx), dx=dy)*8/(4*pi)) 
     180    print("simpson", n, simps(simps(Zq, dx=dx), dx=dy)*8/(4*pi)) 
     181    print("romb", n, romb(romb(Zq, dx=dx), dx=dy)*8/(4*pi)) 
    157182    print("gridded %d evals ="%n, n**2) 
    158183 
     
    168193    #phi = np.linspace(0, pi/2, n) 
    169194    Atheta, Aphi = np.meshgrid(theta, phi) 
    170     Sq = kernel(q=Q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
    171     Sq *= abs(sin(Atheta)) 
    172     pylab.pcolor(degrees(theta), degrees(phi), log10(np.fmax(Sq, 1.e-6))) 
     195    Zq = kernel(q=Q, dnn=dnn, d_factor=d_factor, theta=Atheta, phi=Aphi) 
     196    Zq *= abs(sin(Atheta)) 
     197    pylab.pcolor(degrees(theta), degrees(phi), log10(np.fmax(Zq, 1.e-6))) 
    173198    pylab.axis('tight') 
    174     pylab.title("BCC S(q) for q=%g, dnn=%g d_factor=%g" % (q, dnn, d_factor)) 
     199    pylab.title("%s Z(q) for q=%g, dnn=%g d_factor=%g" 
     200                % (KERNEL.__name__, q, dnn, d_factor)) 
    175201    pylab.xlabel("theta (degrees)") 
    176202    pylab.ylabel("phi (degrees)") 
Note: See TracChangeset for help on using the changeset viewer.