Molassembler  2.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Data.h
Go to the documentation of this file.
1 
8 #ifndef INCLUDE_MOLASSEMBLER_SHAPES_CONSTEXPR_DATA_H
9 #define INCLUDE_MOLASSEMBLER_SHAPES_CONSTEXPR_DATA_H
10 
13 
17 
18 namespace Scine {
19 namespace Molassembler {
20 namespace Shapes {
21 
23 constexpr unsigned ORIGIN_PLACEHOLDER = std::numeric_limits<unsigned>::max();
24 
30 namespace Data {
31 
41 struct Line {
42  static constexpr Shape shape = Shape::Line;
43  static constexpr PointGroup pointGroup = PointGroup::Cinfv;
44  static constexpr unsigned size = 2;
45  static constexpr char stringName[] = "line";
46  static constexpr double angleFunction(const unsigned a, const unsigned b) {
47  if(a == b) {
48  return 0;
49  }
50 
51  return M_PI;
52  }
53  static constexpr std::array<Temple::Vector, 2> coordinates {{
54  { 1 , 0, 0 },
55  { -1, 0, 0 }
56  }};
57  static constexpr std::array<
58  std::array<unsigned, 2>,
59  1
60  > rotations {{
61  {{1, 0}}
62  }};
63  static constexpr std::array<
64  std::array<unsigned, 4>,
65  0
66  > tetrahedra {{}};
67  static constexpr std::array<unsigned, 0> mirror {};
68 };
69 
81 struct Bent {
82  static constexpr Shape shape = Shape::Bent;
83  static constexpr PointGroup pointGroup = PointGroup::C2v;
84  static constexpr unsigned size = 2;
85  static constexpr char stringName[] = "bent";
86  static constexpr double angleFunction(const unsigned a, const unsigned b) {
87  /* subject to a lot of variation, between 90 and 109 degrees pursuant to
88  * english wikipedia, using experimental data here to improve instances
89  * of this geometry on e.g. O center would a big improvement to DG runs
90  */
91  if(a == b) {
92  return 0;
93  }
94 
95  return Temple::Math::toRadians<double>(107);
96  }
97  static constexpr std::array<Temple::Vector, 2> coordinates {{
98  {1., 0., 0.},
99  {-0.292372, 0.956305, 0.}
100  }};
101  static constexpr std::array<
102  std::array<unsigned, 2>,
103  1
104  > rotations {{
105  {{1, 0}}
106  }};
107  static constexpr std::array<
108  std::array<unsigned, 4>,
109  0
110  > tetrahedra {{}};
111  static constexpr std::array<unsigned, 0> mirror {};
112 };
113 
132  static constexpr Shape shape = Shape::EquilateralTriangle;
133  static constexpr PointGroup pointGroup = PointGroup::D3h;
134  static constexpr unsigned size = 3;
135  static constexpr char stringName[] = "triangle";
136  static constexpr double angleFunction(const unsigned a, const unsigned b) {
137  if(a == b) {
138  return 0;
139  }
140 
141  return Temple::Math::toRadians<double>(120);
142  }
143  static constexpr std::array<Temple::Vector, 3> coordinates {{
144  {1, 0, 0},
145  {-0.5, 0.866025, 0},
146  {-0.5, -0.866025, 0}
147  }};
148  static constexpr std::array<
149  std::array<unsigned, 3>,
150  2
151  > rotations {{
152  {{1, 2, 0}}, // C3
153  {{0, 2, 1}} // C2
154  }};
155  static constexpr std::array<
156  std::array<unsigned, 4>,
157  0
158  > tetrahedra {{}};
159  static constexpr std::array<unsigned, 0> mirror {};
160 };
161 
180  static constexpr Shape shape = Shape::VacantTetrahedron;
181  static constexpr PointGroup pointGroup = PointGroup::C3v;
182  static constexpr unsigned size = 3;
183  static constexpr char stringName[] = "vacant tetrahedron";
184  static constexpr double angleFunction(const unsigned a, const unsigned b) {
185  if(a == b) {
186  return 0;
187  }
188 
189  return Temple::Math::toRadians<double>(107.5);
190  }
191  static constexpr std::array<Temple::Vector, 3> coordinates {{
192  {0, -0.366501, 0.930418},
193  {0.805765, -0.366501, -0.465209},
194  {-0.805765, -0.366501, -0.465209}
195  }};
196  static constexpr std::array<
197  std::array<unsigned, 3>,
198  1
199  > rotations {{
200  {{2, 0, 1}} // C3
201  }};
202  static constexpr std::array<
203  std::array<unsigned, 4>,
204  1
205  > tetrahedra {{
206  {{ORIGIN_PLACEHOLDER, 0, 1, 2}}
207  }};
208  static constexpr std::array<unsigned, 3> mirror {{0, 2, 1}};
209 };
210 
222 struct T {
223  static constexpr Shape shape = Shape::T;
224  static constexpr PointGroup pointGroup = PointGroup::C2v;
225  static constexpr unsigned size = 3;
226  static constexpr char stringName[] = "T-shaped";
227  static constexpr double angleFunction(const unsigned a, const unsigned b) {
228  if(a == b) {
229  return 0;
230  }
231 
232  if((a + b) % 2 == 1) {
233  return M_PI / 2;
234  }
235 
236  return M_PI;
237  }
238  static constexpr std::array<Temple::Vector, 3> coordinates {{
239  {-1, -0, -0},
240  {0, 1, 0},
241  {1, 0, 0},
242  }};
243  static constexpr std::array<
244  std::array<unsigned, 3>,
245  1
246  > rotations {{
247  {{2, 1, 0}} // C2
248  }};
249  static constexpr std::array<
250  std::array<unsigned, 4>,
251  0
252  > tetrahedra {{}};
253  static constexpr std::array<unsigned, 0> mirror {};
254 };
255 
271 struct Tetrahedron {
272  static constexpr Shape shape = Shape::Tetrahedron;
273  static constexpr PointGroup pointGroup = PointGroup::Td;
274  static constexpr unsigned size = 4;
275  static constexpr char stringName[] = "tetrahedron";
276  static constexpr double angleFunction(const unsigned a, const unsigned b) {
277  if(a == b) {
278  return 0;
279  }
280 
281  return 2 * Temple::Math::atan(M_SQRT2);
282  }
283  static constexpr std::array<Temple::Vector, 4> coordinates {{
284  {0, 1, 0},
285  {0, -0.333807, 0.942641},
286  {0.816351, -0.333807, -0.471321},
287  {-0.816351, -0.333807, -0.471321}
288  }};
289  static constexpr std::array<
290  std::array<unsigned, 4>,
291  4
292  > rotations {{
293  {{0, 3, 1, 2}}, // C4, 1
294  {{2, 1, 3, 0}}, // C4, 2
295  {{3, 0, 2, 1}}, // C4, 3
296  {{1, 2, 0, 3}} // C4, 4
297  }};
298  static constexpr std::array<
299  std::array<unsigned, 4>,
300  1
301  > tetrahedra {{
302  {{0, 1, 2, 3}}
303  }};
304  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
305 };
306 
322 struct Square {
323  static constexpr Shape shape = Shape::Square;
324  static constexpr PointGroup pointGroup = PointGroup::D4h;
325  static constexpr unsigned size = 4;
326  static constexpr char stringName[] = "square";
327  static constexpr double angleFunction(const unsigned a, const unsigned b) {
328  if(a == b) {
329  return 0;
330  }
331 
332  if((a + b) % 2 == 1) {
333  // this expression indicates cis
334  return M_PI / 2;
335  }
336 
337  // leftover case is trans
338  return M_PI;
339  }
340  static constexpr std::array<Temple::Vector, 4> coordinates {{
341  {1, 0, 0},
342  {0, 1, 0},
343  {-1, -0, -0},
344  {-0, -1, -0}
345  }};
346  static constexpr std::array<
347  std::array<unsigned, 4>,
348  3
349  > rotations {{
350  {{3, 0, 1, 2}}, // C4
351  {{1, 0, 3, 2}}, // C2
352  {{3, 2, 1, 0}} // C2'
353  }};
354  static constexpr std::array<
355  std::array<unsigned, 4>,
356  0
357  > tetrahedra {{}};
358  static constexpr std::array<unsigned, 0> mirror {};
359 };
360 
377 struct Seesaw {
378  static constexpr Shape shape = Shape::Seesaw;
379  static constexpr PointGroup pointGroup = PointGroup::C2v;
380  static constexpr unsigned size = 4;
381  static constexpr char stringName[] = "seesaw";
382  static constexpr double angleFunction(const unsigned a, const unsigned b) {
383  if(a == b) {
384  return 0;
385  }
386 
387  const auto& smaller = std::min(a, b);
388  const auto& larger = std::max(a, b);
389  if(smaller == 0 && larger == 3) {
390  return M_PI;
391  }
392 
393  if(smaller == 1 && larger == 2) {
394  return Temple::Math::toRadians<double>(120);
395  }
396 
397  return M_PI / 2;
398  }
399  static constexpr std::array<Temple::Vector, 4> coordinates {{
400  {0, 1, 0},
401  {1, 0, 0},
402  {-0.5, 0, -0.866025},
403  {-0, -1, -0}
404  }};
405  static constexpr std::array<
406  std::array<unsigned, 4>,
407  1
408  > rotations {{
409  {{3, 2, 1, 0}} // C2
410  }};
411 
412  static constexpr std::array<
413  std::array<unsigned, 4>,
414  2
415  > tetrahedra {{
416  {{0, ORIGIN_PLACEHOLDER, 1, 2}},
417  {{ORIGIN_PLACEHOLDER, 3, 1, 2}},
418  }};
419 
420  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
421 };
422 
423 
445  static constexpr Shape shape = Shape::TrigonalPyramid;
446  static constexpr PointGroup pointGroup = PointGroup::C3v;
447  static constexpr unsigned size = 4;
448  static constexpr char stringName[] = "trigonal pyramid";
449  static constexpr double angleFunction(const unsigned a, const unsigned b) {
450  if(a == b) {
451  return 0;
452  }
453 
454  if(std::max(a, b) != 3) {
455  // -> smaller < 2, this means either 0,1 0,2 1,2 axial
456  return Temple::Math::toRadians<double>(120);
457  }
458 
459  // -> smaller < 3, this means {1,2,3}, 3
460  return M_PI / 2;
461  }
462  static constexpr std::array<Temple::Vector, 4> coordinates {{
463  {1, 0, 0},
464  {-0.5, 0.866025, 0},
465  {-0.5, -0.866025, 0},
466  {0, 0, 1}
467  }};
468  static constexpr std::array<
469  std::array<unsigned, 4>,
470  1
471  > rotations {{
472  {{2, 0, 1, 3}} // C3
473  }};
474  static constexpr std::array<
475  std::array<unsigned, 4>,
476  1
477  > tetrahedra {{
478  {{0, 1, 3, 2}}
479  }};
480  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
481 };
482 
498  static constexpr Shape shape = Shape::SquarePyramid;
499  static constexpr PointGroup pointGroup = PointGroup::C4v;
500  static constexpr unsigned size = 5;
501  static constexpr char stringName[] = "square pyramid";
502  static constexpr double angleFunction(const unsigned a, const unsigned b) {
503  if(a == b) {
504  return 0;
505  }
506 
507  if(a == 4 || b == 4) { // all bonds to axial ligand are 90°
508  return M_PI / 2;
509  }
510 
511  if((a + b) % 2 == 0) { // 0 + 2 or 1 + 3 are trans
512  return M_PI;
513  }
514 
515  // rest are cis
516  return M_PI / 2;
517  }
518  static constexpr std::array<Temple::Vector, 5> coordinates {{
519  {1, 0, 0},
520  {0, 1, 0},
521  {-1, -0, -0},
522  {-0, -1, -0},
523  {0, 0, 1}
524  }};
525  static constexpr std::array<
526  std::array<unsigned, 5>,
527  1
528  > rotations {{
529  {{3, 0, 1, 2, 4}} // C4
530  }};
531 
532  static constexpr std::array<
533  std::array<unsigned, 4>,
534  4
535  > tetrahedra {{
536  {{0, 1, 4, ORIGIN_PLACEHOLDER}},
537  {{1, 2, 4, ORIGIN_PLACEHOLDER}},
538  {{2, 3, 4, ORIGIN_PLACEHOLDER}},
539  {{3, 0, 4, ORIGIN_PLACEHOLDER}}
540  }};
541 
542  static constexpr std::array<unsigned, 5> mirror {{1, 0, 3, 2, 4}};
543 };
544 
564  static constexpr Shape shape = Shape::TrigonalBipyramid;
565  static constexpr PointGroup pointGroup = PointGroup::D3h;
566  static constexpr unsigned size = 5;
567  static constexpr char stringName[] = "trigonal bipyramid";
568  static constexpr double angleFunction(const unsigned a, const unsigned b) {
569  if(a == b) {
570  return 0;
571  }
572 
573  const unsigned smaller = std::min(a, b);
574  const unsigned larger = std::max(a, b);
575  if(larger < 3) {
576  // -> smaller < 2, this means either 0,1 0,2 1,2 axial
577  return 2 * M_PI / 3;
578  }
579 
580  if(larger == 3) {
581  // -> smaller < 3, this means {1,2,3}, 3
582  return M_PI / 2;
583  }
584 
585  if(smaller < 3) {
586  // now, larger must be 4 (process of elimination), so if a is not 3:
587  return M_PI / 2;
588  }
589 
590  // only case left: 3,4
591  return M_PI;
592  }
593  static constexpr std::array<Temple::Vector, 5> coordinates {{
594  {1, 0, 0},
595  {-0.5, 0.866025, 0},
596  {-0.5, -0.866025, 0},
597  {0, 0, 1},
598  {-0, -0, -1}
599  }};
600  static constexpr std::array<
601  std::array<unsigned, 5>,
602  4
603  > rotations {{
604  {{2, 0, 1, 3, 4}}, // C3
605  {{0, 2, 1, 4, 3}}, // C2 on 0
606  {{2, 1, 0, 4, 3}}, // C2 on 1
607  {{1, 0, 2, 4, 3}} // C2 on 2
608  }};
609  static constexpr std::array<
610  std::array<unsigned, 4>,
611  2
612  > tetrahedra {{
613  {{0, 1, 3, 2}},
614  {{0, 1, 2, 4}}
615  }};
616  static constexpr std::array<unsigned, 5> mirror {{0, 2, 1, 3, 4}};
617 };
618 
634 struct Pentagon {
635  static constexpr Shape shape = Shape::Pentagon;
636  static constexpr PointGroup pointGroup = PointGroup::D5h;
637  static constexpr unsigned size = 5;
638  static constexpr char stringName[] = "pentagon";
639  static constexpr double angleFunction(const unsigned a, const unsigned b) {
640  unsigned absDiff = std::min(a - b, b - a);
641  return std::min(
642  absDiff,
643  std::min(absDiff - 5, 5 - absDiff)
644  ) * Temple::Math::toRadians<double>(72);
645  }
646  static constexpr std::array<Temple::Vector, 5> coordinates {{
647  {1, 0, 0},
648  {0.309017, 0.951057, 0},
649  {-0.809017, 0.587785, 0},
650  {-0.809017, -0.587785, 0},
651  {0.309017, -0.951057, 0}
652  }};
653  static constexpr std::array<
654  std::array<unsigned, 5>,
655  2
656  > rotations {{
657  {{4, 0, 1, 2, 3}}, // C5
658  {{0, 4, 3, 2, 1}} // C2
659  }};
660  static constexpr std::array<
661  std::array<unsigned, 4>,
662  0
663  > tetrahedra {{}};
664  static constexpr std::array<unsigned, 0> mirror {};
665 };
666 
687 struct Octahedron {
688  static constexpr Shape shape = Shape::Octahedron;
689  static constexpr PointGroup pointGroup = PointGroup::Oh;
690  static constexpr unsigned size = 6;
691  static constexpr char stringName[] = "octahedron";
692  static constexpr double angleFunction(const unsigned a, const unsigned b) {
693  if(a == b) {
694  return 0;
695  }
696 
697  if(
698  (
699  std::max(a, b) < 4 // if the largest is < 4, then equatorial
700  && (a + b) % 2 == 0 // this gives trans eq ligands
701  ) || std::min(a, b) == 4 // this indicates 4,5 (axial trans)
702  ) {
703  return M_PI;
704  }
705 
706  return M_PI / 2;
707  }
708  static constexpr std::array<Temple::Vector, 6> coordinates {{
709  {1, 0, 0},
710  {0, 1, 0},
711  {-1, -0, -0},
712  {-0, -1, -0},
713  {0, 0, 1},
714  {-0, -0, -1}
715  }};
716  static constexpr std::array<
717  std::array<unsigned, 6>,
718  3
719  > rotations {{
720  {{3, 0, 1, 2, 4, 5}}, // vertical C4
721  {{0, 5, 2, 4, 1, 3}}, // horizontal C4
722  {{4, 1, 5, 3, 2, 0}} // horizontal C4'
723  }};
724 
725  static constexpr std::array<
726  std::array<unsigned, 4>,
727  8
728  > tetrahedra {{
729  {{3, 0, 4, ORIGIN_PLACEHOLDER}},
730  {{0, 1, 4, ORIGIN_PLACEHOLDER}},
731  {{1, 2, 4, ORIGIN_PLACEHOLDER}},
732  {{2, 3, 4, ORIGIN_PLACEHOLDER}},
733  {{3, 0, ORIGIN_PLACEHOLDER, 5}},
734  {{0, 1, ORIGIN_PLACEHOLDER, 5}},
735  {{1, 2, ORIGIN_PLACEHOLDER, 5}},
736  {{2, 3, ORIGIN_PLACEHOLDER, 5}}
737  }};
738  static constexpr std::array<unsigned, 6> mirror {{1, 0, 3, 2, 4, 5}};
739 };
740 
760  static constexpr Shape shape = Shape::TrigonalPrism;
761  static constexpr PointGroup pointGroup = PointGroup::D3h;
762  static constexpr unsigned size = 6;
763  static constexpr char stringName[] = "trigonal prism";
764  static constexpr std::array<Temple::Vector, 6> coordinates {{
765  { 0.755929, 0.000000, 0.654654},
766  {-0.377964, 0.654654, 0.654654},
767  {-0.377964, -0.654654, 0.654654},
768  { 0.755929, 0.000000, -0.654654},
769  {-0.377964, 0.654654, -0.654654},
770  {-0.377964, -0.654654, -0.654654}
771  }};
772  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
773  Detail::makeArray<size>(coordinates)
774  );
775  static constexpr double angleFunction(const unsigned a, const unsigned b) {
776  if(a == b) {
777  return 0;
778  }
779 
780  return angleLookupTable.at(
781  std::min(a, b),
782  std::max(a, b)
783  );
784  }
785  static constexpr std::array<
786  std::array<unsigned, 6>,
787  2
788  > rotations {{
789  {{2, 0, 1, 5, 3, 4}}, // C3 axial
790  {{3, 5, 4, 0, 2, 1}} // C2 betw. 0, 3
791  }};
792 
793  static constexpr std::array<
794  std::array<unsigned, 4>,
795  2
796  > tetrahedra {{
797  {{ORIGIN_PLACEHOLDER, 0, 2, 1}},
798  {{3, ORIGIN_PLACEHOLDER, 5, 4}}
799  }};
800  static constexpr std::array<unsigned, 6> mirror {{0, 2, 1, 3, 5, 4}};
801 };
802 
821  static constexpr Shape shape = Shape::PentagonalPyramid;
822  static constexpr PointGroup pointGroup = PointGroup::C5v;
823  static constexpr unsigned size = 6;
824  static constexpr char stringName[] = "pentagonal pyramid";
825  static constexpr double angleFunction(const unsigned a, const unsigned b) {
826  if(a == b) {
827  return 0;
828  }
829 
830  if(a == 5 || b == 5) {
831  return M_PI / 2;
832  }
833 
834  // remainder are identical to Pentagon
835  unsigned absDiff = std::min(a - b, b - a);
836  return std::min(
837  absDiff,
838  std::min(absDiff - 5, 5 - absDiff)
839  ) * Temple::Math::toRadians<double>(72);
840  }
841  static constexpr std::array<Temple::Vector, 6> coordinates {{
842  {1, 0, 0},
843  {0.309017, 0.951057, 0},
844  {-0.809017, 0.587785, 0},
845  {-0.809017, -0.587785, 0},
846  {0.309017, -0.951057, 0},
847  {0, 0, 1}
848  }};
849  static constexpr std::array<
850  std::array<unsigned, 6>,
851  1
852  > rotations {{
853  {{4, 0, 1, 2, 3, 5}} // C5 axial
854  }};
855 
856  static constexpr std::array<
857  std::array<unsigned, 4>,
858  5
859  > tetrahedra {{
860  {{0, ORIGIN_PLACEHOLDER, 1, 5}},
861  {{1, ORIGIN_PLACEHOLDER, 2, 5}},
862  {{2, ORIGIN_PLACEHOLDER, 3, 5}},
863  {{3, ORIGIN_PLACEHOLDER, 4, 5}},
864  {{4, ORIGIN_PLACEHOLDER, 0, 5}}
865  }};
866  static constexpr std::array<unsigned, 6> mirror {{0, 4, 3, 2, 1, 5}};
867 };
868 
872 struct Hexagon {
873  static constexpr Shape shape = Shape::Hexagon;
874  static constexpr PointGroup pointGroup = PointGroup::D6h;
875  static constexpr unsigned size = 6;
876  static constexpr char stringName[] = "hexagon";
877  static constexpr double angleFunction(const unsigned a, const unsigned b) {
878  unsigned absDiff = std::min(a - b, b - a);
879  return std::min(
880  absDiff,
881  std::min(absDiff - 6, 6 - absDiff)
882  ) * Temple::Math::toRadians<double>(60);
883  }
884  static constexpr std::array<Temple::Vector, 6> coordinates {{
885  { 1.000000, 0.000000, 0.000000},
886  { 0.500000, 0.866025, 0.000000},
887  {-0.500000, 0.866025, 0.000000},
888  {-1.000000, 0.000000, 0.000000},
889  {-0.500000, -0.866025, 0.000000},
890  { 0.500000, -0.866025, 0.000000}
891  }};
892  static constexpr std::array<
893  std::array<unsigned, 6>,
894  2
895  > rotations {{
896  {{5, 0, 1, 2, 3, 4}}, // C6
897  {{0, 5, 4, 3, 2, 1}} // C2
898  }};
899 
900  static constexpr std::array<
901  std::array<unsigned, 4>,
902  0
903  > tetrahedra {{}};
904  static constexpr std::array<unsigned, 0> mirror {};
905 };
906 
926  static constexpr Shape shape = Shape::PentagonalBipyramid;
927  static constexpr PointGroup pointGroup = PointGroup::D5h;
928  static constexpr unsigned size = 7;
929  static constexpr char stringName[] = "pentagonal bipyramid";
930  static constexpr double angleFunction(const unsigned a, const unsigned b) {
931  if(a == b) {
932  return 0;
933  }
934 
935  if(a + b == 11) {
936  return M_PI; // trans 5,6
937  }
938 
939  if(Temple::Math::XOR(a > 4, b > 4)) {
940  return M_PI / 2; // any angle to axial index
941  }
942 
943  // remainder are equatorial angles, like Pentagon
944  unsigned absDiff = std::min(a - b, b - a);
945  return std::min(
946  absDiff,
947  std::min(absDiff - 5, 5 - absDiff)
948  ) * Temple::Math::toRadians<double>(72);
949  }
950  static constexpr std::array<Temple::Vector, 7> coordinates {{
951  {1, 0, 0},
952  {0.309017, 0.951057, 0},
953  {-0.809017, 0.587785, 0},
954  {-0.809017, -0.587785, 0},
955  {0.309017, -0.951057, 0},
956  {0, 0, 1},
957  {-0, -0, -1}
958  }};
959  static constexpr std::array<
960  std::array<unsigned, 7>,
961  2
962  > rotations {{
963  {{4, 0, 1, 2, 3, 5, 6}}, // C5 axial
964  {{1, 0, 4, 3, 2, 6, 5}} // C2 equatorial on 3
965  }};
966 
967  static constexpr std::array<
968  std::array<unsigned, 4>,
969  10
970  > tetrahedra {{
971  {{0, 1, 5, ORIGIN_PLACEHOLDER}},
972  {{1, 2, 5, ORIGIN_PLACEHOLDER}},
973  {{2, 3, 5, ORIGIN_PLACEHOLDER}},
974  {{3, 4, 5, ORIGIN_PLACEHOLDER}},
975  {{4, 0, 5, ORIGIN_PLACEHOLDER}},
976  {{0, 1, ORIGIN_PLACEHOLDER, 6}},
977  {{1, 2, ORIGIN_PLACEHOLDER, 6}},
978  {{2, 3, ORIGIN_PLACEHOLDER, 6}},
979  {{3, 4, ORIGIN_PLACEHOLDER, 6}},
980  {{4, 0, ORIGIN_PLACEHOLDER, 6}}
981  }};
982  static constexpr std::array<unsigned, 7> mirror {{0, 4, 3, 2, 1, 5, 6}};
983 };
984 
992  static constexpr Shape shape = Shape::CappedOctahedron;
993  static constexpr PointGroup pointGroup = PointGroup::C3v;
994  static constexpr unsigned size = 7;
995  static constexpr char stringName[] = "capped octahedron";
1002  static constexpr std::array<Temple::Vector, 7> coordinates {{
1003  { 0.000000, 0.000000, 1.000000},
1004  { 0.957729, 0.000000, 0.287673},
1005  {-0.478864, 0.829418, 0.287673},
1006  {-0.478864, -0.829418, 0.287673},
1007  { 0.389831, 0.675207, -0.626200},
1008  {-0.779662, 0.000000, -0.626200},
1009  { 0.389831, -0.675207, -0.626200}
1010  }};
1011  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1012  Detail::makeArray<size>(coordinates)
1013  );
1014  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1015  if(a == b) {
1016  return 0;
1017  }
1018 
1019  return angleLookupTable.at(
1020  std::min(a, b),
1021  std::max(a, b)
1022  );
1023  }
1024  static constexpr std::array<
1025  std::array<unsigned, 7>,
1026  1
1027  > rotations {{
1028  {{0, 3, 1, 2, 6, 4, 5}} // C3 axial
1029  }};
1030 
1031  static constexpr std::array<
1032  std::array<unsigned, 4>,
1033  2
1034  > tetrahedra {{
1035  {{0, 1, 2, 3}},
1036  {{0, 4, 5, 6}}
1037  }};
1038  static constexpr std::array<unsigned, 7> mirror {{0, 3, 2, 1, 6, 5, 4}};
1039 };
1040 
1047  static constexpr Shape shape = Shape::CappedTrigonalPrism;
1048  static constexpr PointGroup pointGroup = PointGroup::C2v;
1049  static constexpr unsigned size = 7;
1050  static constexpr char stringName[] = "capped trigonal prism";
1055  static constexpr std::array<Temple::Vector, 7> coordinates {{
1056  { -0.000000, -0.000000, 1.000000},
1057  { 0.984798, -0.069552, 0.159173},
1058  { -0.069552, 0.984798, 0.159173},
1059  { -0.984798, 0.069552, 0.159173},
1060  { 0.069552, -0.984798, 0.159173},
1061  { 0.413726, 0.413726, -0.810964},
1062  { -0.413726, -0.413726, -0.810964}
1063  }};
1064  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1065  Detail::makeArray<size>(coordinates)
1066  );
1067  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1068  if(a == b) {
1069  return 0;
1070  }
1071 
1072  return angleLookupTable.at(
1073  std::min(a, b),
1074  std::max(a, b)
1075  );
1076  }
1077  static constexpr std::array<
1078  std::array<unsigned, 7>,
1079  1
1080  > rotations {{
1081  {{0, 3, 4, 1, 2, 6, 5}} // C2 axial
1082  }};
1083 
1084  static constexpr std::array<
1085  std::array<unsigned, 4>,
1086  2
1087  > tetrahedra {{
1088  {{0, 1, 2, 5}},
1089  {{0, 3, 4, 6}}
1090  }};
1091  static constexpr std::array<unsigned, 7> mirror {{0, 2, 1, 4, 3, 5, 6}};
1092 };
1093 
1122  static constexpr Shape shape = Shape::SquareAntiprism;
1123  static constexpr PointGroup pointGroup = PointGroup::D4d;
1124  static constexpr unsigned size = 8;
1125  static constexpr char stringName[] = "square antiprism";
1126  static constexpr std::array<Temple::Vector, 8> coordinates {{
1127  { 0.607781, 0.607781, 0.511081},
1128  {-0.607781, 0.607781, 0.511081},
1129  {-0.607781, -0.607781, 0.511081},
1130  { 0.607781, -0.607781, 0.511081},
1131  { 0.859533, 0.000000, -0.511081},
1132  { 0.000000, 0.859533, -0.511081},
1133  {-0.859533, 0.000000, -0.511081},
1134  {-0.000000, -0.859533, -0.511081}
1135  }};
1136 
1142  Detail::makeArray<size>(coordinates)
1143  );
1144 
1145  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1146  if(a == b) {
1147  return 0;
1148  }
1149 
1150  return angleLookupTable.at(
1151  std::min(a, b),
1152  std::max(a, b)
1153  );
1154  }
1155  static constexpr std::array<
1156  std::array<unsigned, 8>,
1157  2
1158  > rotations {{
1159  {{3, 0, 1, 2, 7, 4, 5, 6}}, // C4 axial
1160  /* 180° on equatorial axis in plane with 4, 6
1161  *
1162  * 1 5 2
1163  * \ · /
1164  * – 4 ·( )· 6 –––––– equatorial axis
1165  * / · \
1166  * 0 7 3
1167  *
1168  * and 45° anticlockwise on axial axis
1169  *
1170  * 5 2 6
1171  * · | ·
1172  * 1 –( )– 3
1173  * · | ·
1174  * 4 0 7
1175  *
1176  */
1177  {{5, 4, 7, 6, 1, 0, 3, 2}},
1178  }};
1179 
1180  static constexpr std::array<
1181  std::array<unsigned, 4>,
1182  4
1183  > tetrahedra {{
1184  {{0, 1, 4, 5}},
1185  {{1, 2, 5, 6}},
1186  {{2, 3, 6, 7}},
1187  {{3, 0, 7, 4}}
1188  }};
1189  static constexpr std::array<unsigned, 8> mirror {{2, 1, 0, 3, 5, 4, 7, 6}};
1190 };
1191 
1195 struct Cube {
1196  static constexpr Shape shape = Shape::Cube;
1197  static constexpr PointGroup pointGroup = PointGroup::Oh;
1198  static constexpr unsigned size = 8;
1199  static constexpr char stringName[] = "cube";
1201  static constexpr std::array<Temple::Vector, 8> coordinates {{
1202  { 0.577350, 0.577350, 0.577350},
1203  { 0.577350, -0.577350, 0.577350},
1204  { 0.577350, -0.577350, -0.577350},
1205  { 0.577350, 0.577350, -0.577350},
1206  { -0.577350, 0.577350, 0.577350},
1207  { -0.577350, -0.577350, 0.577350},
1208  { -0.577350, -0.577350, -0.577350},
1209  { -0.577350, 0.577350, -0.577350}
1210  }};
1211  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1212  Detail::makeArray<size>(coordinates)
1213  );
1214  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1215  if(a == b) {
1216  return 0;
1217  }
1218 
1219  return angleLookupTable.at(
1220  std::min(a, b),
1221  std::max(a, b)
1222  );
1223  }
1224  static constexpr std::array<
1225  std::array<unsigned, 8>,
1226  2
1227  > rotations {{
1228  {{3, 0, 1, 2, 7, 4, 5, 6}}, // C4
1229  {{4, 5, 1, 0, 7, 6, 2, 3}} // C4'
1230  }};
1231 
1232  static constexpr std::array<
1233  std::array<unsigned, 4>,
1234  2
1235  > tetrahedra {{
1236  {{0, 1, 3, 5}},
1237  {{2, 4, 6, 7}}
1238  }};
1239  static constexpr std::array<unsigned, 8> mirror {{1, 0, 3, 2, 5, 4, 7, 6}};
1240 };
1241 
1246  static constexpr Shape shape = Shape::TrigonalDodecahedron;
1247  static constexpr PointGroup pointGroup = PointGroup::D2d;
1248  static constexpr unsigned size = 8;
1249  static constexpr char stringName[] = "trigonal dodecahedron";
1250  static constexpr std::array<Temple::Vector, 8> coordinates {{
1251  { 0.620913, 0.000000, -0.783880},
1252  { -0.620913, 0.000000, -0.783880},
1253  { 0.000000, 0.620913, 0.783880},
1254  { -0.000000, -0.620913, 0.783880},
1255  { 0.950273, 0.000000, 0.311417},
1256  { -0.950273, 0.000000, 0.311417},
1257  { 0.000000, 0.950273, -0.311417},
1258  { 0.000000, -0.950273, -0.311417}
1259  }};
1260  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1261  Detail::makeArray<size>(coordinates)
1262  );
1263  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1264  if(a == b) {
1265  return 0;
1266  }
1267 
1268  return angleLookupTable.at(
1269  std::min(a, b),
1270  std::max(a, b)
1271  );
1272  }
1273  static constexpr std::array<
1274  std::array<unsigned, 8>,
1275  2
1276  > rotations {{
1277  {1, 0, 3, 2, 5, 4, 7, 6}, // C2z between 01
1278  {2, 3, 0, 1, 6, 7, 4, 5} // C2x + C4z
1279  }};
1280 
1281  static constexpr std::array<
1282  std::array<unsigned, 4>,
1283  2
1284  > tetrahedra {{
1285  {4, 2, 3, 5},
1286  {0, 6, 7, 1}
1287  }};
1288  static constexpr std::array<unsigned, 8> mirror {{0, 1, 3, 2, 4, 5, 7, 6}};
1289 };
1290 
1297  static constexpr Shape shape = Shape::HexagonalBipyramid;
1298  static constexpr PointGroup pointGroup = PointGroup::D6h;
1299  static constexpr unsigned size = 8;
1300  static constexpr char stringName[] = "hexagonal bipyramid";
1301  static constexpr std::array<Temple::Vector, 8> coordinates {{
1302  { 1.000000, 0.000000, 0.000000},
1303  { 0.500000, 0.866025, 0.000000},
1304  {-0.500000, 0.866025, 0.000000},
1305  {-1.000000, 0.000000, 0.000000},
1306  {-0.500000, -0.866025, 0.000000},
1307  { 0.500000, -0.866025, 0.000000},
1308  { 0.000000, 0.000000, 1.000000},
1309  { 0.000000, 0.000000, -1.000000}
1310  }};
1311  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1312  Detail::makeArray<size>(coordinates)
1313  );
1314  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1315  if(a == b) {
1316  return 0;
1317  }
1318 
1319  return angleLookupTable.at(
1320  std::min(a, b),
1321  std::max(a, b)
1322  );
1323  }
1324  static constexpr std::array<
1325  std::array<unsigned, 8>,
1326  2
1327  > rotations {{
1328  {5, 0, 1, 2, 3, 4, 6, 7}, // axial C6
1329  {0, 5, 4, 3, 2, 1, 7, 6} // C2 around 0-3
1330  }};
1331 
1332  static constexpr std::array<
1333  std::array<unsigned, 4>,
1334  3
1335  > tetrahedra {{
1336  {6, 0, 1, 7},
1337  {6, 4, 5, 7},
1338  {6, 2, 3, 7}
1339  }};
1340  static constexpr std::array<unsigned, 8> mirror {{0, 5, 4, 3, 2, 1, 6, 7}};
1341 };
1342 
1350  static constexpr Shape shape = Shape::TricappedTrigonalPrism;
1351  static constexpr PointGroup pointGroup = PointGroup::D3h;
1352  static constexpr unsigned size = 9;
1353  static constexpr char stringName[] = "tricapped trigonal prism";
1354  static constexpr std::array<Temple::Vector, 9> coordinates {{
1355  { 0.914109572223, -0.182781178690, -0.361931942064},
1356  { 0.293329304506, 0.734642489361, -0.611766566546},
1357  {-0.480176899428, -0.046026929940, 0.875963279468},
1358  {-0.705684904851, 0.704780196051, -0.072757750931},
1359  { 0.370605109670, 0.769162968265, 0.520615194684},
1360  {-0.904030464226, -0.412626217894, -0.111662545460},
1361  {-0.162180419233, -0.247163999394, -0.955304908927},
1362  { 0.063327560246, -0.997971078243, -0.006583851785},
1363  { 0.610701141906, -0.322016246902, 0.723429092590}
1364  }};
1365  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1366  Detail::makeArray<size>(coordinates)
1367  );
1368  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1369  if(a == b) {
1370  return 0;
1371  }
1372 
1373  return angleLookupTable.at(
1374  std::min(a, b),
1375  std::max(a, b)
1376  );
1377  }
1378  static constexpr std::array<
1379  std::array<unsigned, 9>,
1380  2
1381  > rotations {{
1382  {7, 8, 3, 4, 2, 1, 0, 6, 5}, // C3 ccw between 2-4-3
1383  {2, 5, 0, 6, 7, 1, 3, 4, 8} // C2 at 8
1384  }};
1385 
1386  static constexpr std::array<
1387  std::array<unsigned, 4>,
1388  2
1389  > tetrahedra {{
1390  {1, 0, 6, 7},
1391  {5, 2, 3, 4}
1392  }};
1393  static constexpr std::array<unsigned, 9> mirror {{7, 5, 4, 3, 2, 1, 6, 0, 8}};
1394 };
1395 
1402  static constexpr Shape shape = Shape::CappedSquareAntiprism;
1403  static constexpr PointGroup pointGroup = PointGroup::C4v;
1404  static constexpr unsigned size = 9;
1405  static constexpr char stringName[] = "capped square antiprism";
1406  static constexpr std::array<Temple::Vector, 9> coordinates {{
1407  { -0.000000, 0.932111, 0.362172},
1408  { -0.000000, -0.932111, 0.362172},
1409  { 0.932111, -0.000000, 0.362172},
1410  { -0.932111, 0.000000, 0.362172},
1411  { 0.559626, 0.559626, -0.611258},
1412  { 0.559626, -0.559626, -0.611258},
1413  { -0.559626, 0.559626, -0.611258},
1414  { -0.559626, -0.559626, -0.611258},
1415  { 0.000000, 0.000000, 1.000000}
1416  }};
1417  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1418  Detail::makeArray<size>(coordinates)
1419  );
1420  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1421  if(a == b) {
1422  return 0;
1423  }
1424 
1425  return angleLookupTable.at(
1426  std::min(a, b),
1427  std::max(a, b)
1428  );
1429  }
1430  static constexpr std::array<
1431  std::array<unsigned, 9>,
1432  1
1433  > rotations {{
1434  {2, 3, 1, 0, 5, 7, 4, 6, 8}
1435  }};
1436 
1437  static constexpr std::array<
1438  std::array<unsigned, 4>,
1439  2
1440  > tetrahedra {{
1441  {6, 3, 0, 4},
1442  {7, 5, 1, 2}
1443  }};
1444  static constexpr std::array<unsigned, 9> mirror {{0, 1, 3, 2, 6, 7, 4, 5, 8}};
1445 };
1446 
1451  static constexpr Shape shape = Shape::HeptagonalBipyramid;
1452  static constexpr PointGroup pointGroup = PointGroup::D7h;
1453  static constexpr unsigned size = 9;
1454  static constexpr char stringName[] = "heptagonal bipyramid";
1455  static constexpr std::array<Temple::Vector, 9> coordinates {{
1456  { 1.000000, 0.000000, 0.000000},
1457  { 0.623490, 0.781831, 0.000000},
1458  {-0.222521, 0.974928, 0.000000},
1459  {-0.900969, 0.433884, 0.000000},
1460  {-0.900969, -0.433884, 0.000000},
1461  {-0.222521, -0.974928, 0.000000},
1462  { 0.623490, -0.781831, 0.000000},
1463  { 0.000000, 0.000000, 1.000000},
1464  { 0.000000, 0.000000, -1.000000}
1465  }};
1466  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1467  Detail::makeArray<size>(coordinates)
1468  );
1469  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1470  if(a == b) {
1471  return 0;
1472  }
1473 
1474  return angleLookupTable.at(
1475  std::min(a, b),
1476  std::max(a, b)
1477  );
1478  }
1479  static constexpr std::array<
1480  std::array<unsigned, 9>,
1481  2
1482  > rotations {{
1483  {6, 0, 1, 2, 3, 4, 5, 7, 8}, // axial C7
1484  {0, 6, 5, 4, 3, 2, 1, 8, 7} // C2 around 1 and between 4 and 5
1485  }};
1486 
1487  static constexpr std::array<
1488  std::array<unsigned, 4>,
1489  3
1490  > tetrahedra {{
1491  {8, 1, 0, 7},
1492  {8, 3, 2, 7},
1493  {8, 5, 4, 7}
1494  }};
1495  static constexpr std::array<unsigned, 9> mirror {{0, 6, 5, 4, 3, 2, 1, 7, 8}};
1496 };
1497 
1504  static constexpr Shape shape = Shape::BicappedSquareAntiprism;
1505  static constexpr PointGroup pointGroup = PointGroup::D4h;
1506  static constexpr unsigned size = 10;
1507  static constexpr char stringName[] = "bicapped square antiprism";
1508  static constexpr std::array<Temple::Vector, 10> coordinates {{
1509  { 0.978696890330, 0.074682616274, 0.191245663177},
1510  { 0.537258145625, 0.448413180814, -0.714338368164},
1511  {-0.227939324473, -0.303819959434, -0.925060590777},
1512  { 0.274577116268, 0.833436432027, 0.479573895237},
1513  {-0.599426405232, 0.240685139624, 0.763386303437},
1514  {-0.424664555168, 0.830194107787, -0.361161679833},
1515  {-0.402701180119, -0.893328907767, 0.199487398294},
1516  { 0.552788606831, -0.770301636525, -0.317899583084},
1517  { 0.290107593166, -0.385278374104, 0.876012647646},
1518  {-0.978696887344, -0.074682599351, -0.191245685067}
1519  }};
1520  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1521  Detail::makeArray<size>(coordinates)
1522  );
1523  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1524  if(a == b) {
1525  return 0;
1526  }
1527 
1528  return angleLookupTable.at(
1529  std::min(a, b),
1530  std::max(a, b)
1531  );
1532  }
1533  static constexpr std::array<
1534  std::array<unsigned, 10>,
1535  2
1536  > rotations {{
1537  {0, 7, 6, 1, 5, 2, 4, 8, 3, 9}, // C4z (0-9)
1538  {9, 5, 3, 2, 7, 1, 8, 4, 6, 0} // C2x + C8z
1539  }};
1540 
1541  static constexpr std::array<
1542  std::array<unsigned, 4>,
1543  3
1544  > tetrahedra {{
1545  {0, 6, 8, 7},
1546  {9, 3, 4, 5},
1547  {9, 2, 1, 5}
1548  }};
1549  static constexpr std::array<unsigned, 10> mirror {{0, 1, 5, 7, 6, 2, 4, 3, 8, 9}};
1550 };
1551 
1559  static constexpr Shape shape = Shape::EdgeContractedIcosahedron;
1560  static constexpr PointGroup pointGroup = PointGroup::C2v;
1561  static constexpr unsigned size = 11;
1562  static constexpr char stringName[] = "edge-contracted icosahedron";
1563  static constexpr std::array<Temple::Vector, 11> coordinates {{
1564  { 0.153486836562, -0.831354332797, 0.534127105044},
1565  { 0.092812115769, 0.691598091278, -0.716294626049},
1566  { 0.686120068086, 0.724987503180, 0.060269166267},
1567  { 0.101393837471, 0.257848797505, 0.960850293931},
1568  {-0.143059218646, -0.243142754178, -0.959382958495},
1569  {-0.909929380017, 0.200934944687, -0.362841110384},
1570  {-0.405338453688, 0.872713317547, 0.272162090194},
1571  { 0.896918545883, -0.184616420020, 0.401813264476},
1572  { 0.731466092268, -0.415052523977, -0.541007170195},
1573  {-0.439821168531, -0.864743799130, -0.242436592901},
1574  {-0.773718984882, -0.203685975092, 0.599892453681}
1575  }};
1576  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1577  Detail::makeArray<size>(coordinates)
1578  );
1579  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1580  if(a == b) {
1581  return 0;
1582  }
1583 
1584  return angleLookupTable.at(
1585  std::min(a, b),
1586  std::max(a, b)
1587  );
1588  }
1589  static constexpr std::array<
1590  std::array<unsigned, 11>,
1591  1
1592  > rotations {{
1593  {1, 0, 9, 5, 7, 3, 10, 4, 8, 2, 6} // C2
1594  }};
1595 
1596  static constexpr std::array<
1597  std::array<unsigned, 4>,
1598  3
1599  > tetrahedra {{
1600  {6, 1, 5, 4},
1601  {3, 10, 0, 9},
1602  {1, 2, 8, 7}
1603  }};
1604  static constexpr std::array<unsigned, 11> mirror {{2, 9, 0, 3, 4, 5, 10, 7, 8, 1, 6}};
1605 };
1606 
1610 struct Icosahedron {
1611  static constexpr Shape shape = Shape::Icosahedron;
1612  static constexpr PointGroup pointGroup = PointGroup::Ih;
1613  static constexpr unsigned size = 12;
1614  static constexpr char stringName[] = "icosahedron";
1615  static constexpr std::array<Temple::Vector, 12> coordinates {{
1616  { 0.525731, 0.000000, 0.850651},
1617  { 0.525731, 0.000000, -0.850651},
1618  {-0.525731, 0.000000, 0.850651},
1619  {-0.525731, 0.000000, -0.850651},
1620  { 0.850651, 0.525731, 0.000000},
1621  { 0.850651, -0.525731, 0.000000},
1622  {-0.850651, 0.525731, 0.000000},
1623  {-0.850651, -0.525731, 0.000000},
1624  { 0.000000, 0.850651, 0.525731},
1625  { 0.000000, 0.850651, -0.525731},
1626  { 0.000000, -0.850651, 0.525731},
1627  { 0.000000, -0.850651, -0.525731}
1628  }};
1629  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1630  Detail::makeArray<size>(coordinates)
1631  );
1632  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1633  if(a == b) {
1634  return 0;
1635  }
1636 
1637  return angleLookupTable.at(
1638  std::min(a, b),
1639  std::max(a, b)
1640  );
1641  }
1642  static constexpr std::array<
1643  std::array<unsigned, 12>,
1644  3
1645  > rotations {{
1646  {0, 11, 8, 3, 5, 10, 9, 6, 4, 1, 2, 7}, // C5 around 0-3
1647  {8, 5, 6, 11, 4, 0, 3, 7, 9, 1, 2, 10}, // C5 around 4-7
1648  {2, 3, 0, 1, 7, 6, 5, 4, 10, 11, 8, 9} // C2 between 0-2 / 1-3
1649  }};
1650 
1651  static constexpr std::array<
1652  std::array<unsigned, 4>,
1653  4
1654  > tetrahedra {{
1655  {0, 2, 10, 8},
1656  {1, 3, 9, 11},
1657  {1, 4, 5, 0},
1658  {3, 7, 6, 2}
1659  }};
1660  static constexpr std::array<unsigned, 12> mirror {{0, 1, 2, 3, 5, 4, 7, 6, 10, 11, 8, 9}};
1661 };
1662 
1667  static constexpr Shape shape = Shape::Cuboctahedron;
1668  static constexpr PointGroup pointGroup = PointGroup::Oh;
1669  static constexpr unsigned size = 12;
1670  static constexpr char stringName[] = "cuboctahedron";
1671  static constexpr std::array<Temple::Vector, 12> coordinates {{
1672  { 0.707107, 0.000000, 0.707107},
1673  { 0.707107, 0.000000, -0.707107},
1674  {-0.707107, 0.000000, 0.707107},
1675  {-0.707107, 0.000000, -0.707107},
1676  { 0.707107, 0.707107, 0.000000},
1677  { 0.707107, -0.707107, 0.000000},
1678  {-0.707107, 0.707107, 0.000000},
1679  {-0.707107, -0.707107, 0.000000},
1680  { 0.000000, 0.707107, 0.707107},
1681  { 0.000000, 0.707107, -0.707107},
1682  { 0.000000, -0.707107, 0.707107},
1683  { 0.000000, -0.707107, -0.707107}
1684  }};
1685  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1686  Detail::makeArray<size>(coordinates)
1687  );
1688  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1689  if(a == b) {
1690  return 0;
1691  }
1692 
1693  return angleLookupTable.at(
1694  std::min(a, b),
1695  std::max(a, b)
1696  );
1697  }
1698  static constexpr std::array<
1699  std::array<unsigned, 12>,
1700  3
1701  > rotations {{
1702  {10, 11, 8, 9, 5, 7, 4, 6, 0, 1, 2, 3}, // C4 ccw 0-8-2-10
1703  {2, 0, 3, 1, 8, 10, 9, 11, 6, 4, 7, 5}, // C4 ccw 4-9-6-8
1704  {7, 6, 5, 4, 3, 2, 1, 0, 11, 9, 10, 8}, // C2 along 9-10
1705  }};
1706 
1707  static constexpr std::array<
1708  std::array<unsigned, 4>,
1709  4
1710  > tetrahedra {{
1711  {ORIGIN_PLACEHOLDER, 6, 9, 8},
1712  {ORIGIN_PLACEHOLDER, 4, 1, 0},
1713  {ORIGIN_PLACEHOLDER, 5, 11, 10},
1714  {ORIGIN_PLACEHOLDER, 7, 3, 2}
1715  }};
1716  static constexpr std::array<unsigned, 12> mirror {{8, 9, 10, 11, 4, 6, 5, 7, 0, 1, 2, 3}};
1717 };
1718 
1720 using allShapeDataTypes = std::tuple<
1721  Line,
1722  Bent,
1723  EquilateralTriangle, // 3
1725  T,
1726  Tetrahedron, // 4
1727  Square,
1728  Seesaw,
1730  SquarePyramid, // 5
1732  Pentagon,
1733  Octahedron, // 6
1734  TrigonalPrism,
1736  Hexagon,
1737  PentagonalBipyramid, // 7
1740  SquareAntiprism, // 8
1741  Cube,
1749  Icosahedron, // 12,
1751 >;
1752 
1753 } // namespace Data
1754 } // namespace Shapes
1755 } // namespace Molassembler
1756 } // namespace Scine
1757 
1758 #endif
A square planar symmetry.
Definition: Data.h:322
Equilateral triangle shape (planar)
Definition: Data.h:131
constexpr UpperTriangularMatrix< ValueType, size > makeUpperTriangularMatrix(const ArrayType< ValueType, size > &data)
Helper constructing function that deduces the required type signature.
Definition: UpperTriangularMatrix.h:172
A regular tetrahedron shape.
Definition: Data.h:271
A pentagon shape (planar)
Definition: Data.h:634
A pentagonal pyramid shape, the J2 solid.
Definition: Data.h:820
Trigonal dodecahedron, snub disphenoid shape, spherized J84 solid in D2d.
Definition: Data.h:1245
Line shape.
Definition: Data.h:41
A regular cube.
Definition: Data.h:1195
Capped square antiprism shape, spherized J10 solid in C4v.
Definition: Data.h:1401
A trigonal bipyramid shape, the J12 solid.
Definition: Data.h:563
std::tuple< Line, Bent, EquilateralTriangle, VacantTetrahedron, T, Tetrahedron, Square, Seesaw, TrigonalPyramid, SquarePyramid, TrigonalBipyramid, Pentagon, Octahedron, TrigonalPrism, PentagonalPyramid, Hexagon, PentagonalBipyramid, CappedOctahedron, CappedTrigonalPrism, SquareAntiprism, Cube, TrigonalDodecahedron, HexagonalBipyramid, TricappedTrigonalPrism, CappedSquareAntiprism, HeptagonalBipyramid, BicappedSquareAntiprism, EdgeContractedIcosahedron, Icosahedron, Cuboctahedron > allShapeDataTypes
Type collecting all types of the Symmetry classes.
Definition: Data.h:1751
Regular icosahedron shape.
Definition: Data.h:1610
static constexpr std::array< Temple::Vector, 8 > coordinates
[V(CO)7]+ in C2v
Definition: Data.h:1201
Point group enum.
PointGroup
Point groups.
Definition: PointGroups.h:20
A regular octahedron.
Definition: Data.h:687
A face-centered trigonal pyramid shape = trig. pl. + an axial ligand.
Definition: Data.h:444
A seesaw shape.
Definition: Data.h:377
A regular trigonal prism shape.
Definition: Data.h:759
Bent symmetry at 107°
Definition: Data.h:81
Tricapped trigonal prism, spherized J51 solid in D3h.
Definition: Data.h:1349
Regular square antiprism shape.
Definition: Data.h:1121
Hexagon shape (planar)
Definition: Data.h:872
Provides type-level computations for types enumerated in a tuple.
Capped square antiprism shape, spherized J10 solid in C4v.
Definition: Data.h:1450
A square pyramid shape, the J1 solid (central position is square-face centered)
Definition: Data.h:497
static constexpr std::array< Temple::Vector, 7 > coordinates
Definition: Data.h:1055
Mono-vacant tetrahedron shape.
Definition: Data.h:179
A capped octahedron shape.
Definition: Data.h:991
static constexpr std::array< Temple::Vector, 7 > coordinates
Definition: Data.h:1002
3D Vector class with some operations defined
Line top: 0 ≅ IA &lt;&lt; IB = IC.
Defines symmetry names and total count.
A capped trigonal prism shape, spherized J49 solid in C2v.
Definition: Data.h:1046
Shape
Enumeration of all contained symmetry names.
Definition: Shapes.h:28
constexpr unsigned ORIGIN_PLACEHOLDER
A placeholder value for constexpr tetrahedra specification of origin.
Definition: Data.h:23
Generate lookup table for a symmetry&#39;s angles.
A pentagonal bipyramid shape, the J13 solid.
Definition: Data.h:925
Bicapped square antiprism shape, spherized J17 shape in D4h.
Definition: Data.h:1503
Edge contracted icosahedron shape.
Definition: Data.h:1558
static constexpr auto angleLookupTable
Definition: Data.h:1141
Regular cuboctahedron shape with Oh symmetry.
Definition: Data.h:1666
Hexagonal bipyramid shape.
Definition: Data.h:1296
A T-shaped symmetry.
Definition: Data.h:222