source: sasmodels/sasmodels/models/core_shell_parallelepiped.c @ 71b751d

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 71b751d was 71b751d, checked in by Paul Kienzle <pkienzle@…>, 6 years ago

update remaining form factors to use Fq interface

  • Property mode set to 100644
File size: 5.6 KB
Line 
1// Set OVERLAPPING to 1 in order to fill in the edges of the box, with
2// c endcaps and b overlapping a.  With the proper choice of parameters,
3// (setting rim slds to sld, core sld to solvent, rim thickness to thickness
4// and subtracting 2*thickness from length, this should match the hollow
5// rectangular prism.)  Set it to 0 for the documented behaviour.
6#define OVERLAPPING 0
7static double
8form_volume(double length_a, double length_b, double length_c,
9    double thick_rim_a, double thick_rim_b, double thick_rim_c)
10{
11    return
12#if OVERLAPPING
13        // Hollow rectangular prism only includes the volume of the shell
14        // so uncomment the next line when comparing.  Solid rectangular
15        // prism, or parallelepiped want filled cores, so comment when
16        // comparing.
17        //-length_a * length_b * length_c +
18        (length_a + 2.0*thick_rim_a) *
19        (length_b + 2.0*thick_rim_b) *
20        (length_c + 2.0*thick_rim_c);
21#else
22        length_a * length_b * length_c +
23        2.0 * thick_rim_a * length_b * length_c +
24        2.0 * length_a * thick_rim_b * length_c +
25        2.0 * length_a * length_b * thick_rim_c;
26#endif
27}
28
29static void
30Fq(double q,
31    double *F1,
32    double *F2,
33    double core_sld,
34    double arim_sld,
35    double brim_sld,
36    double crim_sld,
37    double solvent_sld,
38    double length_a,
39    double length_b,
40    double length_c,
41    double thick_rim_a,
42    double thick_rim_b,
43    double thick_rim_c)
44{
45    // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c
46    // Did not understand the code completely, it should be rechecked (Miguel Gonzalez)
47    // Code is rewritten, the code is compliant with Diva Singh's thesis now (Dirk Honecker)
48    // Code rewritten; cross checked against hollow rectangular prism and realspace (PAK)
49
50    const double half_q = 0.5*q;
51
52    const double tA = length_a + 2.0*thick_rim_a;
53    const double tB = length_b + 2.0*thick_rim_b;
54    const double tC = length_c + 2.0*thick_rim_c;
55
56    // Scale factors
57    const double dr0 = (core_sld-solvent_sld);
58    const double drA = (arim_sld-solvent_sld);
59    const double drB = (brim_sld-solvent_sld);
60    const double drC = (crim_sld-solvent_sld);
61
62    // outer integral (with gauss points), integration limits = 0, 1
63    // substitute d_cos_alpha for sin_alpha d_alpha
64    double outer_sum_F1 = 0; //initialize integral
65    double outer_sum_F2 = 0; //initialize integral
66    for( int i=0; i<GAUSS_N; i++) {
67        const double cos_alpha = 0.5 * ( GAUSS_Z[i] + 1.0 );
68        const double mu = half_q * sqrt(1.0-cos_alpha*cos_alpha);
69        const double siC = length_c * sas_sinx_x(length_c * cos_alpha * half_q);
70        const double siCt = tC * sas_sinx_x(tC * cos_alpha * half_q);
71
72        // inner integral (with gauss points), integration limits = 0, 1
73        // substitute beta = PI/2 u (so 2/PI * d_(PI/2 * beta) = d_beta)
74        double inner_sum_F1 = 0.0;
75        double inner_sum_F2 = 0.0;
76        for(int j=0; j<GAUSS_N; j++) {
77            const double u = 0.5 * ( GAUSS_Z[j] + 1.0 );
78            double sin_beta, cos_beta;
79            SINCOS(M_PI_2*u, sin_beta, cos_beta);
80            const double siA = length_a * sas_sinx_x(length_a * mu * sin_beta);
81            const double siB = length_b * sas_sinx_x(length_b * mu * cos_beta);
82            const double siAt = tA * sas_sinx_x(tA * mu * sin_beta);
83            const double siBt = tB * sas_sinx_x(tB * mu * cos_beta);
84
85#if OVERLAPPING
86            const double f = dr0*siA*siB*siC
87                + drA*(siAt-siA)*siB*siC
88                + drB*siAt*(siBt-siB)*siC
89                + drC*siAt*siBt*(siCt-siC);
90#else
91            const double f = dr0*siA*siB*siC
92                + drA*(siAt-siA)*siB*siC
93                + drB*siA*(siBt-siB)*siC
94                + drC*siA*siB*(siCt-siC);
95#endif
96
97            inner_sum_F1 += GAUSS_W[j] * f;
98            inner_sum_F2 += GAUSS_W[j] * f * f;
99        }
100        // now complete change of inner integration variable (1-0)/(1-(-1))= 0.5
101        // and sum up the outer integral
102        outer_sum_F1 += GAUSS_W[i] * inner_sum_F1 * 0.5;
103        outer_sum_F2 += GAUSS_W[i] * inner_sum_F2 * 0.5;
104    }
105    // now complete change of outer integration variable (1-0)/(1-(-1))= 0.5
106    outer_sum_F1 *= 0.5;
107    outer_sum_F2 *= 0.5;
108
109    //convert from [1e-12 A-1] to [cm-1]
110    *F1 = 1.0e-2 * outer_sum_F1;
111    *F2 = 1.0e-4 * outer_sum_F2;
112}
113
114static double
115Iqabc(double qa, double qb, double qc,
116    double core_sld,
117    double arim_sld,
118    double brim_sld,
119    double crim_sld,
120    double solvent_sld,
121    double length_a,
122    double length_b,
123    double length_c,
124    double thick_rim_a,
125    double thick_rim_b,
126    double thick_rim_c)
127{
128    // cspkernel in csparallelepiped recoded here
129    const double dr0 = core_sld-solvent_sld;
130    const double drA = arim_sld-solvent_sld;
131    const double drB = brim_sld-solvent_sld;
132    const double drC = crim_sld-solvent_sld;
133
134    const double tA = length_a + 2.0*thick_rim_a;
135    const double tB = length_b + 2.0*thick_rim_b;
136    const double tC = length_c + 2.0*thick_rim_c;
137    const double siA = length_a*sas_sinx_x(0.5*length_a*qa);
138    const double siB = length_b*sas_sinx_x(0.5*length_b*qb);
139    const double siC = length_c*sas_sinx_x(0.5*length_c*qc);
140    const double siAt = tA*sas_sinx_x(0.5*tA*qa);
141    const double siBt = tB*sas_sinx_x(0.5*tB*qb);
142    const double siCt = tC*sas_sinx_x(0.5*tC*qc);
143
144#if OVERLAPPING
145    const double f = dr0*siA*siB*siC
146        + drA*(siAt-siA)*siB*siC
147        + drB*siAt*(siBt-siB)*siC
148        + drC*siAt*siBt*(siCt-siC);
149#else
150    const double f = dr0*siA*siB*siC
151        + drA*(siAt-siA)*siB*siC
152        + drB*siA*(siBt-siB)*siC
153        + drC*siA*siB*(siCt-siC);
154#endif
155
156    return 1.0e-4 * f * f;
157}
Note: See TracBrowser for help on using the repository browser.