source: sasview/sansmodels/src/sans/models/c_models/flexiblecylinder.cpp @ 7a69683

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 7a69683 was 5068697, checked in by Gervaise Alina <gervyh@…>, 16 years ago

add 1d models

  • Property mode set to 100644
File size: 5.2 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 *      TODO: add 2d
22 */
23
24#include <math.h>
25#include "models.hh"
26#include "parameters.hh"
27#include <stdio.h>
28using namespace std;
29
30extern "C" {
31        #include "libCylinder.h"
32        #include "flexible_cylinder.h"
33}
34
35FlexibleCylinderModel :: FlexibleCylinderModel() {
36        scale      = Parameter(1.0);
37        length     = Parameter(1000.0, true);
38        length.set_min(0.0);
39        kuhn_length = Parameter(100.0, true);
40        kuhn_length.set_min(0.0);
41        radius  = Parameter(20.0, true);
42        radius.set_min(0.0);
43        contrast   = Parameter(5.3e-6);
44        background = Parameter(0.0001);
45        axis_theta  = Parameter(0.0, true);
46        axis_phi    = Parameter(0.0, true);
47}
48
49/**
50 * Function to evaluate 1D scattering function
51 * The NIST IGOR library is used for the actual calculation.
52 * @param q: q-value
53 * @return: function value
54 */
55double FlexibleCylinderModel :: operator()(double q) {
56        double dp[5];
57
58        // Fill parameter array for IGOR library
59        // Add the background after averaging
60        dp[0] = scale();
61        dp[1] = length();
62        dp[2] = kuhn_length();
63        dp[3] = radius();
64        dp[4] = contrast();
65        dp[5] = background();
66
67        // Get the dispersion points for the length
68        vector<WeightPoint> weights_length;
69        length.get_weights(weights_length);
70
71        // Get the dispersion points for the radius
72        vector<WeightPoint> weights_radius;
73        radius.get_weights(weights_radius);
74
75        // Perform the computation, with all weight points
76        double sum = 0.0;
77        double norm = 0.0;
78
79        // Loop over semi axis A weight points
80        for(int i=0; i< (int)weights_length.size(); i++) {
81                dp[1] = weights_length[i].value;
82
83                // Loop over semi axis B weight points
84                for(int j=0; j< (int)weights_radius.size(); j++) {
85                        dp[2] = weights_radius[j].value;
86
87                        sum += weights_length[i].weight
88                                * weights_radius[j].weight * FlexExclVolCyl(dp, q);
89                        norm += weights_length[i].weight
90                                        * weights_radius[j].weight;
91                }
92        }
93        return sum/norm + background();
94}
95
96/**
97 * Function to evaluate 2D scattering function
98 * @param q_x: value of Q along x
99 * @param q_y: value of Q along y
100 * @return: function value
101 */
102double FlexibleCylinderModel :: operator()(double qx, double qy) {
103        FlexibleCylinderParameters dp;
104        // Fill parameter array
105        dp.scale      = scale();
106        dp.length     = length();
107        dp.kuhn_length= kuhn_length();
108        dp.radius     = radius();
109        dp.contrast   = contrast();
110        dp.background = background();
111        dp.axis_theta  = axis_theta();
112        dp.axis_phi    = axis_phi();
113
114        // Get the dispersion points for the length
115        vector<WeightPoint> weights_length;
116        length.get_weights(weights_length);
117
118        // Get the dispersion points for the radius
119        vector<WeightPoint> weights_radius;
120        radius.get_weights(weights_radius);
121
122        // Get angular averaging for theta
123        vector<WeightPoint> weights_theta;
124        axis_theta.get_weights(weights_theta);
125
126        // Get angular averaging for phi
127        vector<WeightPoint> weights_phi;
128        axis_phi.get_weights(weights_phi);
129
130        // Perform the computation, with all weight points
131        double sum = 0.0;
132        double norm = 0.0;
133
134        // Loop over length weight points
135        for(int i=0; i< (int)weights_length.size(); i++) {
136                dp.length = weights_length[i].value;
137
138                // Loop over radius weight points
139                for(int j=0; j< (int)weights_radius.size(); j++) {
140                        dp.radius = weights_radius[j].value;
141
142                                // Average over theta distribution
143                                for(int k=0; k< (int)weights_theta.size(); k++) {
144                                        dp.axis_theta = weights_theta[k].value;
145
146                                        // Average over phi distribution
147                                        for(int l=0; l <(int)weights_phi.size(); l++) {
148                                                dp.axis_phi = weights_phi[l].value;
149
150                                                double _ptvalue = weights_length[i].weight
151                                                        * weights_radius[j].weight
152                                                        * weights_theta[k].weight
153                                                        * weights_phi[l].weight
154                                                        * flexible_cylinder_analytical_2DXY(&dp, qx, qy);
155                                                if (weights_theta.size()>1) {
156                                                        _ptvalue *= sin(weights_theta[k].value);
157                                                }
158                                                sum += _ptvalue;
159
160                                                norm += weights_length[i].weight
161                                                        * weights_radius[j].weight
162                                                        * weights_theta[k].weight
163                                                        * weights_phi[l].weight;
164                                }
165                        }
166                }
167        }
168        // Averaging in theta needs an extra normalization
169        // factor to account for the sin(theta) term in the
170        // integration (see documentation).
171        if (weights_theta.size()>1) norm = norm / asin(1.0);
172        return sum/norm + background();
173}
174
175/**
176 * Function to evaluate 2D scattering function
177 * @param pars: parameters of the triaxial ellipsoid
178 * @param q: q-value
179 * @param phi: angle phi
180 * @return: function value
181 */
182double FlexibleCylinderModel :: evaluate_rphi(double q, double phi) {
183        double qx = q*cos(phi);
184        double qy = q*sin(phi);
185        return (*this).operator()(qx, qy);
186}
Note: See TracBrowser for help on using the repository browser.