Mantid
Loading...
Searching...
No Matches
ReadMaterial.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2009 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#include <utility>
8
12
13namespace Mantid::DataHandling {
14
23 ValidationErrors result;
24 const bool chemicalSymbol{!params.chemicalSymbol.empty()};
25 const bool atomicNumber{params.atomicNumber != 0};
26 if (!chemicalSymbol && !atomicNumber) {
27 if (isEmpty(params.coherentXSection)) {
28 result["CoherentXSection"] = "The cross section must be specified when "
29 "no ChemicalFormula or AtomicNumber is "
30 "given.";
31 }
32 if (isEmpty(params.incoherentXSection)) {
33 result["IncoherentXSection"] = "The cross section must be specified when "
34 "no ChemicalFormula or AtomicNumber is "
35 "given.";
36 }
37 if (isEmpty(params.attenuationXSection) && params.attenuationProfileFileName.empty()) {
38 result["AttenuationXSection"] = "The cross section must be specified "
39 "when no ChemicalFormula or AtomicNumber "
40 "is given.";
41 }
42 if (isEmpty(params.scatteringXSection)) {
43 result["ScatteringXSection"] = "The cross section must be specified when "
44 "no ChemicalFormula or AtomicNumber is "
45 "given.";
46 }
48 isEmpty(params.zParameter) && isEmpty(params.unitCellVolume)) {
49 result["NumberDensity"] = "The number density or effective number density or Z Parameter\\Unit Cell Volume must "
50 " be specified with a user-defined material";
51 }
52
53 } else if (chemicalSymbol && atomicNumber) {
54 result["AtomicNumber"] = "Cannot specify both ChemicalFormula and AtomicNumber";
55 }
56
57 if (!isEmpty(params.numberDensity) && !isEmpty(params.numberDensityEffective) && !isEmpty(params.packingFraction)) {
58 result["NumberDensity"] = "Number Density cannot be determined when "
59 "both the effective number density and "
60 "packing fraction are set. Only two can "
61 "be specified at most.";
62 }
63
64 // If these are all set, then number density and eff. number density can be
65 // calculated. In this case, make sure the packing frac isn't set
66 if (!isEmpty(params.massDensity) && !isEmpty(params.zParameter) && !isEmpty(params.unitCellVolume)) {
67 if (!isEmpty(params.packingFraction)) {
68 result["PackingFraction"] = "Cannot set packing fraction when both the number density "
69 "and effective number density are determined from "
70 "the mass density and cell volume + zParameter.";
71 }
72 }
73
74 // Effective num density will be overwritten in MaterialBuilder if mass
75 // density is set
76 if (!isEmpty(params.massDensity)) {
77 if (!isEmpty(params.numberDensityEffective)) {
78 result["EffectiveNumberDensity"] = "Cannot set effective number density when the mass density "
79 "is specified. The value specified will be overwritten "
80 "because it will be computed from the mass density.";
81 }
82 }
83
84 // Bounds check the packing fraction number [0, 2)
85 if (!isEmpty(params.packingFraction)) {
86 if (params.packingFraction >= 2.0) {
87 result["PackingFraction"] = "Cannot have a packing fraction larger than 2";
88 } else if (params.packingFraction < 0.0) {
89 result["PackingFraction"] = "Cannot have a packing fraction less than 0";
90 }
91 }
92
93 if (params.massNumber > 0 && params.atomicNumber <= 0)
94 result["AtomicNumber"] = "Specified MassNumber without AtomicNumber";
95
96 if (!isEmpty(params.zParameter)) {
97 if (isEmpty(params.unitCellVolume)) {
98 result["UnitCellVolume"] = "UnitCellVolume must be provided with ZParameter";
99 }
100 }
101 return result;
102}
103
111 setMaterial(params.chemicalSymbol, params.atomicNumber, params.massNumber);
112
113 // calculate the mass density if it wasn't provided
114 double massDensity = params.massDensity;
115 if (isEmpty(massDensity)) {
116 if (!(isEmpty(params.mass) || isEmpty(params.volume)))
117 massDensity = params.mass / params.volume;
118 }
119
120 setNumberDensity(massDensity, params.numberDensity, params.numberDensityEffective, params.packingFraction,
121 params.numberDensityUnit, params.zParameter, params.unitCellVolume);
125}
126
132std::unique_ptr<Kernel::Material> ReadMaterial::buildMaterial() {
133 return std::make_unique<Kernel::Material>(builder.build());
134}
135
136void ReadMaterial::setMaterial(const std::string &chemicalSymbol, const int atomicNumber, const int massNumber) {
137 if (!chemicalSymbol.empty()) {
138 builder.setFormula(chemicalSymbol);
139 } else if (atomicNumber != 0) {
140 builder.setAtomicNumber(atomicNumber);
141 builder.setMassNumber(massNumber);
142 }
143}
144
145void ReadMaterial::setNumberDensity(const double rho_m, const double rho, const double rho_eff, const double pFrac,
146 Kernel::MaterialBuilder::NumberDensityUnit rhoUnit, const double zParameter,
147 const double unitCellVolume) {
148 if (!isEmpty(rho_m))
149 builder.setMassDensity(rho_m);
150
151 // These can be specified even if mass density set
152 if (!isEmpty(zParameter)) {
153 builder.setZParameter(zParameter);
154 builder.setUnitCellVolume(unitCellVolume);
155 }
156 if (!isEmpty(rho)) {
159 }
160 if (!isEmpty(rho_eff)) {
162 }
163 if (!isEmpty(pFrac)) {
165 }
166}
167
168void ReadMaterial::setScatteringInfo(double coherentXSection, double incoherentXSection, double attenuationXSection,
169 double scatteringXSection, std::string attenuationProfileFileName,
170 std::string xRayAttenuationProfileFileName) {
171 builder.setCoherentXSection(coherentXSection); // in barns
172 builder.setIncoherentXSection(incoherentXSection); // in barns
173 builder.setAbsorptionXSection(attenuationXSection); // in barns
174 builder.setTotalScatterXSection(scatteringXSection); // in barns
175 builder.setAttenuationProfileFilename(std::move(attenuationProfileFileName));
176 builder.setXRayAttenuationProfileFilename(std::move(xRayAttenuationProfileFileName));
177}
178
179bool ReadMaterial::isEmpty(const double toCheck) { return std::abs((toCheck - EMPTY_DBL()) / (EMPTY_DBL())) < 1e-8; }
180} // namespace Mantid::DataHandling
std::unique_ptr< Kernel::Material > buildMaterial()
Construct the material,.
void setNumberDensity(const double rho_m, const double rho, const double rho_eff, const double pFrac, const Kernel::MaterialBuilder::NumberDensityUnit rhoUnit, const double zParameter, const double unitCellVolume)
void setMaterial(const std::string &chemicalSymbol, const int atomicNumber, const int massNumber)
void setScatteringInfo(double coherentXSection, double incoherentXSection, double attenuationXSection, double scatteringXSection, std::string attenuationProfileFileName, std::string xRayAttenuationProfileFileName)
void setMaterialParameters(const MaterialParameters &params)
Set the parameters to build the material to the builder, taking into account which values were and we...
static ValidationErrors validateInputs(const MaterialParameters &params)
Validate the parameters to build the material from, this returns any errors in the inputs.
static bool isEmpty(const double toCheck)
Kernel::MaterialBuilder builder
The builder used to construct the material.
Definition: ReadMaterial.h:97
MaterialBuilder & setMassDensity(double massDensity)
Set the mass density of the sample in g / cc.
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 & setMassNumber(int massNumber)
Set the isotope by mass number.
MaterialBuilder & setFormula(const std::string &formula)
Set the chemical formula of the material.
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.
MaterialBuilder & setUnitCellVolume(double cellVolume)
Set the volume of unit cell.
MaterialBuilder & setAbsorptionXSection(double xsec)
Set a value for the absorption cross section.
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.
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.
std::map< std::string, std::string > ValidationErrors
Definition: ReadMaterial.h:18
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
This struct contains the parameters for constructing a material, and gives them a default value for e...
Definition: ReadMaterial.h:32
double numberDensity
The sample number density to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:40
double coherentXSection
The coherent scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:56
int massNumber
The mass number to set, defaults to 0.
Definition: ReadMaterial.h:38
double mass
The sample mass to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:52
double packingFraction
The sample packing fraction.
Definition: ReadMaterial.h:44
double attenuationXSection
The absorption cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:60
Kernel::MaterialBuilder::NumberDensityUnit numberDensityUnit
A flag indicating the unit of sampleNumberDensity.
Definition: ReadMaterial.h:68
double volume
The sample volume to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:54
double massDensity
The sample mass density to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:50
double scatteringXSection
The total scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:62
double incoherentXSection
The incoherent scattering cross section to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:58
double zParameter
The zParameter to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:46
std::string chemicalSymbol
The chemical formula to set, defaults to the empty string.
Definition: ReadMaterial.h:34
double numberDensityEffective
The sample effective number density.
Definition: ReadMaterial.h:42
std::string xRayAttenuationProfileFileName
The name or path of a file containing an x ray attenuation profile.
Definition: ReadMaterial.h:66
double unitCellVolume
The unit cell volume to set, defaults to EMPTY_DBL()
Definition: ReadMaterial.h:48
int atomicNumber
The atomic number to set, defaults to 0.
Definition: ReadMaterial.h:36
std::string attenuationProfileFileName
The name or path of a file containing an attenuation profile.
Definition: ReadMaterial.h:64