/******************************************************************************* * McXtrace, X-ray tracing package * Copyright, All rights reserved * Risoe National Laboratory, Roskilde, Denmark * Institut Laue Langevin, Grenoble, France * * Component: SAXSCylinders * * %I * Written by: Martin Cramer Pedersen (mcpe@nbi.dk) * Date: May 2, 2012 * Version: $Revision$ * Origin: KU-Science * * A sample of monodisperse cylindrical particles in solution. * * %D * A component simulating the scattering from a box-shaped, thin solution * of monodisperse, cylindrical particles. * * %P * R ; [AA] Semiaxis of the cross section of the * cylinder. * Height : [AA] Height of the cylinder. * Concentration : [mM] Concentration of sample. * DeltaRho : [cm/AA^3] Excess scattering length density of the * particles. * AbsorptionCrosssection : [1/m] Absorption cross section of the sample. * xwidth : [m] Dimension of component in the x-direction. * yheight : [m] Dimension of component in the y-direction. * zdepth : [m] Dimension of component in the z-direction. * SampleToDetectorDistance : [m] Distance from sample to detector (for * focusing the scattered x-rays). * DetectorRadius : [m] Radius of the detector (for focusing the * scattered x-rays). * * %E *******************************************************************************/ DEFINE COMPONENT SAXSCylinders DEFINITION PARAMETERS () SETTING PARAMETERS (R = 40.0, Height = 100.0, Concentration = 0.01, DeltaRho = 1.0e-14, AbsorptionCrosssection = 0.0, xwidth, yheight, zdepth, SampleToDetectorDistance, DetectorRadius) OUTPUT PARAMETERS () /*X-ray Parameters (x, y, z, kx, ky, kz, phi, t, Ex, Ey, Ez, p)*/ DECLARE %{ // Declarations double Prefactor; double Absorption; double q; double NumberDensity; %} INITIALIZE %{ // Rescale concentration into number of aggregates per m^3 times 10^-4 NumberDensity = Concentration * 6.02214129e19; // Computations if (!xwidth || !yheight || !zdepth) { printf("%s: Sample has no volume, check parameters!\n", NAME_CURRENT_COMP); } Prefactor = NumberDensity * pow(PI * Height * pow(R, 2), 2) * pow(DeltaRho, 2); Absorption = AbsorptionCrosssection; %} TRACE %{ // Declarations double l0; double l1; double l_full; double l; double l_1; double Formfactor1; double Formfactor2; double Intensity; double SolidAngle; double qx; double qy; double qz; double k; double dl; double kx_i; double ky_i; double kz_i; char Intersect = 0; // variables needed for integration over alpha int i; const int NumberOfSteps = 30; double Alpha; const double AlphaMin = 0; const double AlphaMax = PI / 2.0; const double AlphaStep = (AlphaMax - AlphaMin) / (1.0 * NumberOfSteps); // Computation Intersect = box_intersect(&l0, &l1, x, y, z, kx, ky, kz, xwidth, yheight, zdepth); if (Intersect) { if (l0 < 0.0) { fprintf(stderr, "Photon already inside sample %s - absorbing...\n", NAME_CURRENT_COMP); ABSORB; } // Compute properties of photon k = sqrt(pow(kx, 2) + pow(ky, 2) + pow(kz, 2)); l_full = l1 - l0; dl = rand01() * (l1 - l0) + l0; PROP_DL(dl); l = dl - l0; // Store properties of incoming photon kx_i = kx; ky_i = ky; kz_i = kz; // Generate new direction of photon randvec_target_circle(&kx, &ky, &kz, &SolidAngle, 0, 0, SampleToDetectorDistance, DetectorRadius); NORM(kx, ky, kz); kx *= k; ky *= k; kz *= k; // Compute q qx = kx_i - kx; qy = ky_i - ky; qz = kz_i - kz; q = sqrt(pow(qx, 2) + pow(qy, 2) + pow(qz, 2)); // Compute scattering Intensity = 0.0; for (i = 0; i < NumberOfSteps; ++i) { Alpha = (i + 0.5) * AlphaStep; Formfactor1 = j1(q * R * sin(Alpha)) / (q * R * sin(Alpha)); Formfactor2 = sin(q * Height * cos(Alpha) / 2.0) / (q * Height * cos(Alpha) / 2.0); Intensity += sin(Alpha) * Prefactor * pow(2 * Formfactor1 * Formfactor2, 2) * AlphaStep; } p *= l_full * SolidAngle / (4.0 * PI) * Intensity * exp(- Absorption * (l + l1)); SCATTER; } %} MCDISPLAY %{ box(0, 0, 0, xwidth, yheight, zdepth); %} END