Changeset dbddbf5 in sasview for sansmodels/src/c_models


Ignore:
Timestamp:
Jan 4, 2012 5:43:34 PM (13 years ago)
Author:
Mathieu Doucet <doucetm@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
0c2389e
Parents:
d62f422
Message:

refactored cylinder model

Location:
sansmodels/src/c_models
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/c_models/cylinder.cpp

    r67424cd rdbddbf5  
    1818 *   sansmodels/src/libigor 
    1919 * 
    20  *      TODO: refactor so that we pull in the old sansmodels.c_extensions 
    2120 */ 
    2221 
    2322#include <math.h> 
    24 #include "models.hh" 
    2523#include "parameters.hh" 
    2624#include <stdio.h> 
     
    3230        #include "cylinder.h" 
    3331} 
     32 
     33// Convenience parameter structure 
     34typedef struct { 
     35    double scale; 
     36    double radius; 
     37    double length; 
     38    double sldCyl; 
     39    double sldSolv; 
     40    double background; 
     41    double cyl_theta; 
     42    double cyl_phi; 
     43} CylinderParameters; 
    3444 
    3545CylinderModel :: CylinderModel() { 
     
    101111 
    102112        return sum/norm + background(); 
     113} 
     114 
     115/** 
     116 * Function to evaluate 2D scattering function 
     117 * @param pars: parameters of the cylinder 
     118 * @param q: q-value 
     119 * @param q_x: q_x / q 
     120 * @param q_y: q_y / q 
     121 * @return: function value 
     122 */ 
     123static double cylinder_analytical_2D_scaled(CylinderParameters *pars, double q, double q_x, double q_y) { 
     124  double cyl_x, cyl_y, cyl_z; 
     125  double q_z; 
     126  double alpha, vol, cos_val; 
     127  double answer; 
     128  //convert angle degree to radian 
     129  double pi = 4.0*atan(1.0); 
     130  double theta = pars->cyl_theta * pi/180.0; 
     131  double phi = pars->cyl_phi * pi/180.0; 
     132 
     133    // Cylinder orientation 
     134    cyl_x = sin(theta) * cos(phi); 
     135    cyl_y = sin(theta) * sin(phi); 
     136    cyl_z = cos(theta); 
     137 
     138    // q vector 
     139    q_z = 0; 
     140 
     141    // Compute the angle btw vector q and the 
     142    // axis of the cylinder 
     143    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z; 
     144 
     145    // The following test should always pass 
     146    if (fabs(cos_val)>1.0) { 
     147      printf("cyl_ana_2D: Unexpected error: cos(alpha)>1\n"); 
     148      return 0; 
     149    } 
     150 
     151    // Note: cos(alpha) = 0 and 1 will get an 
     152    // undefined value from CylKernel 
     153  alpha = acos( cos_val ); 
     154 
     155  // Call the IGOR library function to get the kernel 
     156  answer = CylKernel(q, pars->radius, pars->length/2.0, alpha) / sin(alpha); 
     157 
     158  // Multiply by contrast^2 
     159  answer *= (pars->sldCyl - pars->sldSolv)*(pars->sldCyl - pars->sldSolv); 
     160 
     161  //normalize by cylinder volume 
     162  //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl 
     163    vol = acos(-1.0) * pars->radius * pars->radius * pars->length; 
     164  answer *= vol; 
     165 
     166  //convert to [cm-1] 
     167  answer *= 1.0e8; 
     168 
     169  //Scale 
     170  answer *= pars->scale; 
     171 
     172  // add in the background 
     173  answer += pars->background; 
     174 
     175  return answer; 
     176} 
     177 
     178/** 
     179 * Function to evaluate 2D scattering function 
     180 * @param pars: parameters of the cylinder 
     181 * @param q: q-value 
     182 * @return: function value 
     183 */ 
     184static double cylinder_analytical_2DXY(CylinderParameters *pars, double qx, double qy) { 
     185  double q; 
     186  q = sqrt(qx*qx+qy*qy); 
     187  return cylinder_analytical_2D_scaled(pars, q, qx/q, qy/q); 
    103188} 
    104189 
     
    254339        return rad_out; 
    255340} 
    256 // Testing code 
    257 int main(void) 
    258 { 
    259         CylinderModel c = CylinderModel(); 
    260  
    261         printf("Length = %g\n", c.length()); 
    262         printf("I(Qx=%g,Qy=%g) = %g\n", 0.001, 0.001, c(0.001, 0.001)); 
    263         printf("I(Q=%g) = %g\n", 0.001, c(0.001)); 
    264         c.radius.dispersion = new GaussianDispersion(); 
    265         c.radius.dispersion->npts = 100; 
    266         c.radius.dispersion->width = 5; 
    267  
    268         //c.length.dispersion = GaussianDispersion(); 
    269         //c.length.dispersion.npts = 20; 
    270         //c.length.dispersion.width = 65; 
    271  
    272         printf("I(Q=%g) = %g\n", 0.001, c(0.001)); 
    273         c.scale = 10.0; 
    274         printf("I(Q=%g) = %g\n", 0.001, c(0.001)); 
    275         printf("I(Qx=%g, Qy=%g) = %g\n", 0.001, 0.001, c(0.001, 0.001)); 
    276         printf("I(Q=%g,  Phi=%g) = %g\n", 0.00447, .7854, c.evaluate_rphi(sqrt(0.00002), .7854)); 
    277  
    278         // Average over phi at theta=90 deg 
    279         c.cyl_theta = 1.57; 
    280         double values_th[100]; 
    281         double values[100]; 
    282         double weights[100]; 
    283         double pi = acos(-1.0); 
    284         printf("pi=%g\n", pi); 
    285         for(int i=0; i<100; i++){ 
    286                 values[i] = (float)i*2.0*pi/99.0; 
    287                 values_th[i] = (float)i*pi/99.0; 
    288                 weights[i] = 1.0; 
    289         } 
    290         //c.radius.dispersion->width = 0; 
    291         c.cyl_phi.dispersion = new ArrayDispersion(); 
    292         c.cyl_theta.dispersion = new ArrayDispersion(); 
    293         (*c.cyl_phi.dispersion).set_weights(100, values, weights); 
    294         (*c.cyl_theta.dispersion).set_weights(100, values_th, weights); 
    295  
    296         double i_avg = c(0.01, 0.01); 
    297         double i_1d = c(sqrt(0.0002)); 
    298  
    299         printf("\nI(Qx=%g, Qy=%g) = %g\n", 0.01, 0.01, i_avg); 
    300         printf("I(Q=%g)         = %g\n", sqrt(0.0002), i_1d); 
    301         printf("ratio %g %g\n", i_avg/i_1d, i_1d/i_avg); 
    302  
    303  
    304         return 0; 
    305 } 
    306  
  • sansmodels/src/c_models/models.hh

    rf425805 rdbddbf5  
    2727using namespace std; 
    2828 
    29 class CylinderModel{ 
    30 public: 
    31         // Model parameters 
    32         Parameter radius; 
    33         Parameter scale; 
    34         Parameter length; 
    35         Parameter sldCyl; 
    36         Parameter sldSolv; 
    37         Parameter background; 
    38         Parameter cyl_theta; 
    39         Parameter cyl_phi; 
    40  
    41         // Constructor 
    42         CylinderModel(); 
    43  
    44         // Operators to get I(Q) 
    45         double operator()(double q); 
    46         double operator()(double qx, double qy); 
    47         double calculate_ER(); 
    48         double evaluate_rphi(double q, double phi); 
    49 }; 
    5029 
    5130class CappedCylinderModel{ 
Note: See TracChangeset for help on using the changeset viewer.