- Timestamp:
- Mar 28, 2019 4:17:33 PM (6 years ago)
- Branches:
- master, ticket-1257-vesicle-product, ticket_1156, ticket_822_more_unit_tests
- Children:
- a34b811
- Parents:
- 3709366
- git-author:
- Paul Kienzle <pkienzle@…> (03/28/19 16:15:11)
- git-committer:
- Paul Kienzle <pkienzle@…> (03/28/19 16:17:33)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/guide/plugin.rst
r2fe39d1 re5cb3df 303 303 **Note: The order of the parameters in the definition will be the order of the 304 304 parameters in the user interface and the order of the parameters in Fq(), Iq(), 305 Iqac(), Iqabc(), form_volume() and shell_volume().305 Iqac(), Iqabc(), radius_effective(), form_volume() and shell_volume(). 306 306 And** *scale* **and** *background* **parameters are implicit to all models, 307 307 so they do not need to be included in the parameter table.** … … 387 387 can take arbitrary values, even for integer parameters, so your model should 388 388 round the incoming parameter value to the nearest integer inside your model 389 you should round to the nearest integer. In C code, you can do this using:: 389 you should round to the nearest integer. In C code, you can do this using: 390 391 .. code-block:: c 390 392 391 393 static double … … 499 501 Models should define *form_volume(par1, par2, ...)* where the parameter 500 502 list includes the *volume* parameters in order. This is used for a weighted 501 volume normalization so that scattering is on an absolute scale. If 502 *form_volume* is not defined, then the default *form_volume = 1.0* will be 503 used. 503 volume normalization so that scattering is on an absolute scale. For 504 solid shapes, the *I(q)* function should use *form_volume* squared 505 as its scale factor. If *form_volume* is not defined, then the default 506 *form_volume = 1.0* will be used. 504 507 505 508 Hollow shapes, where the volume fraction of particle corresponds to the 506 509 material in the shell rather than the volume enclosed by the shape, must 507 510 also define a *shell_volume(par1, par2, ...)* function. The parameters 508 are the same as for *form_volume*. The *I(q)* calculation should use 509 *shell_volume* squared as its scale factor for the volume normalization. 510 The structure factor calculation needs *form_volume* in order to properly 511 scale the volume fraction parameter, so both functions are required for 512 hollow shapes. 511 are the same as for *form_volume*. Here the *I(q)* function should use 512 *shell_volume* squared instead of *form_volume* squared so that the scale 513 parameter corresponds to the volume fraction of material in the sample. 514 The structure factor calculation needs the volume fraction of the filled 515 shapes for its calculation, so the volume fraction parameter in the model 516 is automatically scaled by *form_volume/shell_volume* prior to calling the 517 structure factor. 513 518 514 519 **Note: Pure python models do not yet support direct computation of the** … … 525 530 """ 526 531 527 This expands into the equivalent C code:: 532 This expands into the equivalent C code: 533 534 .. code-block:: c 528 535 529 536 double Iq(double q, double par1, double par2, ...); … … 536 543 includes only the volume parameters. 537 544 538 * form_volume* defines the volume of the shell for hollow shapes. As in545 *shell_volume* defines the volume of the shell for hollow shapes. As in 539 546 python models, it includes only the volume parameters. 540 547 … … 568 575 Rather than returning NAN from Iq, you must define the *INVALID(v)*. The 569 576 *v* parameter lets you access all the parameters in the model using 570 *v.par1*, *v.par2*, etc. For example:: 577 *v.par1*, *v.par2*, etc. For example: 578 579 .. code-block:: c 571 580 572 581 #define INVALID(v) (v.bell_radius < v.radius) … … 583 592 584 593 Instead of defining the *Iq* function, models can define *Fq* as 585 something like:: 594 something like: 595 596 .. code-block:: c 586 597 587 598 double Fq(double q, double *F1, double *F2, double par1, double par2, ...); … … 615 626 laboratory frame and beam travelling along $-z$. 616 627 617 The oriented C model (oriented pure Python models are not supported) 628 The oriented C model (oriented pure Python models are not supported) 618 629 is called using *Iqabc(qa, qb, qc, par1, par2, ...)* where 619 630 *par1*, etc. are the parameters to the model. If the shape is rotationally … … 644 655 645 656 Using the $z, w$ values for Gauss-Legendre integration in "lib/gauss76.c", the 646 numerical integration is then:: 657 numerical integration is then: 658 659 .. code-block:: c 647 660 648 661 double outer_sum = 0.0; … … 987 1000 memory, and wrong answers computed. The conclusion from a very long and 988 1001 strange debugging session was that any arrays that you declare in your 989 model should be a multiple of four. For example:: 1002 model should be a multiple of four. For example: 1003 1004 .. code-block:: c 990 1005 991 1006 double Iq(q, p1, p2, ...) … … 1019 1034 structure factor is the *hardsphere* interaction, which 1020 1035 uses the effective radius of the form factor as an input to the structure 1021 factor model. The effective radius is the average radius of the 1022 form averaged over all the polydispersity values. 1023 1024 :: 1025 1026 def ER(radius, thickness): 1027 """Effective radius of a core-shell sphere.""" 1028 return radius + thickness 1029 1030 Now consider the *core_shell_sphere*, which has a simple effective radius 1031 equal to the radius of the core plus the thickness of the shell, as 1032 shown above. Given polydispersity over *(r1, r2, ..., rm)* in radius and 1033 *(t1, t2, ..., tn)* in thickness, *ER* is called with a mesh 1034 grid covering all possible combinations of radius and thickness. 1035 That is, *radius* is *(r1, r2, ..., rm, r1, r2, ..., rm, ...)* 1036 and *thickness* is *(t1, t1, ... t1, t2, t2, ..., t2, ...)*. 1037 The *ER* function returns one effective radius for each combination. 1038 The effective radius calculator weights each of these according to 1039 the polydispersity distributions and calls the structure factor 1040 with the average *ER*. 1041 1042 :: 1043 1044 def VR(radius, thickness): 1045 """Sphere and shell volumes for a core-shell sphere.""" 1046 whole = 4.0/3.0 * pi * (radius + thickness)**3 1047 core = 4.0/3.0 * pi * radius**3 1048 return whole, whole - core 1049 1050 Core-shell type models have an additional volume ratio which scales 1051 the structure factor. The *VR* function returns the volume of 1052 the whole sphere and the volume of the shell. Like *ER*, there is 1053 one return value for each point in the mesh grid. 1054 1055 *NOTE: we may be removing or modifying this feature soon. As of the 1056 time of writing, core-shell sphere returns (1., 1.) for VR, giving a volume 1057 ratio of 1.0.* 1036 factor model. The effective radius is the weighted average over all 1037 values of the shape in polydisperse systems. 1038 1039 There can be many notions of effective radius, depending on the shape. For 1040 a sphere it is clearly just the radius, but for an ellipsoid of revolution 1041 we provide average curvature, equivalent sphere radius, minimum radius and 1042 maximum radius. These options are listed as *radius_effective_modes* in 1043 the python model defintion, and must be computed by the *radius_effective* 1044 function which takes the *radius_effective_mode* parameter as an integer, 1045 along with the various model parameters. Unlike normal C/Python arrays, 1046 the first mode is 1, the second is 2, etc. Mode 0 indicates that the 1047 effective radius from the shape is to be ignored in favour of the the 1048 effective radius parameter in the structure factor model. 1049 1050 1051 Consider the core-shell sphere, which defines the following effective radius 1052 modes in the python model:: 1053 1054 radius_effective_modes = [ 1055 "outer radius", 1056 "core radius", 1057 ] 1058 1059 and the following function in the C-file for the model: 1060 1061 .. code-block:: c 1062 1063 static double 1064 radius_effective(int mode, double radius, double thickness) 1065 { 1066 switch (mode) { 1067 case 0: return radius + thickness; 1068 case 1: return radius; 1069 default: return 0.; 1070 } 1071 } 1072 1073 static double 1074 form_volume(double radius, double thickness) 1075 { 1076 return M_4PI_3 * cube(radius + thickness); 1077 } 1078 1079 Given polydispersity over *(r1, r2, ..., rm)* in radius and *(t1, t2, ..., tn)* 1080 in thickness, *radius_effective* is called over a mesh grid covering all 1081 possible combinations of radius and thickness, with a single *(ri, tj)* pair 1082 in each call. The weights each of these results according to the 1083 polydispersity distributions and calls the structure factor with the average 1084 effective radius. Similarly, for *form_volume*. 1085 1086 Hollow models have an additional volume ratio which is needed to scale the 1087 structure factor. The structure factor uses the volume fraction of the filled 1088 particles as part of its density estimate, but the scale factor for the 1089 scattering intensity (as non-solvent volume fraction / volume) is determined 1090 by the shell volume only. Therefore the *shell_volume* function is 1091 needed to compute the form:shell volume ratio, which then scales the 1092 *volfraction* parameter prior to calling the structure factor calculator. 1093 In the case of a hollow sphere, this would be: 1094 1095 .. code-block:: c 1096 1097 static double 1098 shell_volume(double radius, double thickness) 1099 { 1100 double whole = M_4PI_3 * cube(radius + thickness); 1101 double core = M_4PI_3 * cube(radius); 1102 return whole - core; 1103 } 1104 1105 If *shell_volume* is not present, then *form_volume* and *shell_volume* are 1106 assumed to be equal, and the shape is considered solid. 1058 1107 1059 1108 Unit Tests … … 1252 1301 | 2016-10-25 Steve King 1253 1302 | 2017-05-07 Paul Kienzle - Moved from sasview to sasmodels docs 1303 | 2019-03-28 Paul Kienzle - Update docs for radius_effective and shell_volume
Note: See TracChangeset
for help on using the changeset viewer.