//****************************************************************************** //** SCATMECH: Polarized Light Scattering C++ Class Library //** //** File: axisym.cpp //** //** Thomas A. Germer //** Sensor Science Division, National Institute of Standards and Technology //** 100 Bureau Dr. Stop 8443; Gaithersburg, MD 20899-8443 //** Phone: (301) 975-2876 //** Email: thomas.germer@nist.gov //** //****************************************************************************** #include "scatmech.h" #include "axipart.h" #include "bobvlieg.h" #include "askuser.h" #include #include using namespace std; namespace SCATMECH { using namespace BobVlieg_Supp; Gauss_Legendre_Integration:: Gauss_Legendre_Integration(int order,double x1,double x2) { x.resize(order); w.resize(order); const double epsilon = 6.0e-16; int m=(order+1)/2; for (int i=0; i epsilon); x[i] = - (x[order-1-i] = z); w[i]= w[order-1-i]= 2.0/((1.0-z*z)*sqr(deriv)); } for (int j=0; jshape*cos(p->abs); if (z>zmax) { zmax = z; } } return zmax; } double Axisymmetric_Shape:: Get_Breast() { SETUP(); double xmax=0; for (shape_vec::const_iterator p=shape.begin(); p!=shape.end(); ++p) { double x = p->shape*sin(p->abs); if (x>xmax) { xmax = x; } } return xmax; } double Axisymmetric_Shape:: Get_MaxRadius() { SETUP(); if (shape.size()==0) return 0; double maxr = shape[0].shape; for (shape_vec::const_iterator p=shape.begin(); p!=shape.end(); ++p) { if (p->shape>maxr) maxr = p->shape; } return maxr; } void Axisymmetric_Shape:: Flip() { for (unsigned int i=0; i=0; --i) { double theta = 2.*pi-shape[i].abs; shapefile << theta/deg << tab << shape[i].shape << tab << -shape[i].dshape << tab << shape[i].shape*sin(theta) << tab << -shape[i].shape*cos(theta)+_length << tab << shape[i].wt << endl; } } void Ellipsoid_Axisymmetric_Shape:: setup() { Axisymmetric_Shape::setup(); if (vertical<=0 || horizontal<=0 || fabs(offset)>vertical) error("Parameters in out of range"); Insert_Points(0.,pi); } double Ellipsoid_Axisymmetric_Shape:: f(double theta) const { double costh=cos(theta); double sinth=sin(theta); return (horizontal*(-(horizontal*offset*costh) + vertical*sqrt(sqr(horizontal)*sqr(costh) + (sqr(vertical) - sqr(offset))*sqr(sinth))))/ (sqr(horizontal)*sqr(costh) + sqr(vertical)*sqr(sinth)); } double Ellipsoid_Axisymmetric_Shape:: df(double theta) const { double a = vertical; double b = horizontal; double d = offset; return (b*sin(theta)*(-(a*(pow(a,4.) - 3*pow(b,4.) + 5*sqr(b)*sqr(d) + sqr(a)*(2*sqr(b) - sqr(d)))*cos(theta)) + a*(sqr(a) - sqr(b))*(sqr(a) - sqr(b) - sqr(d))*cos(3*theta) - 2*b*d*(-3*sqr(a) + sqr(b) + (-sqr(a) + sqr(b))*cos(2*theta))* sqrt(sqr(b)*sqr(cos(theta)) + (sqr(a) - sqr(d))*sqr(sin(theta)))))/ (4.*sqr(sqr(b)*sqr(cos(theta)) + sqr(a)*sqr(sin(theta)))* sqrt(sqr(b)*sqr(cos(theta)) + (sqr(a) - sqr(d))*sqr(sin(theta))) ); } double Table_Axisymmetric_Shape:: f(double theta) const { double r = const_cast(table).value(theta/deg); if (scale>0) r*=scale; if (r<=0) error("radius <= 0"); return r; } void Table_Axisymmetric_Shape:: setup() { Axisymmetric_Shape::setup(); Insert_Points(0.,pi); if (scale<0) Renormalize(4.*pi*cube(scale)/3.); } void Conical_Axisymmetric_Shape:: setup() { Axisymmetric_Shape::setup(); z0 = height/3.-offset; beta = atan(radius/height); a0 = radius-corner_base*tan(beta)-corner_base/cos(beta); theta0 = atan2(a0,z0); theta1 = atan2(a0,(z0-corner_base)); theta2 = atan2((a0+corner_base*cos(beta)),(z0-corner_base-corner_base*sin(beta))); c0 = sqrt(sqr(a0)+sqr(z0-corner_base)); g = height-corner_apex/sin(beta)-z0; theta3 = pi - atan(corner_apex*cos(beta)/(g+corner_apex*sin(beta))); if (a0<0||g<0||theta0>theta1||theta1>theta2||theta2>theta3||offset>height/3.||offset<-2.*height/3.) error("Invalid parameters"); Insert_Points(0.,theta0); Insert_Points(theta0,theta2); Insert_Points(theta2,theta3); Insert_Points(theta3,pi); if (updown) Flip(); if (renorm) Renormalize(pi*radius*radius*height/3.); } double Conical_Axisymmetric_Shape:: f(double theta) const { if (thetapi/2.) theta = pi-theta; if (thetatheta0) { double theta1=atan(B/vertical); double sqrtantheta = sqr(tan(theta)); double a2 = sqr(vertical); double b2 = sqr(B); double c2 = sqr(indent); double sint = sin(theta); double cost = cos(theta); double d= (B*(B*indent*cost + vertical*sqrt(4*b2*sqr(cost) + (4*a2 - c2)*sqr(sint))))/ (2.*(b2*sqr(cost) + a2*sqr(sint))); return d; } else { return (vertical-indent/2)/cos(theta); } } void Indented_Ellipsoid_Axisymmetric_Shape:: setup() { Axisymmetric_Shape::setup(); B = (horizontal==0) ? vertical : horizontal; theta0 = atan(fabs((2.*B*sqrt(indent)*sqrt(2. - indent/vertical))/(sqrt(vertical)*(-2.*vertical + indent)))); Insert_Points(0.,theta0); Insert_Points(theta0,pi); if (updown) Flip(); if (renorm) Renormalize(4.*pi/3.*vertical*B*B); } void Cylinder_Axisymmetric_Shape:: setup() { Axisymmetric_Shape::setup(); theta0 = atan2(2.*(radius-corner),length); theta1 = atan2((radius-corner),(length/2.-corner)); theta2 = atan2(radius,(length/2.-corner)); c = sqrt(sqr(length/2.-corner)+sqr(radius-corner)); if (corner>radius||corner>(length/2.)||corner<0||radius<0||length<0||theta0>theta1 || theta1>theta2) error("Invalid parameters"); Insert_Points(0.,theta0); Insert_Points(theta0,theta2); Insert_Points(theta2,pi-theta2); Insert_Points(pi-theta2,pi-theta0); Insert_Points(pi-theta0,pi); if (renorm) Renormalize(pi*radius*radius*length); } double Cylinder_Axisymmetric_Shape:: f(double theta) const { if (theta>pi/2.) theta = pi-theta; if (thetapi/2.) { otherside=true; theta = pi-theta; } if (theta