source: sasview/sansmodels/src/sans/models/c_models/spheroid.cpp @ 27953d1

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 27953d1 was eddff027, checked in by Jae Cho <jhjcho@…>, 15 years ago

added coreshellellipsoidmodel

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/**
2        This software was developed by the University of Tennessee as part of the
3        Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4        project funded by the US National Science Foundation.
5
6        If you use DANSE applications to do scientific research that leads to
7        publication, we ask that you acknowledge the use of the software with the
8        following sentence:
9
10        "This work benefited from DANSE software developed under NSF award DMR-0520547."
11
12        copyright 2008, University of Tennessee
13 */
14
15/**
16 * Scattering model classes
17 * The classes use the IGOR library found in
18 *   sansmodels/src/libigor
19 *
20 *      TODO: refactor so that we pull in the old sansmodels.c_extensions
21 */
22
23#include <math.h>
24#include "models.hh"
25#include "parameters.hh"
26#include <stdio.h>
27using namespace std;
28
29extern "C" {
30        #include "libCylinder.h"
31        #include "spheroid.h"
32}
33
34CoreShellEllipsoidModel :: CoreShellEllipsoidModel() {
35        scale      = Parameter(1.0);
36        equat_core     = Parameter(200.0, true);
37        equat_core.set_min(0.0);
38        polar_core     = Parameter(20.0, true);
39        polar_core.set_min(0.0);
40        equat_shell   = Parameter(250.0, true);
41        equat_shell.set_min(0.0);
42        polar_shell    = Parameter(30.0, true);
43        polar_shell.set_min(0.0);
44        contrast   = Parameter(1e-6);
45        sld_solvent = Parameter(6.3e-6);
46        background = Parameter(0.0);
47        axis_theta  = Parameter(0.0, true);
48        axis_phi    = Parameter(0.0, true);
49
50}
51
52/**
53 * Function to evaluate 1D scattering function
54 * The NIST IGOR library is used for the actual calculation.
55 * @param q: q-value
56 * @return: function value
57 */
58double CoreShellEllipsoidModel :: operator()(double q) {
59        double dp[8];
60
61        // Fill parameter array for IGOR library
62        // Add the background after averaging
63        dp[0] = scale();
64        dp[1] = equat_core();
65        dp[2] = polar_core();
66        dp[3] = equat_shell();
67        dp[4] = polar_shell();
68        dp[5] = contrast();
69        dp[6] = sld_solvent();
70        dp[7] = 0.0;
71
72        // Get the dispersion points for the major core
73        vector<WeightPoint> weights_equat_core;
74        equat_core.get_weights(weights_equat_core);
75
76        // Get the dispersion points for the minor core
77        vector<WeightPoint> weights_polar_core;
78        polar_core.get_weights(weights_polar_core);
79
80        // Get the dispersion points for the major shell
81        vector<WeightPoint> weights_equat_shell;
82        equat_shell.get_weights(weights_equat_shell);
83
84        // Get the dispersion points for the minor_shell
85        vector<WeightPoint> weights_polar_shell;
86        polar_shell.get_weights(weights_polar_shell);
87
88
89        // Perform the computation, with all weight points
90        double sum = 0.0;
91        double norm = 0.0;
92
93        // Loop over major core weight points
94        for(int i=0; i<(int)weights_equat_core.size(); i++) {
95                dp[1] = weights_equat_core[i].value;
96
97                // Loop over minor core weight points
98                for(int j=0; j<(int)weights_polar_core.size(); j++) {
99                        dp[2] = weights_polar_core[j].value;
100
101                        // Loop over major shell weight points
102                        for(int k=0; k<(int)weights_equat_shell.size(); k++) {
103                                dp[3] = weights_equat_shell[k].value;
104
105                                // Loop over minor shell weight points
106                                for(int l=0; l<(int)weights_polar_shell.size(); l++) {
107                                        dp[4] = weights_polar_shell[l].value;
108
109                                        sum += weights_equat_core[i].weight* weights_polar_core[j].weight * weights_equat_shell[k].weight
110                                                * weights_polar_shell[l].weight * OblateForm(dp, q);
111                                        norm += weights_equat_core[i].weight* weights_polar_core[j].weight * weights_equat_shell[k].weight
112                                                        * weights_polar_shell[l].weight;
113                                }
114                        }
115                }
116        }
117        return sum/norm + background();
118}
119
120/**
121 * Function to evaluate 2D scattering function
122 * @param q_x: value of Q along x
123 * @param q_y: value of Q along y
124 * @return: function value
125 */
126/*
127double OblateModel :: operator()(double qx, double qy) {
128        double q = sqrt(qx*qx + qy*qy);
129
130        return (*this).operator()(q);
131}
132*/
133
134/**
135 * Function to evaluate 2D scattering function
136 * @param pars: parameters of the oblate
137 * @param q: q-value
138 * @param phi: angle phi
139 * @return: function value
140 */
141double CoreShellEllipsoidModel :: evaluate_rphi(double q, double phi) {
142        return (*this).operator()(q);
143}
144
145
146double CoreShellEllipsoidModel :: operator()(double qx, double qy) {
147        SpheroidParameters dp;
148        // Fill parameter array
149        dp.scale      = scale();
150        dp.equat_core = equat_core();
151        dp.polar_core = polar_core();
152        dp.equat_shell = equat_shell();
153        dp.polar_shell = polar_shell();
154        dp.contrast = contrast();
155        dp.sld_solvent = sld_solvent();
156        dp.background = background();
157        dp.axis_theta = axis_theta();
158        dp.axis_phi = axis_phi();
159
160        // Get the dispersion points for the major core
161        vector<WeightPoint> weights_equat_core;
162        equat_core.get_weights(weights_equat_core);
163
164        // Get the dispersion points for the minor core
165        vector<WeightPoint> weights_polar_core;
166        polar_core.get_weights(weights_polar_core);
167
168        // Get the dispersion points for the major shell
169        vector<WeightPoint> weights_equat_shell;
170        equat_shell.get_weights(weights_equat_shell);
171
172        // Get the dispersion points for the minor shell
173        vector<WeightPoint> weights_polar_shell;
174        polar_shell.get_weights(weights_polar_shell);
175
176
177        // Get angular averaging for theta
178        vector<WeightPoint> weights_theta;
179        axis_theta.get_weights(weights_theta);
180
181        // Get angular averaging for phi
182        vector<WeightPoint> weights_phi;
183        axis_phi.get_weights(weights_phi);
184
185        // Perform the computation, with all weight points
186        double sum = 0.0;
187        double norm = 0.0;
188
189        // Loop over major core weight points
190        for(int i=0; i< (int)weights_equat_core.size(); i++) {
191                dp.equat_core = weights_equat_core[i].value;
192
193                // Loop over minor core weight points
194                for(int j=0; j< (int)weights_polar_core.size(); j++) {
195                        dp.polar_core = weights_polar_core[j].value;
196
197                        // Loop over major shell weight points
198                        for(int k=0; k< (int)weights_equat_shell.size(); k++) {
199                                dp.equat_shell = weights_equat_shell[i].value;
200
201                                // Loop over minor shell weight points
202                                for(int l=0; l< (int)weights_polar_shell.size(); l++) {
203                                        dp.polar_shell = weights_polar_shell[l].value;
204
205                                        // Average over theta distribution
206                                        for(int m=0; m< (int)weights_theta.size(); m++) {
207                                                dp.axis_theta = weights_theta[m].value;
208
209                                                // Average over phi distribution
210                                                for(int n=0; n< (int)weights_phi.size(); n++) {
211                                                        dp.axis_phi = weights_phi[n].value;
212
213                                                        double _ptvalue = weights_equat_core[i].weight *weights_polar_core[j].weight
214                                                                * weights_equat_shell[k].weight * weights_polar_shell[l].weight
215                                                                * weights_theta[m].weight
216                                                                * weights_phi[n].weight
217                                                                * spheroid_analytical_2DXY(&dp, qx, qy);
218                                                        if (weights_theta.size()>1) {
219                                                                _ptvalue *= sin(weights_theta[m].value);
220                                                        }
221                                                        sum += _ptvalue;
222
223                                                        norm += weights_equat_core[i].weight *weights_polar_core[j].weight
224                                                                * weights_equat_shell[k].weight * weights_polar_shell[l].weight
225                                                                * weights_theta[m].weight * weights_phi[n].weight;
226                                                }
227                                        }
228                                }
229                        }
230                }
231        }
232        // Averaging in theta needs an extra normalization
233        // factor to account for the sin(theta) term in the
234        // integration (see documentation).
235        if (weights_theta.size()>1) norm = norm / asin(1.0);
236        return sum/norm + background();
237}
238
Note: See TracBrowser for help on using the repository browser.