Changeset 318b5bbb in sasview for sansmodels/src/c_models/libfunc.c


Ignore:
Timestamp:
Dec 18, 2012 10:55:24 AM (12 years ago)
Author:
Jae Cho <jhjcho@…>
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:
6550b64
Parents:
0203ade
Message:

Added polarization and magnetic stuffs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/c_models/libfunc.c

    r5da3cc5 r318b5bbb  
    103103    return -tmp+log(2.5066282746310005*ser/x); 
    104104} 
     105 
     106// calculate magnetic sld and return total sld 
     107// bn : contrast (not just sld of the layer) 
     108// m0: max mag of M; mtheta: angle from x-z plane; 
     109// mphi: angle (anti-clock-wise)of x-z projection(M) from x axis 
     110// spinfraci: the fraction of UP among UP+Down (before sample) 
     111// spinfracf: the fraction of UP among UP+Down (after sample and before detector) 
     112// spintheta: angle (anti-clock-wise) between neutron spin(up) and x axis 
     113// Note: all angles are in degrees. 
     114polar_sld cal_msld(int isangle, double qx, double qy, double bn, 
     115                                double m01, double mtheta1, double mphi1, 
     116                                double spinfraci, double spinfracf, double spintheta) 
     117{ 
     118        //locals 
     119        double q_x = qx; 
     120        double q_y = qy; 
     121        double sld = bn; 
     122        int is_angle = isangle; 
     123        double pi = 4.0*atan(1.0); 
     124        double s_theta = spintheta * pi/180.0; 
     125        double m_max = m01; 
     126        double m_phi = mphi1; 
     127        double m_theta = mtheta1; 
     128        double in_spin = spinfraci; 
     129        double out_spin = spinfracf; 
     130 
     131        double m_perp = 0.0; 
     132        double m_perp_z = 0.0; 
     133        double m_perp_y = 0.0; 
     134        double m_perp_x = 0.0; 
     135        double m_sigma_x = 0.0; 
     136        double m_sigma_z = 0.0; 
     137        double m_sigma_y = 0.0; 
     138        double b_m = 0.0; 
     139        double q_angle = 0.0; 
     140        double mx = 0.0; 
     141        double my = 0.0; 
     142        double mz = 0.0; 
     143        polar_sld p_sld; 
     144        p_sld.uu = sld; 
     145        p_sld.dd = sld; 
     146        p_sld.re_ud = 0.0; 
     147        p_sld.im_ud = 0.0; 
     148        p_sld.re_du = 0.0; 
     149        p_sld.im_du = 0.0; 
     150 
     151        //No mag means no further calculation 
     152        if (isangle>0){ 
     153                if (m_max < 1.0e-32){ 
     154                        p_sld.uu = sqrt(sqrt(in_spin * out_spin)) * p_sld.uu; 
     155                        p_sld.dd = sqrt(sqrt((1.0 - in_spin) * (1.0 - out_spin))) * p_sld.dd; 
     156                        return p_sld; 
     157                } 
     158        } 
     159        else{ 
     160                if (fabs(m_max)< 1.0e-32 && fabs(m_phi)< 1.0e-32 && fabs(m_theta)< 1.0e-32){ 
     161                        p_sld.uu = sqrt(sqrt(in_spin * out_spin)) * p_sld.uu; 
     162                        p_sld.dd = sqrt(sqrt((1.0 - in_spin) * (1.0 - out_spin))) * p_sld.dd; 
     163                        return p_sld; 
     164                } 
     165        } 
     166 
     167        //These are needed because of the precision of inputs 
     168        if (in_spin < 0.0) in_spin = 0.0; 
     169        if (in_spin > 1.0) in_spin = 1.0; 
     170        if (out_spin < 0.0) out_spin = 0.0; 
     171        if (out_spin > 1.0) out_spin = 1.0; 
     172 
     173        if (q_x == 0.0) q_angle = pi / 2.0; 
     174        else q_angle = atan(q_y/q_x); 
     175        if (q_y < 0.0 && q_x < 0.0) q_angle -= pi; 
     176        else if (q_y > 0.0 && q_x < 0.0) q_angle += pi; 
     177 
     178        q_angle = pi/2.0 - q_angle; 
     179        if (q_angle > pi) q_angle -= 2.0 * pi; 
     180        else if (q_angle < -pi) q_angle += 2.0 * pi; 
     181 
     182        if (fabs(q_x) < 1.0e-16 && fabs(q_y) < 1.0e-16){ 
     183                m_perp = 0.0; 
     184                } 
     185        else { 
     186                m_perp = m_max; 
     187                } 
     188        if (is_angle > 0){ 
     189                m_phi *= pi/180.0; 
     190                m_theta *= pi/180.0; 
     191                mx = m_perp * cos(m_theta) * cos(m_phi); 
     192                my = m_perp * sin(m_theta); 
     193                mz = -(m_perp * cos(m_theta) * sin(m_phi)); 
     194        } 
     195        else{ 
     196                mx = m_perp; 
     197                my = m_phi; 
     198                mz = m_theta; 
     199        } 
     200        //ToDo: simplify these steps 
     201        // m_perp1 -m_perp2 
     202        m_perp_x = (mx) *  cos(q_angle); 
     203        m_perp_x -= (my) * sin(q_angle); 
     204        m_perp_y = m_perp_x; 
     205        m_perp_x *= cos(-q_angle); 
     206        m_perp_y *= sin(-q_angle); 
     207        m_perp_z = mz; 
     208 
     209        m_sigma_x = (m_perp_x * cos(-s_theta) - m_perp_y * sin(-s_theta)); 
     210        m_sigma_y = (m_perp_x * sin(-s_theta) + m_perp_y * cos(-s_theta)); 
     211        m_sigma_z = (m_perp_z); 
     212 
     213        //Find b 
     214        p_sld.uu -= m_sigma_x; 
     215        p_sld.dd += m_sigma_x; 
     216        p_sld.re_ud = m_sigma_y; 
     217        p_sld.re_du = m_sigma_y; 
     218        p_sld.im_ud = m_sigma_z; 
     219        p_sld.im_du = -m_sigma_z; 
     220 
     221        p_sld.uu = sqrt(sqrt(in_spin * out_spin)) * p_sld.uu; 
     222        p_sld.dd = sqrt(sqrt((1.0 - in_spin) * (1.0 - out_spin))) * p_sld.dd; 
     223 
     224        p_sld.re_ud = sqrt(sqrt(in_spin * (1.0 - out_spin))) * p_sld.re_ud; 
     225        p_sld.im_ud = sqrt(sqrt(in_spin * (1.0 - out_spin))) * p_sld.im_ud; 
     226        p_sld.re_du = sqrt(sqrt((1.0 - in_spin) * out_spin)) * p_sld.re_du; 
     227        p_sld.im_du = sqrt(sqrt((1.0 - in_spin) * out_spin)) * p_sld.im_du; 
     228 
     229        return p_sld; 
     230} 
     231 
    105232 
    106233/** Modifications below by kieranrcampbell@gmail.com 
     
    131258    ap = a; 
    132259    del = sum = 1.0/a; 
    133      
     260 
    134261    for(n=1;n<=ITMAX;n++) { 
    135262      ++ap; 
     
    150277 
    151278/** 
    152    Implements the incomplete gamma function Q(a,x) evaluated by its continued fraction  
    153    representation  
     279   Implements the incomplete gamma function Q(a,x) evaluated by its continued fraction 
     280   representation 
    154281**/ 
    155282 
     
    196323} 
    197324 
    198 /**  
     325/** 
    199326    Implementation of the error function, erf(x) 
    200327**/ 
Note: See TracChangeset for help on using the changeset viewer.