22 #include <boost/format.hpp>
28 const double eps = 2e-16;
29 const double q_limit_series = 1e-2;
30 const int n_limit_series = 20;
34 const std::vector<kvector_t>& vertices)
46 for (
size_t j = 0; j <
vertices.size(); ++j)
47 for (
size_t jj = j + 1; jj <
vertices.size(); ++jj)
52 std::vector<kvector_t> corners;
60 throw std::logic_error(
"Less than four non-vanishing faces");
70 throw std::logic_error(
"Odd #faces violates symmetry Ci");
73 for (
size_t k = 0; k < N; ++k)
78 }
catch (std::invalid_argument& e) {
79 throw std::invalid_argument(std::string(
"Invalid parameterization of Polyhedron: ")
81 }
catch (std::logic_error& e) {
82 throw std::logic_error(std::string(
"Bug in Polyhedron: ") + e.what()
83 +
" [please report to the maintainers]");
84 }
catch (std::exception& e) {
85 throw std::runtime_error(std::string(
"Unexpected exception in Polyhedron: ") + e.what()
86 +
" [please report to the maintainers]");
95 double pyramidal_volume = 0;
97 pyramidal_volume += Gk.pyramidalVolume();
98 pyramidal_volume /=
m_faces.size();
100 if (std::abs(Gk.pyramidalVolume() - pyramidal_volume) > 160 * eps * pyramidal_volume) {
101 std::cerr << std::setprecision(16)
102 <<
"Bug: pyr_volume(this face)=" << Gk.pyramidalVolume()
103 <<
" vs pyr_volume(avge)=" << pyramidal_volume <<
"\n";
104 throw std::runtime_error(
"Deviant pyramidal volume in Platonic Polyhedron");
128 }
catch (std::logic_error& e) {
129 throw std::logic_error(std::string(
"Bug in Polyhedron: ") + e.what()
130 +
" [please report to the maintainers]");
131 }
catch (std::runtime_error& e) {
132 throw std::runtime_error(std::string(
"Numeric computation failed in Polyhedron: ")
133 + e.what() +
" [please report to the maintainers]");
134 }
catch (std::exception& e) {
135 throw std::runtime_error(std::string(
"Unexpected exception in Polyhedron: ") + e.what()
136 +
" [please report to the maintainers]");
145 #ifdef ALGORITHM_DIAGNOSTIC
146 polyhedralDiagnosis.reset();
150 }
else if (q_red < q_limit_series) {
152 #ifdef ALGORITHM_DIAGNOSTIC
153 polyhedralDiagnosis.algo = 100;
157 int count_return_condition = 0;
158 for (
int n = 2; n < n_limit_series; ++n) {
161 #ifdef ALGORITHM_DIAGNOSTIC
162 polyhedralDiagnosis.order = std::max(polyhedralDiagnosis.order, n);
170 #ifdef ALGORITHM_DIAGNOSTIC_LEVEL2
171 polyhedralDiagnosis.msg +=
172 boost::str(boost::format(
" + term(n=%2i) = %23.17e+i*%23.17e\n") % n % term.real()
176 if (std::abs(term) <= eps * std::abs(sum) || std::abs(sum) < eps *
m_volume)
177 ++count_return_condition;
179 count_return_condition = 0;
180 if (count_return_condition > 2)
184 throw std::runtime_error(
"Series F(q) not converged");
187 #ifdef ALGORITHM_DIAGNOSTIC
188 polyhedralDiagnosis.algo = 200;
192 complex_t qn = Gk.normalProjectionConj(q);
193 if (std::abs(qn) < eps * q.
mag())
196 #ifdef ALGORITHM_DIAGNOSTIC
197 polyhedralDiagnosis.msg += boost::str(boost::format(
" + face_ff = %23.17e+i*%23.17e\n")
198 % term.real() % term.imag());
202 #ifdef ALGORITHM_DIAGNOSTIC
203 polyhedralDiagnosis.msg +=
204 boost::str(boost::format(
" -> raw sum = %23.17e+i*%23.17e; divisor = %23.17e\n")
205 % sum.real() % sum.imag() % q.
mag2());
207 return sum /
I / q.
mag2();
complex_t mul_I(complex_t z)
Returns product I*z, where I is the imaginary unit.
std::complex< double > complex_t
complex_t exp_I(complex_t z)
Returns exp(I*z), where I is the imaginary unit.
Defines functions in namespace Math.
Defines classes PolygonalTopology, PolyhedralTopology.
Defines class Polyhedron.
double mag2() const
Returns magnitude squared of the vector.
double mag() const
Returns magnitude of the vector.
T z() const
Returns z-component in cartesian coordinate system.
For internal use in PolyhedralFace.
std::vector< int > vertexIndices
A polygon, for form factor computation.
static double diameter(const std::vector< kvector_t > &V)
Static method, returns diameter of circle that contains all vertices.
For internal use in IFormFactorPolyhedron.
std::vector< PolygonalTopology > faces
void assert_platonic() const
bool m_sym_Ci
if true, then faces obtainable by inversion are not provided
std::vector< PolyhedralFace > m_faces
complex_t evaluate_centered(const cvector_t &q) const
Returns the form factor F(q) of this polyhedron, with origin at z=0.
complex_t evaluate_for_q(const cvector_t &q) const
needed for topZ, bottomZ computation
const std::vector< kvector_t > & vertices()
std::vector< kvector_t > m_vertices