Skip to content

Internal SLD units are inconsistent

SLD units are "stored" in MaterialBySLDImpl class in nm^-2.

From outside the SLD can be get converted to A^-2 in

complex_t MaterialBySLDImpl::materialData() const
{
    return complex_t(m_sld_real * square_angstroms, m_sld_imag * square_angstroms);
}

or in nm^-2 (but shifted):

complex_t MaterialBySLDImpl::scalarSubtrSLD(double lambda0) const
{
    if (std::isnan(lambda0))
        throw std::runtime_error("wavelength not set");
    return 1.0 / getWlPrefactor(lambda0) - sld();
}

This is a dangerous point.


When BornAgain accepts SLD values from user, these values are always understood in A^-2.

GUI explicitly says that:

GUI/Model/Sample/MaterialItem.cpp : 49 :

    m_sldRe.init("SLD, real", "Real part of SLD (SLD = real - i*imag), " + sld_units_str, 0.0,
                 sld_units, 3, RealLimits::limitless(), "sldRe");
    m_sldIm.init("SLD, imaginary", "Imaginary part of SLD (SLD = real - i*imag), " + sld_units_str,
                 0.0, sld_units, 3, RealLimits::limitless(), "sldIm");

MaterialItem is converted to core class Material in

std::unique_ptr<Material> MaterialItem::createMaterial() const

MaterialBySLD function from MaterialFactoryFuncs.cpp does the convertation to nm^-2.

The same MaterialBySLD function is used in Python API: it accepts SLD in A^-2 and converts it to nm^-2.

Edited by Mikhail Svechnikov