double form_volume(double length_a, double length_b, double length_c, double thick_rim_a, double thick_rim_b, double thick_rim_c); double Iq(double q, double core_sld, double arim_sld, double brim_sld, double crim_sld, double solvent_sld, double length_a, double length_b, double length_c, double thick_rim_a, double thick_rim_b, double thick_rim_c); double Iqxy(double qx, double qy, double core_sld, double arim_sld, double brim_sld, double crim_sld, double solvent_sld, double length_a, double length_b, double length_c, double thick_rim_a, double thick_rim_b, double thick_rim_c, double theta, double phi, double psi); double form_volume(double length_a, double length_b, double length_c, double thick_rim_a, double thick_rim_b, double thick_rim_c) { //return length_a * length_b * length_c; return length_a * length_b * length_c + 2.0 * thick_rim_a * length_b * length_c + 2.0 * thick_rim_b * length_a * length_c + 2.0 * thick_rim_c * length_a * length_b; } double Iq(double q, double core_sld, double arim_sld, double brim_sld, double crim_sld, double solvent_sld, double length_a, double length_b, double length_c, double thick_rim_a, double thick_rim_b, double thick_rim_c) { // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c_scaled // Did not understand the code completely, it should be rechecked (Miguel Gonzalez) double t1, t2, t3, t4, tmp, answer; double mu = q * length_b; //calculate volume before rescaling (in original code, but not used) //double vol = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c); //double vol = length_a * length_b * length_c + // 2.0 * thick_rim_a * length_b * length_c + // 2.0 * thick_rim_b * length_a * length_c + // 2.0 * thick_rim_c * length_a * length_b; // Scale sides by B double a_scaled = length_a / length_b; double c_scaled = length_c / length_b; // DelRho values (note that drC is not used later) double dr0 = core_sld-solvent_sld; double drA = arim_sld-solvent_sld; double drB = brim_sld-solvent_sld; //double drC = crim_sld-solvent_sld; //Order of integration int nordi=76; int nordj=76; // outer integral (with nordi gauss points), integration limits = 0, 1 double summ = 0; //initialize integral for( int i=0; i1.0) { //printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n"); cos_val_c = 1.0; } if (fabs(cos_val_a)>1.0) { //printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n"); cos_val_a = 1.0; } if (fabs(cos_val_b)>1.0) { //printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n"); cos_val_b = 1.0; } // cspkernel in csparallelepiped recoded here double dr0 = core_sld-solvent_sld; double drA = arim_sld-solvent_sld; double drB = brim_sld-solvent_sld; double drC = crim_sld-solvent_sld; double Vin = length_a * length_b * length_c; // As for the 1D case, Vot is not used //double Vot = (length_a * length_b * length_c + // 2.0 * thick_rim_a * length_b * length_c + // 2.0 * length_a * thick_rim_b * length_c + // 2.0 * length_a * length_b * thick_rim_c); double V1 = (2.0 * thick_rim_a * length_b * length_c); // incorrect V1 (aa*bb*cc+2*ta*bb*cc) double V2 = (2.0 * length_a * thick_rim_b * length_c); // incorrect V2(aa*bb*cc+2*aa*tb*cc) double V3 = (2.0 * length_a * length_b * thick_rim_c); // The definitions of ta, tb, tc are not the same as in the 1D case because there is no // the scaling by B. The use of length_a for the 3 of them seems clearly a mistake to me, // but for the moment I let it like this until understanding better the code. double ta = length_a + 2.0*thick_rim_a; double tb = length_a + 2.0*thick_rim_b; double tc = length_a + 2.0*thick_rim_c; //handle arg=0 separately, as sin(t)/t -> 1 as t->0 double argA = 0.5*q*length_a*cos_val_a; double argB = 0.5*q*length_b*cos_val_b; double argC = 0.5*q*length_c*cos_val_c; double argtA = 0.5*q*ta*cos_val_a; double argtB = 0.5*q*tb*cos_val_b; double argtC = 0.5*q*tc*cos_val_c; if(argA==0.0) { tmp1 = 1.0; } else { tmp1 = sin(argA)/argA; } if (argB==0.0) { tmp2 = 1.0; } else { tmp2 = sin(argB)/argB; } if (argC==0.0) { tmp3 = 1.0; } else { tmp3 = sin(argC)/argC; } if(argtA==0.0) { tmpt1 = 1.0; } else { tmpt1 = sin(argtA)/argtA; } if (argtB==0.0) { tmpt2 = 1.0; } else { tmpt2 = sin(argtB)/argtB; } if (argtC==0.0) { tmpt3 = 1.0; } else { tmpt3 = sin(argtC)*sin(argtC)/argtC/argtC; } // f uses Vin, V1, V2, and V3 and it seems to have more sense than the value computed // in the 1D code, but should be checked! double f = ( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1 + drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3); return 1.0e-4 * f * f; }