1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
// ************************************************************************************************
//
// libformfactor: efficient and accurate computation of scattering form factors
//
//! @file ff/Face.h
//! @brief Defines class Face
//!
//! @homepage https://jugit.fz-juelich.de/mlz/libformfactor
//! @license GNU General Public License v3 or higher (see LICENSE)
//! @copyright Forschungszentrum Jülich GmbH 2022
//! @author Joachim Wuttke, Scientific Computing Group at MLZ (see CITATION)
//
// ************************************************************************************************
#ifndef FF_FACE_H
#define FF_FACE_H
#include <heinz/Complex.h>
#include <heinz/Vectors3D.h>
#include <vector>
namespace ff {
class Edge;
#ifdef ALGORITHM_DIAGNOSTIC
#include <string>
struct PolyhedralDiagnosis {
int algo;
int order;
std::string msg;
void reset();
std::string message() const;
bool operator==(const PolyhedralDiagnosis&) const;
bool operator!=(const PolyhedralDiagnosis&) const;
};
inline PolyhedralDiagnosis polyhedralDiagnosis;
#endif
//! A polygon, for form factor computation.
class Face {
public:
Face(const std::vector<R3>& _V, bool _sym_S2 = false);
~Face();
Face(const Face&) = delete;
Face(Face&&) = default;
double area() const { return m_area; }
double radius() const { return m_radius_2d; }
double pyramidalVolume() const { return m_rperp * m_area / 3; }
//! Returns center of mass of the plane figure
R3 center_of_polygon() const;
//! Returns conj(q)*normal [BasicVector3D::dot is antilinear in 'this' argument]
complex_t normalProjectionConj(C3 q) const { return q.dot(m_normal); }
complex_t ff_n(int n, C3 q) const;
complex_t ff(C3 q, bool sym_Ci) const;
complex_t ff_2D(C3 qpa) const;
complex_t ff_2D_direct(C3 qpa) const; // for TestTriangle
complex_t ff_2D_expanded(C3 qpa) const; // for TestTriangle
void assert_Ci(const Face& other) const;
const std::vector<Edge>& edges() const;
const R3& normal() const { return m_normal; }
bool is_symmetric() const { return m_sym_S2; }
bool is_inside(const R3& v) const;
private:
const bool m_sym_S2; //!< if true, then edges obtainable by inversion are not provided
const double m_radius_2d; //!< radius of enclosing cylinder
const R3 m_normal; //!< normal vector of this polygon's plane
const double m_rperp; //!< distance of polygon's plane from the origin, along 'm_normal'
const double m_area;
const std::vector<Edge> m_edges;
void decompose_q(C3 q, complex_t& qperp, C3& qpa) const;
complex_t ff_n_core(int m, C3 qpa, complex_t qperp) const;
complex_t edge_sum_ff(C3 q, C3 qpa, bool sym_Ci) const;
complex_t expansion(complex_t fac_even, complex_t fac_odd, C3 qpa, double abslevel) const;
};
} // namespace ff
#endif // FF_FACE_H
|