Changeset e5cb3df in sasmodels

Mar 28, 2019 4:17:33 PM (15 months ago)
Paul Kienzle <pkienzle@…>
master, ticket-1257-vesicle-product, ticket_1156, ticket_822_more_unit_tests
Paul Kienzle <pkienzle@…> (03/28/19 16:15:11)
Paul Kienzle <pkienzle@…> (03/28/19 16:17:33)

put in docs for radius_effective, form_volume and shell_volume

1 edited


  • doc/guide/plugin.rst

    r2fe39d1 re5cb3df  
    303303**Note: The order of the parameters in the definition will be the order of the 
    304304parameters in the user interface and the order of the parameters in Fq(), Iq(), 
    305 Iqac(), Iqabc(), form_volume() and shell_volume(). 
     305Iqac(), Iqabc(), radius_effective(), form_volume() and shell_volume(). 
    306306And** *scale* **and** *background* **parameters are implicit to all models, 
    307307so they do not need to be included in the parameter table.** 
    387387can take arbitrary values, even for integer parameters, so your model should 
    388388round 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:: 
     389you should round to the nearest integer.  In C code, you can do this using: 
     391.. code-block:: c 
    391393    static double 
    499501Models should define *form_volume(par1, par2, ...)* where the parameter 
    500502list 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. 
     503volume normalization so that scattering is on an absolute scale.  For 
     504solid shapes, the *I(q)* function should use *form_volume* squared 
     505as its scale factor.  If *form_volume* is not defined, then the default 
     506*form_volume = 1.0* will be used. 
    505508Hollow shapes, where the volume fraction of particle corresponds to the 
    506509material in the shell rather than the volume enclosed by the shape, must 
    507510also 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. 
     511are 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 
     513parameter corresponds to the volume fraction of material in the sample. 
     514The structure factor calculation needs the volume fraction of the filled 
     515shapes for its calculation, so the volume fraction parameter in the model 
     516is automatically scaled by *form_volume/shell_volume* prior to calling the 
     517structure factor. 
    514519**Note: Pure python models do not yet support direct computation of the** 
    525530    """ 
    527 This expands into the equivalent C code:: 
     532This expands into the equivalent C code: 
     534.. code-block:: c 
    529536    double Iq(double q, double par1, double par2, ...); 
    536543includes only the volume parameters. 
    538 *form_volume* defines the volume of the shell for hollow shapes. As in 
     545*shell_volume* defines the volume of the shell for hollow shapes. As in 
    539546python models, it includes only the volume parameters. 
    568575Rather than returning NAN from Iq, you must define the *INVALID(v)*.  The 
    569576*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: 
     579.. code-block:: c 
    572581    #define INVALID(v) (v.bell_radius < v.radius) 
    584593Instead of defining the *Iq* function, models can define *Fq* as 
    585 something like:: 
     594something like: 
     596.. code-block:: c 
    587598    double Fq(double q, double *F1, double *F2, double par1, double par2, ...); 
    615626laboratory frame and beam travelling along $-z$. 
    617 The oriented C model (oriented pure Python models are not supported)  
     628The oriented C model (oriented pure Python models are not supported) 
    618629is called using *Iqabc(qa, qb, qc, par1, par2, ...)* where 
    619630*par1*, etc. are the parameters to the model.  If the shape is rotationally 
    645656Using the $z, w$ values for Gauss-Legendre integration in "lib/gauss76.c", the 
    646 numerical integration is then:: 
     657numerical integration is then: 
     659.. code-block:: c 
    648661    double outer_sum = 0.0; 
    9871000  memory, and wrong answers computed. The conclusion from a very long and 
    9881001  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: 
     1004  .. code-block:: c 
    9911006      double Iq(q, p1, p2, ...) 
    10191034structure factor is the *hardsphere* interaction, which 
    10201035uses 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. 
    1024 :: 
    1026     def ER(radius, thickness): 
    1027         """Effective radius of a core-shell sphere.""" 
    1028         return radius + thickness 
    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*. 
    1042 :: 
    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 
    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. 
    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.* 
     1036factor model.  The effective radius is the weighted average over all 
     1037values of the shape in polydisperse systems. 
     1039There can be many notions of effective radius, depending on the shape.  For 
     1040a sphere it is clearly just the radius, but for an ellipsoid of revolution 
     1041we provide average curvature, equivalent sphere radius, minimum radius and 
     1042maximum radius.  These options are listed as *radius_effective_modes* in 
     1043the python model defintion, and must be computed by the *radius_effective* 
     1044function which takes the *radius_effective_mode* parameter as an integer, 
     1045along with the various model parameters.  Unlike normal C/Python arrays, 
     1046the first mode is 1, the second is 2, etc.  Mode 0 indicates that the 
     1047effective radius from the shape is to be ignored in favour of the the 
     1048effective radius parameter in the structure factor model. 
     1051Consider the core-shell sphere, which defines the following effective radius 
     1052modes in the python model:: 
     1054    radius_effective_modes = [ 
     1055        "outer radius", 
     1056        "core radius", 
     1057    ] 
     1059and the following function in the C-file for the model: 
     1061.. code-block:: c 
     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    } 
     1073    static double 
     1074    form_volume(double radius, double thickness) 
     1075    { 
     1076        return M_4PI_3 * cube(radius + thickness); 
     1077    } 
     1079Given polydispersity over *(r1, r2, ..., rm)* in radius and *(t1, t2, ..., tn)* 
     1080in thickness, *radius_effective* is called over a mesh grid covering all 
     1081possible combinations of radius and thickness, with a single *(ri, tj)* pair 
     1082in each call. The weights each of these results according to the 
     1083polydispersity distributions and calls the structure factor with the average 
     1084effective radius.  Similarly, for *form_volume*. 
     1086Hollow models have an additional volume ratio which is needed to scale the 
     1087structure factor.  The structure factor uses the volume fraction of the filled 
     1088particles as part of its density estimate, but the scale factor for the 
     1089scattering intensity (as non-solvent volume fraction / volume) is determined 
     1090by the shell volume only.  Therefore the *shell_volume* function is 
     1091needed to compute the form:shell volume ratio, which then scales the 
     1092*volfraction* parameter prior to calling the structure factor calculator. 
     1093In the case of a hollow sphere, this would be: 
     1095.. code-block:: c 
     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    } 
     1105If *shell_volume* is not present, then *form_volume* and *shell_volume* are 
     1106assumed to be equal, and the shape is considered solid. 
    10591108Unit Tests 
    12521301| 2016-10-25 Steve King 
    12531302| 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.