25 double damping_length)
27 m_use_damping_length(true), m_kappa(0.0), m_domain_size(0.0)
29 setName(
"InterferenceRadialParaCrystal");
30 if (m_damping_length == 0.0)
31 m_use_damping_length =
false;
32 registerParameter(
"PeakDistance", &m_peak_distance).setUnit(
"nm").setNonnegative();
33 registerParameter(
"DampingLength", &m_damping_length).setUnit(
"nm").setNonnegative();
34 registerParameter(
"SizeSpaceCoupling", &m_kappa).setNonnegative();
35 registerParameter(
"DomainSize", &m_domain_size).setUnit(
"nm").setNonnegative();
41 ret->setPositionVariance(m_position_var);
43 ret->setProbabilityDistribution(*mP_pdf);
44 ret->setKappa(m_kappa);
45 ret->setDomainSize(m_domain_size);
55 double InterferenceFunctionRadialParaCrystal::kappa()
const
68 complex_t InterferenceFunctionRadialParaCrystal::FTPDF(
double qpar)
const
70 complex_t phase =
exp_I(qpar * m_peak_distance);
71 double amplitude = mP_pdf->evaluate(qpar);
72 complex_t result = phase * amplitude;
73 if (m_use_damping_length)
74 result *= std::exp(-m_peak_distance / m_damping_length);
83 mP_pdf.reset(pdf.clone());
84 registerChild(mP_pdf.get());
89 return std::vector<const INode*>() << mP_pdf;
92 double InterferenceFunctionRadialParaCrystal::iff_without_dw(
const kvector_t q)
const
96 "evaluate() -> Error! Probability distribution for "
97 "interference function not properly initialized");
101 double qpar = std::sqrt(qxr * qxr + qyr * qyr);
102 int n =
static_cast<int>(std::abs(m_domain_size / m_peak_distance));
103 double nd =
static_cast<double>(n);
104 complex_t fp = FTPDF(qpar);
106 if (std::abs(1.0 - fp) < 10. * std::numeric_limits<double>::epsilon()) {
107 result = mP_pdf->qSecondDerivative() / m_peak_distance / m_peak_distance;
109 result = ((1.0 + fp) / (1.0 - fp)).real();
112 if (std::norm(1.0 - fp) < 10. * std::numeric_limits<double>::epsilon()) {
116 else if (std::abs(1.0 - fp) * nd < 2e-4) {
117 complex_t intermediate =
118 (nd - 1.0) / 2.0 + (nd * nd - 1.0) * (fp - 1.0) / 6.0
119 + (nd * nd * nd - 2.0 * nd * nd - nd + 2.0) * (fp - 1.0) * (fp - 1.0) / 24.0;
120 result = 1.0 + 2.0 * intermediate.real();
123 if (std::abs(fp) == 0.0
124 || std::log(std::abs(fp)) * nd < std::log(std::numeric_limits<double>::min())) {
127 tmp = std::pow(fp, n);
129 complex_t intermediate =
130 fp / (1.0 - fp) - fp * (1.0 - tmp) / nd / (1.0 - fp) / (1.0 - fp);
131 result = 1.0 + 2.0 * intermediate.real();
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Defines many exception classes in namespace Exceptionss.
Defines class InterferenceFunctionRadialParaCrystal.
Defines class ParameterPool.
Defines class RealParameter.
T y() const
Returns y-component in cartesian coordinate system.
T x() const
Returns x-component in cartesian coordinate system.
Interface for a one-dimensional distribution, with normalization adjusted so that the Fourier transfo...
Pure virtual base class of interference functions.
Interference function of radial paracrystal.
InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length)
Constructor of interference function of radial paracrystal.
std::vector< const INode * > getChildren() const override final
Returns a vector of children (const).
InterferenceFunctionRadialParaCrystal * clone() const override final
Returns a clone of this ISample object.
void setDomainSize(double size)
Sets domain size (finite size corrections).
void setKappa(double kappa)
Sets size spacing coupling parameter of the Size Spacing Correlation Approximation.
void setProbabilityDistribution(const IFTDistribution1D &pdf)
Sets one-dimensional probability distribution.