Changeset 54bcd4a in sasmodels for sasmodels/models/spherical_sld.py
- Timestamp:
- Aug 4, 2016 2:48:37 PM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 745b7bb
- Parents:
- bd49c79
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/spherical_sld.py
r4fd2c63 r54bcd4a 190 190 191 191 import numpy as np 192 from numpy import inf 192 from numpy import inf, expm1, sqrt 193 from scipy.special import erf 193 194 194 195 name = "spherical_sld" … … 200 201 category = "shape:sphere" 201 202 203 SHAPES = ["erf(|nu|*z)", "Rpow(z^|nu|)", "Lpow(z^|nu|)", 204 "Rexp(-|nu|z)", "Lexp(-|nu|z)"], 205 202 206 # pylint: disable=bad-whitespace, line-too-long 203 207 # ["name", "units", default, [lower, upper], "type", "description"], 204 parameters = [["n_shells", "", 1, [0, 10], "volume", "number of shells"], 205 ["npts_inter", "", 35, [0, inf], "", "number of points in each sublayer Must be odd number"], 206 ["radius_core", "Ang", 50.0, [0, inf], "volume", "intern layer thickness"], 207 ["sld_core", "1e-6/Ang^2", 2.07, [-inf, inf], "sld", "sld function flat"], 208 ["sld_solvent", "1e-6/Ang^2", 1.0, [-inf, inf], "sld", "sld function solvent"], 209 ["func_inter0", "", 0, [0, 5], "", "Erf:0, RPower:1, LPower:2, RExp:3, LExp:4, Linear:5"], 210 ["thick_inter0", "Ang", 50.0, [0, inf], "volume", "intern layer thickness for core layer"], 211 ["nu_inter0", "", 2.5, [-inf, inf], "", "steepness parameter for core layer"], 212 ["sld_flat[n_shells]", "1e-6/Ang^2", 4.06, [-inf, inf], "sld", "sld function flat"], 213 ["thick_flat[n_shells]", "Ang", 100.0, [0, inf], "volume", "flat layer_thickness"], 214 ["func_inter[n_shells]", "", 0, [0, 5], "", "Erf:0, RPower:1, LPower:2, RExp:3, LExp:4, Linear:5"], 215 ["thick_inter[n_shells]", "Ang", 50.0, [0, inf], "volume", "intern layer thickness"], 216 ["nu_inter[n_shells]", "", 2.5, [-inf, inf], "", "steepness parameter"], 208 parameters = [["n_shells", "", 1, [1, 11], "volume", "number of shells"], 209 ["sld_solvent", "1e-6/Ang^2", 1.0, [-inf, inf], "sld", "solvent sld"], 210 ["sld[n_shells]", "1e-6/Ang^2", 4.06, [-inf, inf], "sld", "sld of the shell"], 211 ["thickness[n_shells]", "Ang", 100.0, [0, inf], "volume", "thickness shell"], 212 ["interface[n_shells]", "Ang", 50.0, [0, inf], "volume", "thickness of the interface"], 213 ["shape[n_shells]", "", 0, SHAPES, "", "interface shape"], 214 ["nu[n_shells]", "", 2.5, [0, inf], "", "interface shape exponent"], 215 ["n_steps", "", 35, [0, inf], "", "number of steps in each interface (must be an odd integer)"], 217 216 ] 218 217 # pylint: enable=bad-whitespace, line-too-long 219 source = ["lib/polevl.c", "lib/sas_erf.c", "lib/ librefl.c", "lib/sph_j1c.c", "spherical_sld.c"]218 source = ["lib/polevl.c", "lib/sas_erf.c", "lib/sph_j1c.c", "spherical_sld.c"] 220 219 single = False # TODO: fix low q behaviour 221 220 222 221 profile_axes = ['Radius (A)', 'SLD (1e-6/A^2)'] 223 def profile(n_shells, radius_core, sld_core, sld_solvent, sld_flat, 224 thick_flat, func_inter, thick_inter, nu_inter, npts_inter): 222 223 SHAPE_FUNCTIONS = [ 224 lambda z, nu: erf(nu/sqrt(2)*(2*z-1))/(2*erf(nu/sqrt(2))) + 0.5, # erf 225 lambda z, nu: z**nu, # Rpow 226 lambda z, nu: 1 - (1-z)**nu, # Lpow 227 lambda z, nu: expm1(-nu*z)/expm1(-nu), # Rexp 228 lambda z, nu: expm1(nu*z)/expm1(nu), # Lexp 229 ] 230 231 def profile(n_shells, sld_solvent, sld, thickness, 232 interface, shape, nu, n_steps): 225 233 """ 226 234 Returns shape profile with x=radius, y=SLD. … … 228 236 229 237 z = [] 230 beta= []238 rho = [] 231 239 z0 = 0 232 240 # two sld points for core 233 241 z.append(0) 234 beta.append(sld_core) 235 z.append(radius_core) 236 beta.append(sld_core) 237 z0 += radius_core 238 239 for i in range(1, n_shells+2): 240 dz = thick_inter[i-1]/npts_inter 241 # j=0 for interface, j=1 for flat layer 242 for j in range(0, 2): 243 # interation for sub-layers 244 for n_s in range(0, npts_inter+1): 245 if j == 1: 246 if i == n_shells+1: 247 break 248 # shift half sub thickness for the first point 249 z0 -= dz#/2.0 250 z.append(z0) 251 #z0 -= dz/2.0 252 z0 += thick_flat[i] 253 sld_i = sld_flat[i] 254 beta.append(sld_flat[i]) 255 dz = 0 256 else: 257 nu = nu_inter[i-1] 258 # decide which sld is which, sld_r or sld_l 259 if i == 1: 260 sld_l = sld_core 261 else: 262 sld_l = sld_flat[i-1] 263 if i == n_shells+1: 264 sld_r = sld_solvent 265 else: 266 sld_r = sld_flat[i] 267 # get function type 268 func_idx = func_inter[i-1] 269 # calculate the sld 270 sld_i = intersldfunc(func_idx, npts_inter, n_s, nu, 271 sld_l, sld_r) 272 # append to the list 273 z.append(z0) 274 beta.append(sld_i) 275 z0 += dz 276 if j == 1: 277 break 278 z.append(z0) 279 beta.append(sld_solvent) 280 z_ext = z0/5.0 281 z.append(z0+z_ext) 282 beta.append(sld_solvent) 242 rho.append(sld[0]) 243 244 for i in range(0, n_shells): 245 z0 += thickness[i] 246 z.append(z0) 247 rho.append(sld[i]) 248 dz = interface[i]/n_steps 249 sld_l = sld[i] 250 sld_r = sld[i+1] if i < n_shells-1 else sld_solvent 251 interface = SHAPE_FUNCTIONS[int(np.clip(shape[i], 0, len(SHAPES)-1))] 252 for step in range(1, n_steps+1): 253 portion = interface(float(step)/n_steps, max(abs(nu[i]), 1e-14)) 254 z0 += dz 255 z.append(z0) 256 rho.append((sld_r - sld_l)*portion + sld_l) 257 z.append(z0*1.2) 258 rho.append(sld_solvent) 283 259 # return sld profile (r, beta) 284 return np.asarray(z), np.asarray(beta)*1e-6 285 286 def ER(n_shells, radius_core, thick_inter0, thick_inter, thick_flat): 260 return np.asarray(z), np.asarray(rho)*1e-6 261 262 263 def ER(n_shells, thickness, interface): 287 264 n_shells = int(n_shells) 288 total_thickness = thick_inter0 289 total_thickness += np.sum(thick_inter[:n_shells], axis=0) 290 total_thickness += np.sum(thick_flat[:n_shells], axis=0) 291 return total_thickness + radius_core 265 total = (np.sum(thickness[:n_shells], axis=1) 266 + np.sum(interface[:n_shells], axis=1)) 267 return total 292 268 293 269 294 270 demo = { 295 "n_shells": 4, 296 "npts_inter": 35.0, 297 "radius_core": 50.0, 298 "sld_core": 2.07, 271 "n_shells": 5, 272 "n_steps": 35.0, 299 273 "sld_solvent": 1.0, 300 "thick_inter0": 50.0, 301 "func_inter0": 0, 302 "nu_inter0": 2.5, 303 "sld_flat":[4.0,3.5,4.0,3.5], 304 "thick_flat":[100.0,100.0,100.0,100.0], 305 "func_inter":[0,0,0,0], 306 "thick_inter":[50.0,50.0,50.0,50.0], 307 "nu_inter":[2.5,2.5,2.5,2.5], 274 "sld":[2.07,4.0,3.5,4.0,3.5], 275 "thickness":[50.0,100.0,100.0,100.0,100.0], 276 "interface":[50.0,50.0,50.0,50.0], 277 "shape": [0,0,0,0,0], 278 "nu":[2.5,2.5,2.5,2.5,2.5], 308 279 } 309 280 … … 312 283 tests = [ 313 284 # Accuracy tests based on content in test/utest_extra_models.py 314 [{"n_shells":4, 315 'npts_inter':35, 316 "radius_core":50.0, 317 "sld_core":2.07, 285 [{"n_shells": 5, 286 "n_steps": 35, 318 287 "sld_solvent": 1.0, 319 "sld _flat":[4.0,3.5,4.0,3.5],320 "thick _flat":[100.0,100.0,100.0,100.0],321 " func_inter":[0,0,0,0],322 " thick_inter":[50.0,50.0,50.0,50.0],323 "nu _inter":[2.5,2.5,2.5,2.5]288 "sld": [2.07, 4.0, 3.5, 4.0, 3.5], 289 "thickness": [50.0, 100.0, 100.0, 100.0, 100.0], 290 "interface": [50]*5, 291 "shape": [0]*5, 292 "nu": [2.5]*5, 324 293 }, 0.001, 0.001], 325 294 ]
Note: See TracChangeset
for help on using the changeset viewer.