Skip to content
Snippets Groups Projects
Commit b8112b8c authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

Core: FF full spheroid: analytical formula instead of numeric

integration
parent 93373c87
No related branches found
No related tags found
No related merge requests found
...@@ -30,34 +30,26 @@ FormFactorFullSpheroid::FormFactorFullSpheroid(double radius, double height) ...@@ -30,34 +30,26 @@ FormFactorFullSpheroid::FormFactorFullSpheroid(double radius, double height)
setName(BornAgain::FFFullSpheroidType); setName(BornAgain::FFFullSpheroidType);
registerParameter(BornAgain::Radius, &m_radius).setUnit(BornAgain::UnitsNm).setNonnegative(); registerParameter(BornAgain::Radius, &m_radius).setUnit(BornAgain::UnitsNm).setNonnegative();
registerParameter(BornAgain::Height, &m_height).setUnit(BornAgain::UnitsNm).setNonnegative(); registerParameter(BornAgain::Height, &m_height).setUnit(BornAgain::UnitsNm).setNonnegative();
mP_integrator = make_integrator_complex(this, &FormFactorFullSpheroid::Integrand);
onChange(); onChange();
} }
//! Integrand for complex formfactor.
complex_t FormFactorFullSpheroid::Integrand(double Z) const
{
double R = m_radius;
double h = m_height / 2;
double Rz = R * std::sqrt(1 - Z * Z / (h * h));
complex_t qxy = std::sqrt(m_q.x() * m_q.x() + m_q.y() * m_q.y());
complex_t qrRz = qxy * Rz;
complex_t J1_qrRz_div_qrRz = MathFunctions::Bessel_J1c(qrRz);
return Rz * Rz * J1_qrRz_div_qrRz * std::cos(m_q.z() * Z);
}
complex_t FormFactorFullSpheroid::evaluate_for_q(cvector_t q) const complex_t FormFactorFullSpheroid::evaluate_for_q(cvector_t q) const
{ {
double h = m_height / 2; double h = m_height / 2;
double R = m_radius; double R = m_radius;
m_q = q;
if (std::abs(m_q.mag()) <= std::numeric_limits<double>::epsilon()) // complex length of q (not a sesquilinear dot product!),
return 4 * M_PI * R * R * h / 3.; // xy components multiplied with R, z component multiplied with h
complex_t qR =
sqrt( R * R * (q.x() * q.x() + q.y() * q.y()) + h * h * q.z() * q.z());
complex_t zFactor = exp_I(h * q.z());
if (std::abs(qR) < 1e-4)
// expand sin(qR)-qR*cos(qR) up to qR^5
return 4 * M_PI / 3 * R * R * h * (1. - 0.1 * pow(qR, 2)) * zFactor;
return 4 * M_PI * mP_integrator->integrate(0.0, h) * exp_I(h * q.z()); return 4 * M_PI / pow(qR, 3) * R * R * h * (sin(qR) - qR * cos(qR)) * zFactor;
} }
IFormFactor* FormFactorFullSpheroid::sliceFormFactor(ZLimits limits, const IRotation& rot, IFormFactor* FormFactorFullSpheroid::sliceFormFactor(ZLimits limits, const IRotation& rot,
......
...@@ -46,15 +46,8 @@ protected: ...@@ -46,15 +46,8 @@ protected:
void onChange() override final; void onChange() override final;
private: private:
complex_t Integrand(double Z) const;
double m_radius; double m_radius;
double m_height; double m_height;
mutable cvector_t m_q;
#ifndef SWIG
std::unique_ptr<IntegratorComplex<FormFactorFullSpheroid>> mP_integrator;
#endif
}; };
#endif // FORMFACTORFULLSPHEROID_H #endif // FORMFACTORFULLSPHEROID_H
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