Skip to content
Snippets Groups Projects
Commit dddbef1c authored by Martyn Gigg's avatar Martyn Gigg
Browse files

Add attenuation method to Material class

Refs #25957
parent 53b5f223
No related branches found
No related tags found
No related merge requests found
......@@ -18,21 +18,6 @@ using Kernel::V3D;
namespace Algorithms {
namespace {
/**
* Compute the attenuation factor for the given coefficients
* @param rho Number density of the sample in \f$\\A^{-3}\f$
* @param sigma Cross-section in barns
* @param length Path length in metres
* @return The dimensionless attenuated fraction
*/
double attenuation(double rho, double sigma, double length) {
using std::exp;
return exp(-100 * rho * sigma * length);
}
} // namespace
/**
* Construct the volume encompassing the sample + any environment kit. The
* beam profile defines a bounding region for the sampling of the scattering
......@@ -119,11 +104,7 @@ double MCInteractionVolume::calculateAbsorption(
for (const auto &segment : path) {
const double length = segment.distInsideObject;
const auto &segObj = *(segment.object);
const auto &segMat = segObj.material();
factor *= attenuation(segMat.numberDensity(),
segMat.totalScatterXSection(lambda) +
segMat.absorbXSection(lambda),
length);
factor *= segObj.material().attenuation(length, lambda);
}
return factor;
};
......
......@@ -103,6 +103,10 @@ public:
double
absorbXSection(const double lambda =
PhysicalConstants::NeutronAtom::ReferenceLambda) const;
/// Compute the attenuation at a given wavelegnth over the given distance
double attenuation(const double distance,
const double lambda =
PhysicalConstants::NeutronAtom::ReferenceLambda) const;
/**
* Returns the linear coefficient of absorption for the material in units of
......
......@@ -243,11 +243,21 @@ double Material::absorbXSection(const double lambda) const {
}
}
/**
* @param distance Distance (m) travelled
* @param lambda Wavelength (Angstroms) to compute the attenuation (default =
* reference lambda)
* @return The dimensionless attenuation coefficient
*/
double Material::attenuation(const double distance, const double lambda) const {
return exp(-100 * numberDensity() *
(totalScatterXSection() + absorbXSection(lambda)) * distance);
}
// NOTE: the angstrom^-2 to barns and the angstrom^-1 to cm^-1
// will cancel for mu to give units: cm^-1
double Material::linearAbsorpCoef(const double lambda) const {
return absorbXSection(NeutronAtom::ReferenceLambda) * 100. * numberDensity() *
lambda / NeutronAtom::ReferenceLambda;
return absorbXSection(lambda) * 100. * numberDensity();
}
// This must match the values that come from the scalar version
......
......@@ -85,6 +85,8 @@ public:
TS_ASSERT_DELTA(material.incohScatterXSection(lambda),
material.incohScatterXSection(), 1e-04);
TS_ASSERT_DELTA(material.absorbXSection(lambda), 5.93, 1e-02);
const double distance(0.05);
TS_ASSERT_DELTA(material.attenuation(distance, lambda), 0.01884, 1e-4);
}
// highly absorbing material
......@@ -124,6 +126,8 @@ public:
const double totXS = TiZr.totalScatterXSection();
TS_ASSERT_DELTA(TiZr.totalScatterLengthSqrd(), 25. * totXS / M_PI, 1.e-4);
const double distance(0.05);
TS_ASSERT_DELTA(TiZr.attenuation(distance), 0., 1e-4);
}
/** Save then re-load from a NXS file */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment