source: sasmodels/sasmodels/models/core_shell_parallelepiped.c @ 2773c66

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 2773c66 was d277229, checked in by grethevj, 6 years ago

Models updated to include choices for effective interaction radii

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[fc0b7aa]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
[becded3]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)
[44bd2be]10{
[fc0b7aa]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
[44bd2be]27}
28
[d277229]29static double
30radius_from_volume(double length_a, double length_b, double length_c,
31                   double thick_rim_a, double thick_rim_b, double thick_rim_c)
32{
33    const double volume_paral = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c);
34    return cbrt(0.75*volume_paral/M_PI);
35}
36
37static double
38radius_from_crosssection(double length_a, double length_b, double thick_rim_a, double thick_rim_b)
39{
40    const double area_xsec_paral = length_a*length_b + 2.0*thick_rim_a*length_b + 2.0*thick_rim_b*length_a;
41    return sqrt(area_xsec_paral/M_PI);
42}
43
44static double
45effective_radius(int mode, double length_a, double length_b, double length_c,
46                 double thick_rim_a, double thick_rim_b, double thick_rim_c)
47{
48    if (mode == 1) {
49        return radius_from_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c);
50    } else if (mode == 2) {
51        return 0.5 * (length_a + thick_rim_a);
52    } else if (mode == 3) {
53        return 0.5 * (length_b + thick_rim_b);
54    } else if (mode == 4) {
55        return 0.5 * (length_c + thick_rim_c);
56    } else if (mode == 5) {
57        return radius_from_crosssection(length_a, length_b, thick_rim_a, thick_rim_b);
58    } else if (mode == 6) {
59        return 0.5*sqrt(square(length_a+thick_rim_a) + square(length_b+thick_rim_b));
60    } else {
61        return 0.5*sqrt(square(length_a+thick_rim_a) + square(length_b+thick_rim_b) + square(length_c+thick_rim_c));
62    }
63}
64
[71b751d]65static void
66Fq(double q,
67    double *F1,
68    double *F2,
[44bd2be]69    double core_sld,
70    double arim_sld,
71    double brim_sld,
72    double crim_sld,
73    double solvent_sld,
[2222134]74    double length_a,
75    double length_b,
76    double length_c,
77    double thick_rim_a,
78    double thick_rim_b,
79    double thick_rim_c)
[44bd2be]80{
[3a1fc7d]81    // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c
[44bd2be]82    // Did not understand the code completely, it should be rechecked (Miguel Gonzalez)
[e077231]83    // Code is rewritten, the code is compliant with Diva Singh's thesis now (Dirk Honecker)
84    // Code rewritten; cross checked against hollow rectangular prism and realspace (PAK)
[2a0b2b1]85
[4493288]86    const double half_q = 0.5*q;
[2a0b2b1]87
[4493288]88    const double tA = length_a + 2.0*thick_rim_a;
89    const double tB = length_b + 2.0*thick_rim_b;
90    const double tC = length_c + 2.0*thick_rim_c;
[14838a3]91
[4493288]92    // Scale factors
[3a1fc7d]93    const double dr0 = (core_sld-solvent_sld);
94    const double drA = (arim_sld-solvent_sld);
95    const double drB = (brim_sld-solvent_sld);
96    const double drC = (crim_sld-solvent_sld);
[14838a3]97
98    // outer integral (with gauss points), integration limits = 0, 1
[dbf1a60]99    // substitute d_cos_alpha for sin_alpha d_alpha
[71b751d]100    double outer_sum_F1 = 0; //initialize integral
101    double outer_sum_F2 = 0; //initialize integral
[74768cb]102    for( int i=0; i<GAUSS_N; i++) {
[a261a83]103        const double cos_alpha = 0.5 * ( GAUSS_Z[i] + 1.0 );
[4493288]104        const double mu = half_q * sqrt(1.0-cos_alpha*cos_alpha);
105        const double siC = length_c * sas_sinx_x(length_c * cos_alpha * half_q);
106        const double siCt = tC * sas_sinx_x(tC * cos_alpha * half_q);
[dbf1a60]107
108        // inner integral (with gauss points), integration limits = 0, 1
109        // substitute beta = PI/2 u (so 2/PI * d_(PI/2 * beta) = d_beta)
[71b751d]110        double inner_sum_F1 = 0.0;
111        double inner_sum_F2 = 0.0;
[74768cb]112        for(int j=0; j<GAUSS_N; j++) {
[dbf1a60]113            const double u = 0.5 * ( GAUSS_Z[j] + 1.0 );
[4493288]114            double sin_beta, cos_beta;
[dbf1a60]115            SINCOS(M_PI_2*u, sin_beta, cos_beta);
[4493288]116            const double siA = length_a * sas_sinx_x(length_a * mu * sin_beta);
117            const double siB = length_b * sas_sinx_x(length_b * mu * cos_beta);
118            const double siAt = tA * sas_sinx_x(tA * mu * sin_beta);
119            const double siBt = tB * sas_sinx_x(tB * mu * cos_beta);
[3a1fc7d]120
[fc0b7aa]121#if OVERLAPPING
[4493288]122            const double f = dr0*siA*siB*siC
123                + drA*(siAt-siA)*siB*siC
124                + drB*siAt*(siBt-siB)*siC
125                + drC*siAt*siBt*(siCt-siC);
[fc0b7aa]126#else
[4493288]127            const double f = dr0*siA*siB*siC
128                + drA*(siAt-siA)*siB*siC
129                + drB*siA*(siBt-siB)*siC
130                + drC*siA*siB*(siCt-siC);
[fc0b7aa]131#endif
132
[71b751d]133            inner_sum_F1 += GAUSS_W[j] * f;
134            inner_sum_F2 += GAUSS_W[j] * f * f;
[44bd2be]135        }
[dbf1a60]136        // now complete change of inner integration variable (1-0)/(1-(-1))= 0.5
[71b751d]137        // and sum up the outer integral
138        outer_sum_F1 += GAUSS_W[i] * inner_sum_F1 * 0.5;
139        outer_sum_F2 += GAUSS_W[i] * inner_sum_F2 * 0.5;
[44bd2be]140    }
[dbf1a60]141    // now complete change of outer integration variable (1-0)/(1-(-1))= 0.5
[71b751d]142    outer_sum_F1 *= 0.5;
143    outer_sum_F2 *= 0.5;
[44bd2be]144
[14838a3]145    //convert from [1e-12 A-1] to [cm-1]
[71b751d]146    *F1 = 1.0e-2 * outer_sum_F1;
147    *F2 = 1.0e-4 * outer_sum_F2;
[44bd2be]148}
149
[becded3]150static double
[108e70e]151Iqabc(double qa, double qb, double qc,
[44bd2be]152    double core_sld,
153    double arim_sld,
154    double brim_sld,
155    double crim_sld,
156    double solvent_sld,
[2222134]157    double length_a,
158    double length_b,
159    double length_c,
160    double thick_rim_a,
161    double thick_rim_b,
[becded3]162    double thick_rim_c)
[44bd2be]163{
[14838a3]164    // cspkernel in csparallelepiped recoded here
165    const double dr0 = core_sld-solvent_sld;
166    const double drA = arim_sld-solvent_sld;
167    const double drB = brim_sld-solvent_sld;
168    const double drC = crim_sld-solvent_sld;
169
[fc0b7aa]170    const double tA = length_a + 2.0*thick_rim_a;
171    const double tB = length_b + 2.0*thick_rim_b;
172    const double tC = length_c + 2.0*thick_rim_c;
[4493288]173    const double siA = length_a*sas_sinx_x(0.5*length_a*qa);
174    const double siB = length_b*sas_sinx_x(0.5*length_b*qb);
175    const double siC = length_c*sas_sinx_x(0.5*length_c*qc);
176    const double siAt = tA*sas_sinx_x(0.5*tA*qa);
177    const double siBt = tB*sas_sinx_x(0.5*tB*qb);
178    const double siCt = tC*sas_sinx_x(0.5*tC*qc);
[fc0b7aa]179
180#if OVERLAPPING
[4493288]181    const double f = dr0*siA*siB*siC
182        + drA*(siAt-siA)*siB*siC
183        + drB*siAt*(siBt-siB)*siC
184        + drC*siAt*siBt*(siCt-siC);
[fc0b7aa]185#else
[4493288]186    const double f = dr0*siA*siB*siC
187        + drA*(siAt-siA)*siB*siC
188        + drB*siA*(siBt-siB)*siC
189        + drC*siA*siB*(siCt-siC);
[fc0b7aa]190#endif
[2a0b2b1]191
[44bd2be]192    return 1.0e-4 * f * f;
193}
Note: See TracBrowser for help on using the repository browser.