From 1e7c133e96d1bbc690290019bdb8d7928fe8ee50 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Wed, 23 Sep 2020 11:12:20 +0200 Subject: [PATCH] Core FF Prism now in pimpl idiom --- Core/HardParticle/IFormFactorPolyhedron.h | 4 +- Core/HardParticle/IFormFactorPrism.cpp | 84 ++++++++++++++--------- Core/HardParticle/IFormFactorPrism.h | 21 +++++- 3 files changed, 74 insertions(+), 35 deletions(-) diff --git a/Core/HardParticle/IFormFactorPolyhedron.h b/Core/HardParticle/IFormFactorPolyhedron.h index 525e188d52a..e21c3675509 100644 --- a/Core/HardParticle/IFormFactorPolyhedron.h +++ b/Core/HardParticle/IFormFactorPolyhedron.h @@ -22,9 +22,11 @@ //! A polyhedron, implementation class for use in IFormFactorPolyhedron -class Polyhedron +class BA_CORE_API_ Polyhedron { public: + Polyhedron() = delete; + Polyhedron(const Polyhedron&) = delete; Polyhedron(const PolyhedralTopology& topology, double z_bottom, const std::vector<kvector_t>& vertices); void assert_platonic() const; diff --git a/Core/HardParticle/IFormFactorPrism.cpp b/Core/HardParticle/IFormFactorPrism.cpp index 3e3dfff7d05..0bc572d69a2 100644 --- a/Core/HardParticle/IFormFactorPrism.cpp +++ b/Core/HardParticle/IFormFactorPrism.cpp @@ -27,54 +27,38 @@ namespace const double eps = 2e-16; } // namespace -IFormFactorPrism::IFormFactorPrism(const NodeMeta& meta, const std::vector<double>& PValues) - : IFormFactorBorn(meta, PValues) -{ -} - -void IFormFactorPrism::setPrism(bool symmetry_Ci, const std::vector<kvector_t>& vertices) +Prism::Prism(bool symmetry_Ci, double height, const std::vector<kvector_t>& vertices) { + m_height = height; m_vertices.clear(); for (const kvector_t& vertex : vertices) { m_vertices.push_back(vertex); - m_vertices.push_back(vertex + kvector_t{0, 0, height()}); + m_vertices.push_back(vertex + kvector_t{0, 0, m_height}); } try { m_base = std::unique_ptr<PolyhedralFace>(new PolyhedralFace(vertices, symmetry_Ci)); } catch (std::invalid_argument& e) { - throw std::invalid_argument("Invalid parameterization of " + getName() + ": " + e.what()); + throw std::invalid_argument(std::string("Invalid parameterization of Prism: ") + + e.what()); } catch (std::logic_error& e) { - throw std::logic_error("Bug in " + getName() + ": " + e.what() + throw std::logic_error(std::string("Bug in Prism: ") + e.what() + " [please report to the maintainers]"); } catch (std::exception& e) { - throw std::runtime_error("Unexpected exception in " + getName() + ": " + e.what() + throw std::runtime_error(std::string("Unexpected exception in Prism: ") + e.what() + " [please report to the maintainers]"); } } -double IFormFactorPrism::bottomZ(const IRotation& rotation) const -{ - return BottomZ(m_vertices, rotation); -} - -double IFormFactorPrism::topZ(const IRotation& rotation) const -{ - return TopZ(m_vertices, rotation); -} +double Prism::area() const { return m_base->area(); } -//! Returns the volume of this prism. -double IFormFactorPrism::volume() const +const std::vector<kvector_t>& Prism::vertices() { - return height() * m_base->area(); + return m_vertices; } -double IFormFactorPrism::getHeight() const { return height(); } -double IFormFactorPrism::radialExtension() const { return std::sqrt(m_base->area()); } -//! Returns the form factor F(q) of this polyhedron, respecting the offset height/2. - -complex_t IFormFactorPrism::evaluate_for_q(cvector_t q) const +complex_t Prism::evaluate_for_q(const cvector_t& q) const { try { #ifdef POLYHEDRAL_DIAGNOSTIC @@ -82,16 +66,54 @@ complex_t IFormFactorPrism::evaluate_for_q(cvector_t q) const diagnosis.nExpandedFaces = 0; #endif cvector_t qxy(q.x(), q.y(), 0.); - return height() * exp_I(height() / 2 * q.z()) * MathFunctions::sinc(height() / 2 * q.z()) + return m_height * exp_I(m_height / 2 * q.z()) * MathFunctions::sinc(m_height / 2 * q.z()) * m_base->ff_2D(qxy); } catch (std::logic_error& e) { - throw std::logic_error("Bug in " + getName() + ": " + e.what() + throw std::logic_error(std::string("Bug in Prism: ") + e.what() + " [please report to the maintainers]"); } catch (std::runtime_error& e) { - throw std::runtime_error("Numeric computation failed in " + getName() + ": " + e.what() + throw std::runtime_error(std::string("Numeric computation failed in Prism: ") + e.what() + " [please report to the maintainers]"); } catch (std::exception& e) { - throw std::runtime_error("Unexpected exception in " + getName() + ": " + e.what() + throw std::runtime_error(std::string("Unexpected exception in Prism: ") + e.what() + " [please report to the maintainers]"); } } + + + +IFormFactorPrism::IFormFactorPrism(const NodeMeta& meta, const std::vector<double>& PValues) + : IFormFactorBorn(meta, PValues) +{ +} + +void IFormFactorPrism::setPrism(bool symmetry_Ci, const std::vector<kvector_t>& vertices) +{ + pimpl = std::make_unique<Prism>(symmetry_Ci, height(), vertices); +} + +double IFormFactorPrism::bottomZ(const IRotation& rotation) const +{ + return BottomZ(pimpl->vertices(), rotation); +} + +double IFormFactorPrism::topZ(const IRotation& rotation) const +{ + return TopZ(pimpl->vertices(), rotation); +} + +//! Returns the volume of this prism. +double IFormFactorPrism::volume() const +{ + return height() * pimpl->area(); +} + +double IFormFactorPrism::getHeight() const { return height(); } +double IFormFactorPrism::radialExtension() const { return std::sqrt(pimpl->area()); } + +//! Returns the form factor F(q) of this polyhedron, respecting the offset height/2. + +complex_t IFormFactorPrism::evaluate_for_q(cvector_t q) const +{ + return pimpl->evaluate_for_q(q); +} diff --git a/Core/HardParticle/IFormFactorPrism.h b/Core/HardParticle/IFormFactorPrism.h index dbad76ea93d..c1aeffa6279 100644 --- a/Core/HardParticle/IFormFactorPrism.h +++ b/Core/HardParticle/IFormFactorPrism.h @@ -20,6 +20,22 @@ #include "Core/Scattering/IFormFactorBorn.h" #include <memory> +class BA_CORE_API_ Prism +{ +public: + Prism() = delete; + Prism(const Prism&) = delete; + Prism(bool symmetry_Ci, double height, const std::vector<kvector_t>& vertices); + double area() const; + const std::vector<kvector_t>& vertices(); //! needed for topZ, bottomZ computation + complex_t evaluate_for_q(const cvector_t& q) const; + // complex_t evaluate_centered(const cvector_t& q) const; +private: + std::unique_ptr<PolyhedralFace> m_base; + double m_height; + std::vector<kvector_t> m_vertices; //! for topZ, bottomZ computation only +}; + //! A prism with a polygonal base, for form factor computation. class BA_CORE_API_ IFormFactorPrism : public IFormFactorBorn @@ -38,11 +54,10 @@ public: protected: void setPrism(bool symmetry_Ci, const std::vector<kvector_t>& vertices); + virtual double height() const = 0; // TODO mv parameter m_height back from children to this private: - virtual double height() const = 0; - std::unique_ptr<PolyhedralFace> m_base; - std::vector<kvector_t> m_vertices; //! for topZ, bottomZ computation only + std::unique_ptr<Prism> pimpl; }; #endif // BORNAGAIN_CORE_HARDPARTICLE_IFORMFACTORPRISM_H -- GitLab