Changes in / [b3f4831:c6084f1] in sasmodels
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
explore/realspace.py
r5778279 r362a66f 9 9 import numpy as np 10 10 from numpy import pi, radians, sin, cos, sqrt 11 from numpy.random import poisson, uniform, randn, rand , randint11 from numpy.random import poisson, uniform, randn, rand 12 12 from numpy.polynomial.legendre import leggauss 13 13 from scipy.integrate import simps … … 78 78 79 79 80 I3 = np.matrix([[1., 0, 0], [0, 1, 0], [0, 0, 1]])81 82 80 class Shape: 83 rotation = I381 rotation = np.matrix([[1., 0, 0], [0, 1, 0], [0, 0, 1]]) 84 82 center = np.array([0., 0., 0.])[:, None] 85 83 r_max = None 86 lattice_size = np.array((1, 1, 1))87 lattice_spacing = np.array((1., 1., 1.))88 lattice_distortion = 0.089 lattice_rotation = 0.090 lattice_type = ""91 84 92 85 def volume(self): … … 103 96 104 97 def rotate(self, theta, phi, psi): 105 if theta != 0. or phi != 0. or psi != 0.: 106 self.rotation = rotation(theta, phi, psi) * self.rotation 98 self.rotation = rotation(theta, phi, psi) * self.rotation 107 99 return self 108 100 … … 111 103 return self 112 104 113 def lattice(self, size=(1, 1, 1), spacing=(2, 2, 2), type="sc",114 distortion=0.0, rotation=0.0):115 self.lattice_size = np.asarray(size, 'i')116 self.lattice_spacing = np.asarray(spacing, 'd')117 self.lattice_type = type118 self.lattice_distortion = distortion119 self.lattice_rotation = rotation120 121 105 def _adjust(self, points): 122 if self.rotation is I3: 123 points = points.T + self.center 124 else: 125 points = np.asarray(self.rotation * np.matrix(points.T)) + self.center 126 if self.lattice_type: 127 points = self._apply_lattice(points) 106 points = np.asarray(self.rotation * np.matrix(points.T)) + self.center 128 107 return points.T 129 108 130 def r_bins(self, q, over_sampling=10, r_step=0.): 131 if self.lattice_type: 132 r_max = np.sqrt(np.sum(self.lattice_size*self.lattice_spacing*self.dims)**2)/2 133 else: 134 r_max = self.r_max 135 #r_max = min(2 * pi / q[0], r_max) 109 def r_bins(self, q, over_sampling=1, r_step=0.): 110 r_max = min(2 * pi / q[0], self.r_max) 136 111 if r_step == 0.: 137 112 r_step = 2 * pi / q[-1] / over_sampling 138 113 #r_step = 0.01 139 114 return np.arange(r_step, r_max, r_step) 140 141 def _apply_lattice(self, points):142 """Spread points to different lattice positions"""143 size = self.lattice_size144 spacing = self.lattice_spacing145 shuffle = self.lattice_distortion146 rotate = self.lattice_rotation147 lattice = self.lattice_type148 149 if rotate != 0:150 # To vectorize the rotations we will need to unwrap the matrix multiply151 raise NotImplementedError("don't handle rotations yet")152 153 # Determine the number of lattice points in the lattice154 shapes_per_cell = 2 if lattice == "bcc" else 4 if lattice == "fcc" else 1155 number_of_lattice_points = np.prod(size) * shapes_per_cell156 157 # For each point in the original shape, figure out which lattice point158 # to translate it to. This is both cell index (i*ny*nz + j*nz + k) as159 # well as the point in the cell (corner, body center or face center).160 nsamples = points.shape[1]161 lattice_point = randint(number_of_lattice_points, size=nsamples)162 163 # Translate the cell index into the i,j,k coordinates of the senter164 cell_index = lattice_point // shapes_per_cell165 center = np.vstack((cell_index//(size[1]*size[2]),166 (cell_index%(size[1]*size[2]))//size[2],167 cell_index%size[2]))168 center = np.asarray(center, dtype='d')169 if lattice == "bcc":170 center[:, lattice_point % shapes_per_cell == 1] += [[0.5], [0.5], [0.5]]171 elif lattice == "fcc":172 center[:, lattice_point % shapes_per_cell == 1] += [[0.0], [0.5], [0.5]]173 center[:, lattice_point % shapes_per_cell == 2] += [[0.5], [0.0], [0.5]]174 center[:, lattice_point % shapes_per_cell == 3] += [[0.5], [0.5], [0.0]]175 176 # Each lattice point has its own displacement from the ideal position.177 # Not checking that shapes do not overlap if displacement is too large.178 offset = shuffle*(randn(3, number_of_lattice_points) if shuffle < 0.3179 else rand(3, number_of_lattice_points))180 center += offset[:, cell_index]181 182 # Each lattice point has its own rotation. Rotate the point prior to183 # applying any displacement.184 # rotation = rotate*(randn(size=(shapes, 3)) if shuffle < 30 else rand(size=(nsamples, 3)))185 # for k in shapes: points[k] = rotation[k]*points[k]186 points += center*(np.array([spacing])*np.array(self.dims)).T187 return points188 115 189 116 class Composite(Shape): … … 742 669 Iq = 100 * np.ones_like(qx) 743 670 data = Data2D(x=qx, y=qy, z=Iq, dx=None, dy=None, dz=np.sqrt(Iq)) 744 data.x_bins = qx[0, 745 data.y_bins = qy[:, 671 data.x_bins = qx[0,:] 672 data.y_bins = qy[:,0] 746 673 data.filename = "fake data" 747 674 … … 768 695 return shape, fn, fn_xy 769 696 770 DEFAULT_SPHERE_RADIUS = 125 771 DEFAULT_SPHERE_CONTRAST = 2 772 def build_sphere(radius=DEFAULT_SPHERE_RADIUS, rho=DEFAULT_SPHERE_CONTRAST): 697 def build_sphere(radius=125, rho=2): 773 698 shape = TriaxialEllipsoid(radius, radius, radius, rho) 774 699 fn = lambda q: sphere_Iq(q, radius)*rho**2 … … 826 751 return shape, fn, fn_xy 827 752 828 def build_ sc_lattice(shape, nx=1, ny=1, nz=1, dx=2, dy=2, dz=2,829 753 def build_cubic_lattice(shape, nx=1, ny=1, nz=1, dx=2, dy=2, dz=2, 754 shuffle=0, rotate=0): 830 755 a, b, c = shape.dims 831 corners= [copy(shape)756 shapes = [copy(shape) 832 757 .shift((ix+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a, 833 758 (iy+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b, … … 837 762 for iy in range(ny) 838 763 for iz in range(nz)] 839 lattice = Composite( corners)764 lattice = Composite(shapes) 840 765 return lattice 841 766 842 def build_bcc_lattice(shape, nx=1, ny=1, nz=1, dx=2, dy=2, dz=2,843 shuffle=0, rotate=0):844 a, b, c = shape.dims845 corners = [copy(shape)846 .shift((ix+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,847 (iy+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,848 (iz+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)849 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))850 for ix in range(nx)851 for iy in range(ny)852 for iz in range(nz)]853 centers = [copy(shape)854 .shift((ix+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,855 (iy+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,856 (iz+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)857 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))858 for ix in range(nx)859 for iy in range(ny)860 for iz in range(nz)]861 lattice = Composite(corners + centers)862 return lattice863 864 def build_fcc_lattice(shape, nx=1, ny=1, nz=1, dx=2, dy=2, dz=2,865 shuffle=0, rotate=0):866 a, b, c = shape.dims867 corners = [copy(shape)868 .shift((ix+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,869 (iy+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,870 (iz+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)871 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))872 for ix in range(nx)873 for iy in range(ny)874 for iz in range(nz)]875 faces_a = [copy(shape)876 .shift((ix+0.0+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,877 (iy+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,878 (iz+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)879 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))880 for ix in range(nx)881 for iy in range(ny)882 for iz in range(nz)]883 faces_b = [copy(shape)884 .shift((ix+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,885 (iy+0.0+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,886 (iz+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)887 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))888 for ix in range(nx)889 for iy in range(ny)890 for iz in range(nz)]891 faces_c = [copy(shape)892 .shift((ix+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dx*a,893 (iy+0.5+(randn() if shuffle < 0.3 else rand())*shuffle)*dy*b,894 (iz+0.0+(randn() if shuffle < 0.3 else rand())*shuffle)*dz*c)895 .rotate(*((randn(3) if rotate < 30 else rand(3))*rotate))896 for ix in range(nx)897 for iy in range(ny)898 for iz in range(nz)]899 lattice = Composite(corners + faces_a + faces_b + faces_c)900 return lattice901 767 902 768 SHAPE_FUNCTIONS = OrderedDict([ … … 909 775 ]) 910 776 SHAPES = list(SHAPE_FUNCTIONS.keys()) 911 LATTICE_FUNCTIONS = OrderedDict([912 ("sc", build_sc_lattice),913 ("bcc", build_bcc_lattice),914 ("fcc", build_fcc_lattice),915 ])916 LATTICE_TYPES = list(LATTICE_FUNCTIONS.keys())917 777 918 778 def check_shape(title, shape, fn=None, show_points=False, … … 923 783 r = shape.r_bins(q, r_step=r_step) 924 784 sampling_density = samples / shape.volume 925 print("sampling points")926 785 rho, points = shape.sample(sampling_density) 927 print("calculating Pr")928 786 t0 = time.time() 929 787 Pr = calc_Pr(r, rho-rho_solvent, points) … … 934 792 import pylab 935 793 if show_points: 936 plot_points(rho, points); pylab.figure()794 plot_points(rho, points); pylab.figure() 937 795 plot_calc(r, Pr, q, Iq, theory=theory, title=title) 938 796 pylab.gcf().canvas.set_window_title(title) … … 948 806 Qx, Qy = np.meshgrid(qx, qy) 949 807 sampling_density = samples / shape.volume 950 print("sampling points")951 808 t0 = time.time() 952 809 rho, points = shape.sample(sampling_density) … … 987 844 help='lattice size') 988 845 parser.add_argument('-z', '--spacing', type=str, default='2,2,2', 989 help='lattice spacing (relative to shape)') 990 parser.add_argument('-t', '--type', choices=LATTICE_TYPES, 991 default=LATTICE_TYPES[0], 992 help='lattice type') 846 help='lattice spacing') 993 847 parser.add_argument('-r', '--rotate', type=float, default=0., 994 848 help="rotation relative to lattice, gaussian < 30 degrees, uniform otherwise") … … 1004 858 nx, ny, nz = [int(v) for v in opts.lattice.split(',')] 1005 859 dx, dy, dz = [float(v) for v in opts.spacing.split(',')] 1006 distortion, rotation= opts.shuffle, opts.rotate860 shuffle, rotate = opts.shuffle, opts.rotate 1007 861 shape, fn, fn_xy = SHAPE_FUNCTIONS[opts.shape](**pars) 1008 view = tuple(float(v) for v in opts.view.split(',')) 1009 # If comparing a sphere in a cubic lattice, compare against the 1010 # corresponding paracrystalline model. 1011 if opts.shape == "sphere" and dx == dy == dz and nx*ny*nz > 1: 1012 radius = pars.get('radius', DEFAULT_SPHERE_RADIUS) 1013 model_name = opts.type + "_paracrystal" 1014 model_pars = { 1015 "scale": 1., 1016 "background": 0., 1017 "lattice_spacing": 2*radius*dx, 1018 "lattice_distortion": distortion, 1019 "radius": radius, 1020 "sld": pars.get('rho', DEFAULT_SPHERE_CONTRAST), 1021 "sld_solvent": 0., 1022 "theta": view[0], 1023 "phi": view[1], 1024 "psi": view[2], 1025 } 1026 fn, fn_xy = wrap_sasmodel(model_name, **model_pars) 1027 if nx*ny*nz > 1: 1028 if rotation != 0: 1029 print("building %s lattice"%opts.type) 1030 build_lattice = LATTICE_FUNCTIONS[opts.type] 1031 shape = build_lattice(shape, nx, ny, nz, dx, dy, dz, 1032 distortion, rotation) 1033 else: 1034 shape.lattice(size=(nx, ny, nz), spacing=(dx, dy, dz), 1035 type=opts.type, 1036 rotation=rotation, distortion=distortion) 1037 862 if nx > 1 or ny > 1 or nz > 1: 863 shape = build_cubic_lattice(shape, nx, ny, nz, dx, dy, dz, shuffle, rotate) 1038 864 title = "%s(%s)" % (opts.shape, " ".join(opts.pars)) 1039 865 if opts.dim == 1: … … 1041 867 mesh=opts.mesh, qmax=opts.qmax, samples=opts.samples) 1042 868 else: 869 view = tuple(float(v) for v in opts.view.split(',')) 1043 870 check_shape_2d(title, shape, fn_xy, view=view, show_points=opts.plot, 1044 871 mesh=opts.mesh, qmax=opts.qmax, samples=opts.samples) -
sasmodels/convert.py
r610ef23 r610ef23 166 166 oldpars = _hand_convert_3_1_2_to_4_1(name, oldpars) 167 167 if version < (4, 2, 0): 168 oldpars = _hand_convert_4_1_to_4_2(name, oldpars)169 168 oldpars = _rename_magnetic_pars(oldpars) 170 return oldpars171 172 def _hand_convert_4_1_to_4_2(name, oldpars):173 if name in ('bcc_paracrystal', 'fcc_paracrystal', 'sc_paracrystal'):174 oldpars['lattice_spacing'] = oldpars.pop('dnn')175 oldpars['lattice_distortion'] = oldpars.pop('d_factor')176 169 return oldpars 177 170 -
sasmodels/models/bcc_paracrystal.c
r642046e r108e70e 1 1 static double 2 bcc_Zq(double qa, double qb, double qc, double lattice_spacing, double lattice_distortion)2 bcc_Zq(double qa, double qb, double qc, double dnn, double d_factor) 3 3 { 4 4 // Equations from Matsuoka 26-27-28, multiplied by |q| … … 17 17 // => exp(a)^2 - 2 cos(d ak) exp(a) + 1) 18 18 // => (exp(a) - 2 cos(d ak)) * exp(a) + 1 19 const double arg = -0.5*square( lattice_spacing*lattice_distortion)*(a1*a1 + a2*a2 + a3*a3);19 const double arg = -0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3); 20 20 const double exp_arg = exp(arg); 21 21 const double Zq = -cube(expm1(2.0*arg)) 22 / ( ((exp_arg - 2.0*cos( lattice_spacing*a1))*exp_arg + 1.0)23 * ((exp_arg - 2.0*cos( lattice_spacing*a2))*exp_arg + 1.0)24 * ((exp_arg - 2.0*cos( lattice_spacing*a3))*exp_arg + 1.0));22 / ( ((exp_arg - 2.0*cos(dnn*a1))*exp_arg + 1.0) 23 * ((exp_arg - 2.0*cos(dnn*a2))*exp_arg + 1.0) 24 * ((exp_arg - 2.0*cos(dnn*a3))*exp_arg + 1.0)); 25 25 26 26 #elif 0 … … 36 36 // = tanh(-a) / [1 - cos(d a_k)/cosh(-a)] 37 37 // 38 const double arg = 0.5*square( lattice_spacing*lattice_distortion)*(a1*a1 + a2*a2 + a3*a3);38 const double arg = 0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3); 39 39 const double sinh_qd = sinh(arg); 40 40 const double cosh_qd = cosh(arg); 41 const double Zq = sinh_qd/(cosh_qd - cos( lattice_spacing*a1))42 * sinh_qd/(cosh_qd - cos( lattice_spacing*a2))43 * sinh_qd/(cosh_qd - cos( lattice_spacing*a3));41 const double Zq = sinh_qd/(cosh_qd - cos(dnn*a1)) 42 * sinh_qd/(cosh_qd - cos(dnn*a2)) 43 * sinh_qd/(cosh_qd - cos(dnn*a3)); 44 44 #else 45 const double arg = 0.5*square( lattice_spacing*lattice_distortion)*(a1*a1 + a2*a2 + a3*a3);45 const double arg = 0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3); 46 46 const double tanh_qd = tanh(arg); 47 47 const double cosh_qd = cosh(arg); 48 const double Zq = tanh_qd/(1.0 - cos( lattice_spacing*a1)/cosh_qd)49 * tanh_qd/(1.0 - cos( lattice_spacing*a2)/cosh_qd)50 * tanh_qd/(1.0 - cos( lattice_spacing*a3)/cosh_qd);48 const double Zq = tanh_qd/(1.0 - cos(dnn*a1)/cosh_qd) 49 * tanh_qd/(1.0 - cos(dnn*a2)/cosh_qd) 50 * tanh_qd/(1.0 - cos(dnn*a3)/cosh_qd); 51 51 #endif 52 52 … … 57 57 // occupied volume fraction calculated from lattice symmetry and sphere radius 58 58 static double 59 bcc_volume_fraction(double radius, double lattice_spacing)59 bcc_volume_fraction(double radius, double dnn) 60 60 { 61 return 2.0*sphere_volume( radius/lattice_spacing);61 return 2.0*sphere_volume(sqrt(0.75)*radius/dnn); 62 62 } 63 63 … … 69 69 70 70 71 static double Iq(double q, double lattice_spacing,72 double lattice_distortion, double radius,71 static double Iq(double q, double dnn, 72 double d_factor, double radius, 73 73 double sld, double solvent_sld) 74 74 { … … 94 94 const double qa = qab*cos_phi; 95 95 const double qb = qab*sin_phi; 96 const double form = bcc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);96 const double form = bcc_Zq(qa, qb, qc, dnn, d_factor); 97 97 inner_sum += GAUSS_W[j] * form; 98 98 } … … 103 103 const double Zq = outer_sum/(4.0*M_PI); 104 104 const double Pq = sphere_form(q, radius, sld, solvent_sld); 105 return bcc_volume_fraction(radius, lattice_spacing) * Pq * Zq;105 return bcc_volume_fraction(radius, dnn) * Pq * Zq; 106 106 } 107 107 108 108 109 109 static double Iqabc(double qa, double qb, double qc, 110 double lattice_spacing, double lattice_distortion, double radius,110 double dnn, double d_factor, double radius, 111 111 double sld, double solvent_sld) 112 112 { 113 113 const double q = sqrt(qa*qa + qb*qb + qc*qc); 114 const double Zq = bcc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);114 const double Zq = bcc_Zq(qa, qb, qc, dnn, d_factor); 115 115 const double Pq = sphere_form(q, radius, sld, solvent_sld); 116 return bcc_volume_fraction(radius, lattice_spacing) * Pq * Zq;116 return bcc_volume_fraction(radius, dnn) * Pq * Zq; 117 117 } -
sasmodels/models/bcc_paracrystal.py
rda7b26b rda7b26b 34 34 .. math:: 35 35 36 V_\text{lattice} = \frac{ 8\pi}{3} \frac{R^3}{\left(2D/\sqrt{3}\right)^3}36 V_\text{lattice} = \frac{16\pi}{3} \frac{R^3}{\left(D\sqrt{2}\right)^3} 37 37 38 38 … … 104 104 105 105 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 106 * **Last Modified by:** Paul Butler **Date:** September 16, 2018107 * **Last Reviewed by:** Paul Butler **Date:** September 16, 2018106 * **Last Modified by:** Paul Butler **Date:** September 29, 2016 107 * **Last Reviewed by:** Richard Heenan **Date:** March 21, 2016 108 108 """ 109 109 … … 127 127 # pylint: disable=bad-whitespace, line-too-long 128 128 # ["name", "units", default, [lower, upper], "type","description" ], 129 parameters = [[" lattice_spacing", "Ang", 220, [-inf, inf], "", "Lattice spacing"],130 [" lattice_distortion", "", 0.06, [-inf, inf], "", "Paracrystal distortion factor"],129 parameters = [["dnn", "Ang", 220, [-inf, inf], "", "Nearest neighbour distance"], 130 ["d_factor", "", 0.06, [-inf, inf], "", "Paracrystal distortion factor"], 131 131 ["radius", "Ang", 40, [0, inf], "volume", "Particle radius"], 132 132 ["sld", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Particle scattering length density"], … … 149 149 # in this range 'cuz its easy. 150 150 radius = 10**np.random.uniform(1.3, 4) 151 lattice_distortion= 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7152 lattice_spacing_fraction = np.random.beta(a=10, b=1)153 lattice_spacing = radius*4/np.sqrt(3)/lattice_spacing_fraction151 d_factor = 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7 152 dnn_fraction = np.random.beta(a=10, b=1) 153 dnn = radius*4/np.sqrt(3)/dnn_fraction 154 154 pars = dict( 155 155 #sld=1, sld_solvent=0, scale=1, background=1e-32, 156 lattice_spacing=lattice_spacing,157 lattice_distortion=lattice_distortion,156 dnn=dnn, 157 d_factor=d_factor, 158 158 radius=radius, 159 159 ) -
sasmodels/models/fcc_paracrystal.c
r642046e r108e70e 1 1 static double 2 fcc_Zq(double qa, double qb, double qc, double lattice_spacing, double lattice_distortion)2 fcc_Zq(double qa, double qb, double qc, double dnn, double d_factor) 3 3 { 4 4 // Equations from Matsuoka 17-18-19, multiplied by |q| … … 16 16 // => exp(a)^2 - 2 cos(d ak) exp(a) + 1) 17 17 // => (exp(a) - 2 cos(d ak)) * exp(a) + 1 18 const double arg = -0.5*square( lattice_spacing*lattice_distortion)*(a1*a1 + a2*a2 + a3*a3);18 const double arg = -0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3); 19 19 const double exp_arg = exp(arg); 20 20 const double Zq = -cube(expm1(2.0*arg)) 21 / ( ((exp_arg - 2.0*cos( lattice_spacing*a1))*exp_arg + 1.0)22 * ((exp_arg - 2.0*cos( lattice_spacing*a2))*exp_arg + 1.0)23 * ((exp_arg - 2.0*cos( lattice_spacing*a3))*exp_arg + 1.0));21 / ( ((exp_arg - 2.0*cos(dnn*a1))*exp_arg + 1.0) 22 * ((exp_arg - 2.0*cos(dnn*a2))*exp_arg + 1.0) 23 * ((exp_arg - 2.0*cos(dnn*a3))*exp_arg + 1.0)); 24 24 25 25 return Zq; … … 29 29 // occupied volume fraction calculated from lattice symmetry and sphere radius 30 30 static double 31 fcc_volume_fraction(double radius, double lattice_spacing)31 fcc_volume_fraction(double radius, double dnn) 32 32 { 33 return 4.0*sphere_volume( radius/lattice_spacing);33 return 4.0*sphere_volume(M_SQRT1_2*radius/dnn); 34 34 } 35 35 … … 41 41 42 42 43 static double Iq(double q, double lattice_spacing,44 double lattice_distortion, double radius,43 static double Iq(double q, double dnn, 44 double d_factor, double radius, 45 45 double sld, double solvent_sld) 46 46 { … … 66 66 const double qa = qab*cos_phi; 67 67 const double qb = qab*sin_phi; 68 const double form = fcc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);68 const double form = fcc_Zq(qa, qb, qc, dnn, d_factor); 69 69 inner_sum += GAUSS_W[j] * form; 70 70 } … … 76 76 const double Pq = sphere_form(q, radius, sld, solvent_sld); 77 77 78 return fcc_volume_fraction(radius, lattice_spacing) * Pq * Zq;78 return fcc_volume_fraction(radius, dnn) * Pq * Zq; 79 79 } 80 80 81 81 82 82 static double Iqabc(double qa, double qb, double qc, 83 double lattice_spacing, double lattice_distortion, double radius,83 double dnn, double d_factor, double radius, 84 84 double sld, double solvent_sld) 85 85 { 86 86 const double q = sqrt(qa*qa + qb*qb + qc*qc); 87 87 const double Pq = sphere_form(q, radius, sld, solvent_sld); 88 const double Zq = fcc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);89 return fcc_volume_fraction(radius, lattice_spacing) * Pq * Zq;88 const double Zq = fcc_Zq(qa, qb, qc, dnn, d_factor); 89 return fcc_volume_fraction(radius, dnn) * Pq * Zq; 90 90 } -
sasmodels/models/fcc_paracrystal.py
rda7b26b rda7b26b 3 3 #note - calculation requires double precision 4 4 r""" 5 .. warning:: This model and this model description are under review following 6 concerns raised by SasView users. If you need to use this model, 7 please email help@sasview.org for the latest situation. *The 5 .. warning:: This model and this model description are under review following 6 concerns raised by SasView users. If you need to use this model, 7 please email help@sasview.org for the latest situation. *The 8 8 SasView Developers. September 2018.* 9 9 … … 100 100 101 101 Authorship and Verification 102 --------------------------- -102 --------------------------- 103 103 104 104 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 105 * **Last Modified by:** Paul Butler **Date:** September 16, 2018106 * **Last Reviewed by:** Paul Butler **Date:** September 16, 2018105 * **Last Modified by:** Paul Butler **Date:** September 29, 2016 106 * **Last Reviewed by:** Richard Heenan **Date:** March 21, 2016 107 107 """ 108 108 … … 123 123 # pylint: disable=bad-whitespace, line-too-long 124 124 # ["name", "units", default, [lower, upper], "type","description"], 125 parameters = [[" lattice_spacing", "Ang", 220, [-inf, inf], "", "Lattice spacing"],126 [" lattice_distortion", "", 0.06, [-inf, inf], "", "Paracrystal distortion factor"],125 parameters = [["dnn", "Ang", 220, [-inf, inf], "", "Nearest neighbour distance"], 126 ["d_factor", "", 0.06, [-inf, inf], "", "Paracrystal distortion factor"], 127 127 ["radius", "Ang", 40, [0, inf], "volume", "Particle radius"], 128 128 ["sld", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Particle scattering length density"], … … 139 139 # copied from bcc_paracrystal 140 140 radius = 10**np.random.uniform(1.3, 4) 141 lattice_distortion= 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7142 lattice_spacing_fraction = np.random.beta(a=10, b=1)143 lattice_spacing = radius*4/np.sqrt(2)/lattice_spacing_fraction141 d_factor = 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7 142 dnn_fraction = np.random.beta(a=10, b=1) 143 dnn = radius*4/np.sqrt(2)/dnn_fraction 144 144 pars = dict( 145 145 #sld=1, sld_solvent=0, scale=1, background=1e-32, 146 latice_spacing=lattice_spacing,147 lattice_distortion=d_factor,146 dnn=dnn, 147 d_factor=d_factor, 148 148 radius=radius, 149 149 ) -
sasmodels/models/sc_paracrystal.c
r6530963 r108e70e 1 1 static double 2 sc_Zq(double qa, double qb, double qc, double lattice_spacing, double lattice_distortion)2 sc_Zq(double qa, double qb, double qc, double dnn, double d_factor) 3 3 { 4 4 // Equations from Matsuoka 9-10-11, multiplied by |q| … … 16 16 // => exp(a)^2 - 2 cos(d ak) exp(a) + 1) 17 17 // => (exp(a) - 2 cos(d ak)) * exp(a) + 1 18 const double arg = -0.5*square( lattice_spacing*lattice_distortion)*(a1*a1 + a2*a2 + a3*a3);18 const double arg = -0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3); 19 19 const double exp_arg = exp(arg); 20 20 const double Zq = -cube(expm1(2.0*arg)) 21 / ( ((exp_arg - 2.0*cos( lattice_spacing*a1))*exp_arg + 1.0)22 * ((exp_arg - 2.0*cos( lattice_spacing*a2))*exp_arg + 1.0)23 * ((exp_arg - 2.0*cos( lattice_spacing*a3))*exp_arg + 1.0));21 / ( ((exp_arg - 2.0*cos(dnn*a1))*exp_arg + 1.0) 22 * ((exp_arg - 2.0*cos(dnn*a2))*exp_arg + 1.0) 23 * ((exp_arg - 2.0*cos(dnn*a3))*exp_arg + 1.0)); 24 24 25 25 return Zq; … … 28 28 // occupied volume fraction calculated from lattice symmetry and sphere radius 29 29 static double 30 sc_volume_fraction(double radius, double lattice_spacing)30 sc_volume_fraction(double radius, double dnn) 31 31 { 32 return sphere_volume(radius/ lattice_spacing);32 return sphere_volume(radius/dnn); 33 33 } 34 34 … … 41 41 42 42 static double 43 Iq(double q, double lattice_spacing,44 double lattice_distortion, double radius,43 Iq(double q, double dnn, 44 double d_factor, double radius, 45 45 double sld, double solvent_sld) 46 46 { … … 67 67 const double qa = qab*cos_phi; 68 68 const double qb = qab*sin_phi; 69 const double form = sc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);69 const double form = sc_Zq(qa, qb, qc, dnn, d_factor); 70 70 inner_sum += GAUSS_W[j] * form; 71 71 } … … 77 77 const double Pq = sphere_form(q, radius, sld, solvent_sld); 78 78 79 return sc_volume_fraction(radius, lattice_spacing) * Pq * Zq;79 return sc_volume_fraction(radius, dnn) * Pq * Zq; 80 80 } 81 81 … … 83 83 static double 84 84 Iqabc(double qa, double qb, double qc, 85 double lattice_spacing, double lattice_distortion, double radius,85 double dnn, double d_factor, double radius, 86 86 double sld, double solvent_sld) 87 87 { 88 88 const double q = sqrt(qa*qa + qb*qb + qc*qc); 89 89 const double Pq = sphere_form(q, radius, sld, solvent_sld); 90 const double Zq = sc_Zq(qa, qb, qc, lattice_spacing, lattice_distortion);91 return sc_volume_fraction(radius, lattice_spacing) * Pq * Zq;90 const double Zq = sc_Zq(qa, qb, qc, dnn, d_factor); 91 return sc_volume_fraction(radius, dnn) * Pq * Zq; 92 92 } -
sasmodels/models/sc_paracrystal.py
rda7b26b rda7b26b 1 1 r""" 2 .. warning:: This model and this model description are under review following 3 concerns raised by SasView users. If you need to use this model, 4 please email help@sasview.org for the latest situation. *The 2 .. warning:: This model and this model description are under review following 3 concerns raised by SasView users. If you need to use this model, 4 please email help@sasview.org for the latest situation. *The 5 5 SasView Developers. September 2018.* 6 6 7 7 Definition 8 8 ---------- … … 104 104 105 105 Authorship and Verification 106 --------------------------- -106 --------------------------- 107 107 108 108 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 109 * **Last Modified by:** Paul Butler **Date:** September 16, 2018110 * **Last Reviewed by:** Paul Butler **Date:** September 16, 2018109 * **Last Modified by:** Paul Butler **Date:** September 29, 2016 110 * **Last Reviewed by:** Richard Heenan **Date:** March 21, 2016 111 111 """ 112 112 … … 129 129 scale: volume fraction of spheres 130 130 bkg:background, R: radius of sphere 131 lattice_spacing: Nearest neighbor distance132 lattice_distortion: Paracrystal distortion factor131 dnn: Nearest neighbor distance 132 d_factor: Paracrystal distortion factor 133 133 radius: radius of the spheres 134 134 sldSph: SLD of the sphere … … 139 139 # pylint: disable=bad-whitespace, line-too-long 140 140 # ["name", "units", default, [lower, upper], "type","description"], 141 parameters = [[" lattice_spacing", "Ang", 220.0, [0.0, inf], "", "Lattice spacing"],142 [" lattice_distortion", "", 0.06, [-inf, inf], "","Paracrystal distortion factor"],141 parameters = [["dnn", "Ang", 220.0, [0.0, inf], "", "Nearest neighbor distance"], 142 ["d_factor", "", 0.06, [-inf, inf], "", "Paracrystal distortion factor"], 143 143 ["radius", "Ang", 40.0, [0.0, inf], "volume", "Radius of sphere"], 144 144 ["sld", "1e-6/Ang^2", 3.0, [0.0, inf], "sld", "Sphere scattering length density"], … … 155 155 # copied from bcc_paracrystal 156 156 radius = 10**np.random.uniform(1.3, 4) 157 lattice_distortion= 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7158 lattice_spacing_fraction = np.random.beta(a=10, b=1)159 lattice_spacing = radius*4/np.sqrt(4)/lattice_spacing_fraction157 d_factor = 10**np.random.uniform(-2, -0.7) # sigma_d in 0.01-0.7 158 dnn_fraction = np.random.beta(a=10, b=1) 159 dnn = radius*4/np.sqrt(4)/dnn_fraction 160 160 pars = dict( 161 161 #sld=1, sld_solvent=0, scale=1, background=1e-32, 162 lattice_spacing=lattice_spacing,163 lattice_distortion=lattice_distortion,162 dnn=dnn, 163 d_factor=d_factor, 164 164 radius=radius, 165 165 )
Note: See TracChangeset
for help on using the changeset viewer.