23constexpr auto LARGE_LAMBDA = 100;
31 : m_name(), m_formula(), m_atomicNo(), m_massNo(0), m_numberDensity(), m_packingFraction(), m_zParam(), m_cellVol(),
32 m_massDensity(), m_totalXSection(), m_cohXSection(), m_incXSection(), m_absSection(),
42 throw std::invalid_argument(
"MaterialBuilder::setName() - Empty name not allowed.");
59 throw std::runtime_error(
"MaterialBuilder::setFormula() - Atomic no. "
60 "already set, cannot use formula aswell.");
62 if (formula.empty()) {
63 throw std::invalid_argument(
"MaterialBuilder::setFormula() - Empty formula provided.");
68 }
catch (std::runtime_error &exc) {
69 throw std::invalid_argument(
"MaterialBuilder::setFormula() - Unable to parse chemical formula: " +
70 std::string(exc.what()));
82 throw std::runtime_error(
"MaterialBuilder::setAtomicNumber() - Formula "
83 "already set, cannot use atomic number aswell.");
220 if (!filename.empty()) {
232 if (!filename.empty()) {
256 throw std::runtime_error(
"Please specify one of chemical formula or atomic "
257 "number or all cross sections and a number "
263 std::unique_ptr<Material> material;
267 std::make_unique<Material>(
m_name, neutron, density_struct.number_density, density_struct.packing_fraction);
270 std::make_unique<Material>(
m_name, formula, density_struct.number_density, density_struct.packing_fraction);
274 material.get(), LARGE_LAMBDA);
275 material->setAttenuationProfile(materialAttenuation);
282 material->setXRayAttenuationProfile(materialAttenuation);
296 formula.emplace_back(unit);
320 const double totalNumAtoms =
321 std::accumulate(formula.cbegin(), formula.cend(), 0.,
332 }
else if (!formula.empty() && formula.size() == 1) {
333 result.number_density = formula.front().atom->number_density;
340 std::accumulate(formula.cbegin(), formula.cend(), 0.,
347 if (result.packing_fraction > 0.)
349 if (result.effective_number_density > 0.)
351 if (result.number_density > 0.)
356 throw std::runtime_error(
"The number density could not be determined. Please "
357 "provide the number density, ZParameter and unit "
358 "cell volume or mass density.");
359 }
else if (
count == 1) {
360 result.packing_fraction = 1.;
361 if (result.number_density > 0.)
362 result.effective_number_density = result.number_density;
363 else if (result.effective_number_density > 0.)
364 result.number_density = result.effective_number_density;
366 throw std::runtime_error(
"Must specify the number density in some way");
367 }
else if (
count == 2) {
368 if (result.number_density > 0.) {
369 if (result.effective_number_density > 0.)
370 result.packing_fraction = result.effective_number_density / result.number_density;
371 else if (result.packing_fraction > 0.)
372 result.effective_number_density = result.packing_fraction * result.number_density;
373 }
else if (result.effective_number_density > 0.) {
374 if (result.number_density > 0.)
375 result.packing_fraction = result.effective_number_density / result.number_density;
376 else if (result.packing_fraction > 0.)
377 result.number_density = result.effective_number_density / result.packing_fraction;
380 }
else if (
count == 3) {
381 throw std::runtime_error(
"The number density and effective density were over-determined");
392 NeutronAtom neutronAtom(0, 0., 0., 0., 0., 0., 0.);
396 auto atom = getAtom(
static_cast<uint16_t
>(
m_atomicNo.get()),
static_cast<uint16_t
>(
m_massNo));
397 neutronAtom = atom.neutron;
400 double totalNumAtoms = 0.;
401 for (
const auto &formulaUnit :
m_formula) {
402 neutronAtom = neutronAtom + formulaUnit.multiplicity * formulaUnit.atom->neutron;
403 totalNumAtoms += formulaUnit.multiplicity;
405 neutronAtom = (1. / totalNumAtoms) * neutronAtom;
412 calculateScatteringLengths(neutronAtom);
double value
The value of the point.
Create a material from a set of user defined options.
boost::optional< int > m_atomicNo
Material::ChemicalFormula m_formula
MaterialBuilder & setMassDensity(double massDensity)
Set the mass density of the sample in g / cc.
bool hasOverrideNeutronProperties() const
MaterialBuilder & setAttenuationProfileFilename(std::string filename)
Set a value for the attenuation profile filename.
Material build() const
Build the new Material object from the current set of options.
MaterialBuilder & setEffectiveNumberDensity(double rho_eff)
Set the effective number density of the sample in atoms or formula units / Angstrom^3.
MaterialBuilder & setName(const std::string &name)
Set the string name given to the material.
void overrideNeutronProperties(PhysicalConstants::NeutronAtom &neutron) const
Override default neutron properties with those supplied.
boost::optional< double > m_incXSection
boost::optional< double > m_cellVol
MaterialBuilder()
Constructor.
boost::optional< double > m_totalXSection
MaterialBuilder & setMassNumber(int massNumber)
Set the isotope by mass number.
MaterialBuilder & setFormula(const std::string &formula)
Set the chemical formula of the material.
boost::optional< double > m_zParam
boost::optional< double > m_packingFraction
boost::optional< double > m_massDensity
MaterialBuilder & setZParameter(double zparam)
Set the number of formula units in the unit cell.
MaterialBuilder & setPackingFraction(double fraction)
Set the packing fraction of the material (default is 1).
MaterialBuilder & setTotalScatterXSection(double xsec)
Set a value for the total scattering cross section.
boost::optional< double > m_absSection
MaterialBuilder & setUnitCellVolume(double cellVolume)
Set the volume of unit cell.
Material::ChemicalFormula createCompositionFromAtomicNumber() const
Create the NeutronAtom object from the atomic number.
MaterialBuilder & setAbsorptionXSection(double xsec)
Set a value for the absorption cross section.
density_packing getOrCalculateRhoAndPacking(const Material::ChemicalFormula &formula) const
Return the manually set density or calculate it from other parameters.
void setAttenuationSearchPath(std::string path)
Set a value for the attenuation profile search path.
PhysicalConstants::NeutronAtom generateCustomNeutron() const
std::string m_attenuationFileSearchPath
boost::optional< double > m_cohXSection
NumberDensityUnit m_numberDensityUnit
MaterialBuilder & setNumberDensityUnit(NumberDensityUnit unit)
Set the unit for number density.
MaterialBuilder & setCoherentXSection(double xsec)
Set a value for the coherent scattering cross section.
MaterialBuilder & setIncoherentXSection(double xsec)
Set a value for the incoherent scattering cross section.
boost::optional< std::string > m_attenuationProfileFileName
boost::optional< std::string > m_xRayAttenuationProfileFileName
boost::optional< double > m_numberDensity
boost::optional< double > m_numberDensityEff
MaterialBuilder & setNumberDensity(double rho)
Set the number density of the sample in atoms or formula units / Angstrom^3.
MaterialBuilder & setAtomicNumber(int atomicNumber)
Set the type of atom by its atomic number.
MaterialBuilder & setXRayAttenuationProfileFilename(std::string filename)
Set a value for the attenuation profile filename.
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
std::vector< FormulaUnit > ChemicalFormula
static ChemicalFormula parseChemicalFormula(const std::string &chemicalSymbol)
Struture to hold the common information for an atom.
MANTID_KERNEL_DLL int isEmpty(const std::string &A)
Determines if a string is only spaces.
MANTID_KERNEL_DLL const Atom & getAtom(const uint16_t z_number, const uint16_t a_number=0)
static constexpr double N_A
Avagodro constant in mol-1.
Helper class which provides the Collimation Length for SANS instruments.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Structure to store neutronic scattering information for the various elements.
uint16_t z_number
The atomic number, or number of protons, for the atom.
double inc_scatt_xs
The incoherent scattering cross section in barns.
double tot_scatt_xs
The total scattering cross section in barns.
double abs_scatt_xs
The absorption cross section for 2200m/s neutrons in barns.
double coh_scatt_xs
The coherent scattering cross section in barns.
uint16_t a_number
The total number of protons and neutrons, or mass number, for the atom for isotopic averages this is ...