Molassembler  1.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 
18 
19 namespace Scine {
20 namespace Molassembler {
21 namespace Shapes {
22 
24 constexpr unsigned ORIGIN_PLACEHOLDER = std::numeric_limits<unsigned>::max();
25 
31 namespace Data {
32 
42 struct Line {
43  static constexpr Shape shape = Shape::Line;
44  static constexpr PointGroup pointGroup = PointGroup::Cinfv;
45  static constexpr unsigned size = 2;
46  static constexpr char stringName[] = "line";
47  static constexpr double angleFunction(const unsigned a, const unsigned b) {
48  if(a == b) {
49  return 0;
50  }
51 
52  return M_PI;
53  }
54  static constexpr std::array<Temple::Vector, 2> coordinates {{
55  { 1 , 0, 0 },
56  { -1, 0, 0 }
57  }};
58  static constexpr std::array<
59  std::array<unsigned, 2>,
60  1
61  > rotations {{
62  {{1, 0}}
63  }};
64  static constexpr std::array<
65  std::array<unsigned, 4>,
66  0
67  > tetrahedra {{}};
68  static constexpr std::array<unsigned, 0> mirror {};
69 };
70 
82 struct Bent {
83  static constexpr Shape shape = Shape::Bent;
84  static constexpr PointGroup pointGroup = PointGroup::C2v;
85  static constexpr unsigned size = 2;
86  static constexpr char stringName[] = "bent";
87  static constexpr double angleFunction(const unsigned a, const unsigned b) {
88  /* subject to a lot of variation, between 90 and 109 degrees pursuant to
89  * english wikipedia, using experimental data here to improve instances
90  * of this geometry on e.g. O center would a big improvement to DG runs
91  */
92  if(a == b) {
93  return 0;
94  }
95 
96  return Temple::Math::toRadians<double>(107);
97  }
98  static constexpr std::array<Temple::Vector, 2> coordinates {{
99  {1., 0., 0.},
100  {-0.292372, 0.956305, 0.}
101  }};
102  static constexpr std::array<
103  std::array<unsigned, 2>,
104  1
105  > rotations {{
106  {{1, 0}}
107  }};
108  static constexpr std::array<
109  std::array<unsigned, 4>,
110  0
111  > tetrahedra {{}};
112  static constexpr std::array<unsigned, 0> mirror {};
113 };
114 
133  static constexpr Shape shape = Shape::EquilateralTriangle;
134  static constexpr PointGroup pointGroup = PointGroup::D3h;
135  static constexpr unsigned size = 3;
136  static constexpr char stringName[] = "triangle";
137  static constexpr double angleFunction(const unsigned a, const unsigned b) {
138  if(a == b) {
139  return 0;
140  }
141 
142  return Temple::Math::toRadians<double>(120);
143  }
144  static constexpr std::array<Temple::Vector, 3> coordinates {{
145  {1, 0, 0},
146  {-0.5, 0.866025, 0},
147  {-0.5, -0.866025, 0}
148  }};
149  static constexpr std::array<
150  std::array<unsigned, 3>,
151  2
152  > rotations {{
153  {{1, 2, 0}}, // C3
154  {{0, 2, 1}} // C2
155  }};
156  static constexpr std::array<
157  std::array<unsigned, 4>,
158  0
159  > tetrahedra {{}};
160  static constexpr std::array<unsigned, 0> mirror {};
161 };
162 
181  static constexpr Shape shape = Shape::VacantTetrahedron;
182  static constexpr PointGroup pointGroup = PointGroup::C3v;
183  static constexpr unsigned size = 3;
184  static constexpr char stringName[] = "vacant tetrahedron";
185  static constexpr double angleFunction(const unsigned a, const unsigned b) {
186  if(a == b) {
187  return 0;
188  }
189 
190  return Temple::Math::toRadians<double>(107.5);
191  }
192  static constexpr std::array<Temple::Vector, 3> coordinates {{
193  {0, -0.366501, 0.930418},
194  {0.805765, -0.366501, -0.465209},
195  {-0.805765, -0.366501, -0.465209}
196  }};
197  static constexpr std::array<
198  std::array<unsigned, 3>,
199  1
200  > rotations {{
201  {{2, 0, 1}} // C3
202  }};
203  static constexpr std::array<
204  std::array<unsigned, 4>,
205  1
206  > tetrahedra {{
207  {{ORIGIN_PLACEHOLDER, 0, 1, 2}}
208  }};
209  static constexpr std::array<unsigned, 3> mirror {{0, 2, 1}};
210 };
211 
223 struct T {
224  static constexpr Shape shape = Shape::T;
225  static constexpr PointGroup pointGroup = PointGroup::C2v;
226  static constexpr unsigned size = 3;
227  static constexpr char stringName[] = "T-shaped";
228  static constexpr double angleFunction(const unsigned a, const unsigned b) {
229  if(a == b) {
230  return 0;
231  }
232 
233  if((a + b) % 2 == 1) {
234  return M_PI / 2;
235  }
236 
237  return M_PI;
238  }
239  static constexpr std::array<Temple::Vector, 3> coordinates {{
240  {-1, -0, -0},
241  {0, 1, 0},
242  {1, 0, 0},
243  }};
244  static constexpr std::array<
245  std::array<unsigned, 3>,
246  1
247  > rotations {{
248  {{2, 1, 0}} // C2
249  }};
250  static constexpr std::array<
251  std::array<unsigned, 4>,
252  0
253  > tetrahedra {{}};
254  static constexpr std::array<unsigned, 0> mirror {};
255 };
256 
272 struct Tetrahedron {
273  static constexpr Shape shape = Shape::Tetrahedron;
274  static constexpr PointGroup pointGroup = PointGroup::Td;
275  static constexpr unsigned size = 4;
276  static constexpr char stringName[] = "tetrahedron";
277  static constexpr double angleFunction(const unsigned a, const unsigned b) {
278  if(a == b) {
279  return 0;
280  }
281 
282  return 2 * Temple::Math::atan(M_SQRT2);
283  }
284  static constexpr std::array<Temple::Vector, 4> coordinates {{
285  {0, 1, 0},
286  {0, -0.333807, 0.942641},
287  {0.816351, -0.333807, -0.471321},
288  {-0.816351, -0.333807, -0.471321}
289  }};
290  static constexpr std::array<
291  std::array<unsigned, 4>,
292  4
293  > rotations {{
294  {{0, 3, 1, 2}}, // C4, 1
295  {{2, 1, 3, 0}}, // C4, 2
296  {{3, 0, 2, 1}}, // C4, 3
297  {{1, 2, 0, 3}} // C4, 4
298  }};
299  static constexpr std::array<
300  std::array<unsigned, 4>,
301  1
302  > tetrahedra {{
303  {{0, 1, 2, 3}}
304  }};
305  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
306 };
307 
323 struct Square {
324  static constexpr Shape shape = Shape::Square;
325  static constexpr PointGroup pointGroup = PointGroup::D4h;
326  static constexpr unsigned size = 4;
327  static constexpr char stringName[] = "square";
328  static constexpr double angleFunction(const unsigned a, const unsigned b) {
329  if(a == b) {
330  return 0;
331  }
332 
333  if((a + b) % 2 == 1) {
334  // this expression indicates cis
335  return M_PI / 2;
336  }
337 
338  // leftover case is trans
339  return M_PI;
340  }
341  static constexpr std::array<Temple::Vector, 4> coordinates {{
342  {1, 0, 0},
343  {0, 1, 0},
344  {-1, -0, -0},
345  {-0, -1, -0}
346  }};
347  static constexpr std::array<
348  std::array<unsigned, 4>,
349  3
350  > rotations {{
351  {{3, 0, 1, 2}}, // C4
352  {{1, 0, 3, 2}}, // C2
353  {{3, 2, 1, 0}} // C2'
354  }};
355  static constexpr std::array<
356  std::array<unsigned, 4>,
357  0
358  > tetrahedra {{}};
359  static constexpr std::array<unsigned, 0> mirror {};
360 };
361 
378 struct Seesaw {
379  static constexpr Shape shape = Shape::Seesaw;
380  static constexpr PointGroup pointGroup = PointGroup::C2v;
381  static constexpr unsigned size = 4;
382  static constexpr char stringName[] = "seesaw";
383  static constexpr double angleFunction(const unsigned a, const unsigned b) {
384  if(a == b) {
385  return 0;
386  }
387 
388  const auto& smaller = std::min(a, b);
389  const auto& larger = std::max(a, b);
390  if(smaller == 0 && larger == 3) {
391  return M_PI;
392  }
393 
394  if(smaller == 1 && larger == 2) {
395  return Temple::Math::toRadians<double>(120);
396  }
397 
398  return M_PI / 2;
399  }
400  static constexpr std::array<Temple::Vector, 4> coordinates {{
401  {0, 1, 0},
402  {1, 0, 0},
403  {-0.5, 0, -0.866025},
404  {-0, -1, -0}
405  }};
406  static constexpr std::array<
407  std::array<unsigned, 4>,
408  1
409  > rotations {{
410  {{3, 2, 1, 0}} // C2
411  }};
412 
413 #ifdef USE_ALTERNATE_TETRAHEDRA
414  static constexpr std::array<
415  std::array<unsigned, 4>,
416  1
417  > tetrahedra {{
418  {{0, 1, 2, 3}}
419  }};
420 #else // Regular
421  static constexpr std::array<
422  std::array<unsigned, 4>,
423  2
424  > tetrahedra {{
425  {{0, ORIGIN_PLACEHOLDER, 1, 2}},
426  {{ORIGIN_PLACEHOLDER, 3, 1, 2}},
427  }};
428 #endif
429 
430  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
431 };
432 
454  static constexpr Shape shape = Shape::TrigonalPyramid;
455  static constexpr PointGroup pointGroup = PointGroup::C3v;
456  static constexpr unsigned size = 4;
457  static constexpr char stringName[] = "trigonal pyramid";
458  static constexpr double angleFunction(const unsigned a, const unsigned b) {
459  if(a == b) {
460  return 0;
461  }
462 
463  if(std::max(a, b) != 3) {
464  // -> smaller < 2, this means either 0,1 0,2 1,2 axial
465  return Temple::Math::toRadians<double>(120);
466  }
467 
468  // -> smaller < 3, this means {1,2,3}, 3
469  return M_PI / 2;
470  }
471  static constexpr std::array<Temple::Vector, 4> coordinates {{
472  {1, 0, 0},
473  {-0.5, 0.866025, 0},
474  {-0.5, -0.866025, 0},
475  {0, 0, 1}
476  }};
477  static constexpr std::array<
478  std::array<unsigned, 4>,
479  1
480  > rotations {{
481  {{2, 0, 1, 3}} // C3
482  }};
483  static constexpr std::array<
484  std::array<unsigned, 4>,
485  1
486  > tetrahedra {{
487  {{0, 1, 3, 2}}
488  }};
489  static constexpr std::array<unsigned, 4> mirror {{0, 2, 1, 3}};
490 };
491 
507  static constexpr Shape shape = Shape::SquarePyramid;
508  static constexpr PointGroup pointGroup = PointGroup::C4v;
509  static constexpr unsigned size = 5;
510  static constexpr char stringName[] = "square pyramid";
511  static constexpr double angleFunction(const unsigned a, const unsigned b) {
512  if(a == b) {
513  return 0;
514  }
515 
516  if(a == 4 || b == 4) { // all bonds to axial ligand are 90°
517  return M_PI / 2;
518  }
519 
520  if((a + b) % 2 == 0) { // 0 + 2 or 1 + 3 are trans
521  return M_PI;
522  }
523 
524  // rest are cis
525  return M_PI / 2;
526  }
527  static constexpr std::array<Temple::Vector, 5> coordinates {{
528  {1, 0, 0},
529  {0, 1, 0},
530  {-1, -0, -0},
531  {-0, -1, -0},
532  {0, 0, 1}
533  }};
534  static constexpr std::array<
535  std::array<unsigned, 5>,
536  1
537  > rotations {{
538  {{3, 0, 1, 2, 4}} // C4
539  }};
540 
541 #ifdef USE_ALTERNATE_TETRAHEDRA
542  static constexpr std::array<
543  std::array<unsigned, 4>,
544  2
545  > tetrahedra {{
546  {{0, 1, 4, 2}},
547  {{0, 3, 2, 4}}
548  }};
549 #else // Regular
550  static constexpr std::array<
551  std::array<unsigned, 4>,
552  4
553  > tetrahedra {{
554  {{0, 1, 4, ORIGIN_PLACEHOLDER}},
555  {{1, 2, 4, ORIGIN_PLACEHOLDER}},
556  {{2, 3, 4, ORIGIN_PLACEHOLDER}},
557  {{3, 0, 4, ORIGIN_PLACEHOLDER}}
558  }};
559 #endif
560 
561  static constexpr std::array<unsigned, 5> mirror {{1, 0, 3, 2, 4}};
562 };
563 
583  static constexpr Shape shape = Shape::TrigonalBipyramid;
584  static constexpr PointGroup pointGroup = PointGroup::D3h;
585  static constexpr unsigned size = 5;
586  static constexpr char stringName[] = "trigonal bipyramid";
587  static constexpr double angleFunction(const unsigned a, const unsigned b) {
588  if(a == b) {
589  return 0;
590  }
591 
592  unsigned smaller = std::min(a, b), larger = std::max(a, b);
593  if(larger < 3) {
594  // -> smaller < 2, this means either 0,1 0,2 1,2 axial
595  return 2 * M_PI / 3;
596  }
597 
598  if(larger == 3) {
599  // -> smaller < 3, this means {1,2,3}, 3
600  return M_PI / 2;
601  }
602 
603  if(smaller < 3) {
604  // now, larger must be 4 (process of elimination), so if a is not 3:
605  return M_PI / 2;
606  }
607 
608  // only case left: 3,4
609  return M_PI;
610  }
611  static constexpr std::array<Temple::Vector, 5> coordinates {{
612  {1, 0, 0},
613  {-0.5, 0.866025, 0},
614  {-0.5, -0.866025, 0},
615  {0, 0, 1},
616  {-0, -0, -1}
617  }};
618  static constexpr std::array<
619  std::array<unsigned, 5>,
620  4
621  > rotations {{
622  {{2, 0, 1, 3, 4}}, // C3
623  {{0, 2, 1, 4, 3}}, // C2 on 0
624  {{2, 1, 0, 4, 3}}, // C2 on 1
625  {{1, 0, 2, 4, 3}} // C2 on 2
626  }};
627  static constexpr std::array<
628  std::array<unsigned, 4>,
629  2
630  > tetrahedra {{
631  {{0, 1, 3, 2}},
632  {{0, 1, 2, 4}}
633  }};
634  static constexpr std::array<unsigned, 5> mirror {{0, 2, 1, 3, 4}};
635 };
636 
652 struct Pentagon {
653  static constexpr Shape shape = Shape::Pentagon;
654  static constexpr PointGroup pointGroup = PointGroup::D5h;
655  static constexpr unsigned size = 5;
656  static constexpr char stringName[] = "pentagon";
657  static constexpr double angleFunction(const unsigned a, const unsigned b) {
658  unsigned absDiff = std::min(a - b, b - a);
659  return std::min(
660  absDiff,
661  std::min(absDiff - 5, 5 - absDiff)
662  ) * Temple::Math::toRadians<double>(72);
663  }
664  static constexpr std::array<Temple::Vector, 5> coordinates {{
665  {1, 0, 0},
666  {0.309017, 0.951057, 0},
667  {-0.809017, 0.587785, 0},
668  {-0.809017, -0.587785, 0},
669  {0.309017, -0.951057, 0}
670  }};
671  static constexpr std::array<
672  std::array<unsigned, 5>,
673  2
674  > rotations {{
675  {{4, 0, 1, 2, 3}}, // C5
676  {{0, 4, 3, 2, 1}} // C2
677  }};
678  static constexpr std::array<
679  std::array<unsigned, 4>,
680  0
681  > tetrahedra {{}};
682  static constexpr std::array<unsigned, 0> mirror {};
683 };
684 
705 struct Octahedron {
706  static constexpr Shape shape = Shape::Octahedron;
707  static constexpr PointGroup pointGroup = PointGroup::Oh;
708  static constexpr unsigned size = 6;
709  static constexpr char stringName[] = "octahedron";
710  static constexpr double angleFunction(const unsigned a, const unsigned b) {
711  if(a == b) {
712  return 0;
713  }
714 
715  if(
716  (
717  std::max(a, b) < 4 // if the largest is < 4, then equatorial
718  && (a + b) % 2 == 0 // this gives trans eq ligands
719  ) || std::min(a, b) == 4 // this indicates 4,5 (axial trans)
720  ) {
721  return M_PI;
722  }
723 
724  return M_PI / 2;
725  }
726  static constexpr std::array<Temple::Vector, 6> coordinates {{
727  {1, 0, 0},
728  {0, 1, 0},
729  {-1, -0, -0},
730  {-0, -1, -0},
731  {0, 0, 1},
732  {-0, -0, -1}
733  }};
734  static constexpr std::array<
735  std::array<unsigned, 6>,
736  3
737  > rotations {{
738  {{3, 0, 1, 2, 4, 5}}, // vertical C4
739  {{0, 5, 2, 4, 1, 3}}, // horizontal C4
740  {{4, 1, 5, 3, 2, 0}} // horizontal C4'
741  }};
742 
743 #ifdef USE_ALTERNATE_TETRAHEDRA
744  static constexpr std::array<
745  std::array<unsigned, 4>,
746  4
747  > tetrahedra {{
748  {{3, 0, 4, 5}},
749  {{0, 1, 4, 5}},
750  {{1, 2, 4, 5}},
751  {{2, 3, 4, 5}}
752  }};
753 #else // Regular
754  static constexpr std::array<
755  std::array<unsigned, 4>,
756  8
757  > tetrahedra {{
758  {{3, 0, 4, ORIGIN_PLACEHOLDER}},
759  {{0, 1, 4, ORIGIN_PLACEHOLDER}},
760  {{1, 2, 4, ORIGIN_PLACEHOLDER}},
761  {{2, 3, 4, ORIGIN_PLACEHOLDER}},
762  {{3, 0, ORIGIN_PLACEHOLDER, 5}},
763  {{0, 1, ORIGIN_PLACEHOLDER, 5}},
764  {{1, 2, ORIGIN_PLACEHOLDER, 5}},
765  {{2, 3, ORIGIN_PLACEHOLDER, 5}}
766  }};
767 #endif
768  static constexpr std::array<unsigned, 6> mirror {{1, 0, 3, 2, 4, 5}};
769 };
770 
790  static constexpr Shape shape = Shape::TrigonalPrism;
791  static constexpr PointGroup pointGroup = PointGroup::D3h;
792  static constexpr unsigned size = 6;
793  static constexpr char stringName[] = "trigonal prism";
794  static constexpr std::array<Temple::Vector, 6> coordinates {{
795  { 0.755929, 0.000000, 0.654654},
796  {-0.377964, 0.654654, 0.654654},
797  {-0.377964, -0.654654, 0.654654},
798  { 0.755929, 0.000000, -0.654654},
799  {-0.377964, 0.654654, -0.654654},
800  {-0.377964, -0.654654, -0.654654}
801  }};
802  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
803  Detail::makeArray<size>(coordinates)
804  );
805  static constexpr double angleFunction(const unsigned a, const unsigned b) {
806  if(a == b) {
807  return 0;
808  }
809 
810  return angleLookupTable.at(
811  std::min(a, b),
812  std::max(a, b)
813  );
814  }
815  static constexpr std::array<
816  std::array<unsigned, 6>,
817  2
818  > rotations {{
819  {{2, 0, 1, 5, 3, 4}}, // C3 axial
820  {{3, 5, 4, 0, 2, 1}} // C2 betw. 0, 3
821  }};
822 
823  static constexpr std::array<
824  std::array<unsigned, 4>,
825  2
826  > tetrahedra {{
827  {{ORIGIN_PLACEHOLDER, 0, 2, 1}},
828  {{3, ORIGIN_PLACEHOLDER, 5, 4}}
829  }};
830  static constexpr std::array<unsigned, 6> mirror {{0, 2, 1, 3, 5, 4}};
831 };
832 
851  static constexpr Shape shape = Shape::PentagonalPyramid;
852  static constexpr PointGroup pointGroup = PointGroup::C5v;
853  static constexpr unsigned size = 6;
854  static constexpr char stringName[] = "pentagonal pyramid";
855  static constexpr double angleFunction(const unsigned a, const unsigned b) {
856  if(a == b) {
857  return 0;
858  }
859 
860  if(a == 5 || b == 5) {
861  return M_PI / 2;
862  }
863 
864  // remainder are identical to Pentagon
865  unsigned absDiff = std::min(a - b, b - a);
866  return std::min(
867  absDiff,
868  std::min(absDiff - 5, 5 - absDiff)
869  ) * Temple::Math::toRadians<double>(72);
870  }
871  static constexpr std::array<Temple::Vector, 6> coordinates {{
872  {1, 0, 0},
873  {0.309017, 0.951057, 0},
874  {-0.809017, 0.587785, 0},
875  {-0.809017, -0.587785, 0},
876  {0.309017, -0.951057, 0},
877  {0, 0, 1}
878  }};
879  static constexpr std::array<
880  std::array<unsigned, 6>,
881  1
882  > rotations {{
883  {{4, 0, 1, 2, 3, 5}} // C5 axial
884  }};
885 
886 #ifdef USE_ALTERNATE_TETRAHEDRA
887  static constexpr std::array<
888  std::array<unsigned, 4>,
889  3
890  > tetrahedra {{
891  {{0, 1, 5, 2}},
892  {{2, 3, 5, 4}},
893  {{4, 5, ORIGIN_PLACEHOLDER, 0}}
894  }};
895 #else // Regular
896  static constexpr std::array<
897  std::array<unsigned, 4>,
898  5
899  > tetrahedra {{
900  {{0, ORIGIN_PLACEHOLDER, 1, 5}},
901  {{1, ORIGIN_PLACEHOLDER, 2, 5}},
902  {{2, ORIGIN_PLACEHOLDER, 3, 5}},
903  {{3, ORIGIN_PLACEHOLDER, 4, 5}},
904  {{4, ORIGIN_PLACEHOLDER, 0, 5}}
905  }};
906 #endif
907  static constexpr std::array<unsigned, 6> mirror {{0, 4, 3, 2, 1, 5}};
908 };
909 
913 struct Hexagon {
914  static constexpr Shape shape = Shape::Hexagon;
915  static constexpr PointGroup pointGroup = PointGroup::D6h;
916  static constexpr unsigned size = 6;
917  static constexpr char stringName[] = "hexagon";
918  static constexpr double angleFunction(const unsigned a, const unsigned b) {
919  unsigned absDiff = std::min(a - b, b - a);
920  return std::min(
921  absDiff,
922  std::min(absDiff - 6, 6 - absDiff)
923  ) * Temple::Math::toRadians<double>(60);
924  }
925  static constexpr std::array<Temple::Vector, 6> coordinates {{
926  { 1.000000, 0.000000, 0.000000},
927  { 0.500000, 0.866025, 0.000000},
928  {-0.500000, 0.866025, 0.000000},
929  {-1.000000, 0.000000, 0.000000},
930  {-0.500000, -0.866025, 0.000000},
931  { 0.500000, -0.866025, 0.000000}
932  }};
933  static constexpr std::array<
934  std::array<unsigned, 6>,
935  2
936  > rotations {{
937  {{5, 0, 1, 2, 3, 4}}, // C6
938  {{0, 5, 4, 3, 2, 1}} // C2
939  }};
940 
941  static constexpr std::array<
942  std::array<unsigned, 4>,
943  0
944  > tetrahedra {{}};
945  static constexpr std::array<unsigned, 0> mirror {};
946 };
947 
967  static constexpr Shape shape = Shape::PentagonalBipyramid;
968  static constexpr PointGroup pointGroup = PointGroup::D5h;
969  static constexpr unsigned size = 7;
970  static constexpr char stringName[] = "pentagonal bipyramid";
971  static constexpr double angleFunction(const unsigned a, const unsigned b) {
972  if(a == b) {
973  return 0;
974  }
975 
976  if(a + b == 11) {
977  return M_PI; // trans 5,6
978  }
979 
980  if(Temple::Math::XOR(a > 4, b > 4)) {
981  return M_PI / 2; // any angle to axial index
982  }
983 
984  // remainder are equatorial angles, like Pentagon
985  unsigned absDiff = std::min(a - b, b - a);
986  return std::min(
987  absDiff,
988  std::min(absDiff - 5, 5 - absDiff)
989  ) * Temple::Math::toRadians<double>(72);
990  }
991  static constexpr std::array<Temple::Vector, 7> coordinates {{
992  {1, 0, 0},
993  {0.309017, 0.951057, 0},
994  {-0.809017, 0.587785, 0},
995  {-0.809017, -0.587785, 0},
996  {0.309017, -0.951057, 0},
997  {0, 0, 1},
998  {-0, -0, -1}
999  }};
1000  static constexpr std::array<
1001  std::array<unsigned, 7>,
1002  2
1003  > rotations {{
1004  {{4, 0, 1, 2, 3, 5, 6}}, // C5 axial
1005  {{1, 0, 4, 3, 2, 6, 5}} // C2 equatorial on 3
1006  }};
1007 
1008 #ifdef USE_ALTERNATE_TETRAHEDRA
1009  static constexpr std::array<
1010  std::array<unsigned, 4>,
1011  5
1012  > tetrahedra {{
1013  {{0, 1, 5, 6}},
1014  {{1, 2, 5, 6}},
1015  {{2, 3, 5, 6}},
1016  {{3, 4, 5, 6}},
1017  {{4, 0, 5, 6}}
1018  }};
1019 #else // Regular
1020  static constexpr std::array<
1021  std::array<unsigned, 4>,
1022  10
1023  > tetrahedra {{
1024  {{0, 1, 5, ORIGIN_PLACEHOLDER}},
1025  {{1, 2, 5, ORIGIN_PLACEHOLDER}},
1026  {{2, 3, 5, ORIGIN_PLACEHOLDER}},
1027  {{3, 4, 5, ORIGIN_PLACEHOLDER}},
1028  {{4, 0, 5, ORIGIN_PLACEHOLDER}},
1029  {{0, 1, ORIGIN_PLACEHOLDER, 6}},
1030  {{1, 2, ORIGIN_PLACEHOLDER, 6}},
1031  {{2, 3, ORIGIN_PLACEHOLDER, 6}},
1032  {{3, 4, ORIGIN_PLACEHOLDER, 6}},
1033  {{4, 0, ORIGIN_PLACEHOLDER, 6}}
1034  }};
1035 #endif
1036  static constexpr std::array<unsigned, 7> mirror {{0, 4, 3, 2, 1, 5, 6}};
1037 };
1038 
1046  static constexpr Shape shape = Shape::CappedOctahedron;
1047  static constexpr PointGroup pointGroup = PointGroup::C3v;
1048  static constexpr unsigned size = 7;
1049  static constexpr char stringName[] = "capped octahedron";
1056  static constexpr std::array<Temple::Vector, 7> coordinates {{
1057  { 0.000000, 0.000000, 1.000000},
1058  { 0.957729, 0.000000, 0.287673},
1059  {-0.478864, 0.829418, 0.287673},
1060  {-0.478864, -0.829418, 0.287673},
1061  { 0.389831, 0.675207, -0.626200},
1062  {-0.779662, 0.000000, -0.626200},
1063  { 0.389831, -0.675207, -0.626200}
1064  }};
1065  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1066  Detail::makeArray<size>(coordinates)
1067  );
1068  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1069  if(a == b) {
1070  return 0;
1071  }
1072 
1073  return angleLookupTable.at(
1074  std::min(a, b),
1075  std::max(a, b)
1076  );
1077  }
1078  static constexpr std::array<
1079  std::array<unsigned, 7>,
1080  1
1081  > rotations {{
1082  {{0, 3, 1, 2, 6, 4, 5}} // C3 axial
1083  }};
1084 
1085  static constexpr std::array<
1086  std::array<unsigned, 4>,
1087  2
1088  > tetrahedra {{
1089  {{0, 1, 2, 3}},
1090  {{0, 4, 5, 6}}
1091  }};
1092  static constexpr std::array<unsigned, 7> mirror {{0, 3, 2, 1, 6, 5, 4}};
1093 };
1094 
1101  static constexpr Shape shape = Shape::CappedTrigonalPrism;
1102  static constexpr PointGroup pointGroup = PointGroup::C2v;
1103  static constexpr unsigned size = 7;
1104  static constexpr char stringName[] = "capped trigonal prism";
1109  static constexpr std::array<Temple::Vector, 7> coordinates {{
1110  { -0.000000, -0.000000, 1.000000},
1111  { 0.984798, -0.069552, 0.159173},
1112  { -0.069552, 0.984798, 0.159173},
1113  { -0.984798, 0.069552, 0.159173},
1114  { 0.069552, -0.984798, 0.159173},
1115  { 0.413726, 0.413726, -0.810964},
1116  { -0.413726, -0.413726, -0.810964}
1117  }};
1118  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1119  Detail::makeArray<size>(coordinates)
1120  );
1121  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1122  if(a == b) {
1123  return 0;
1124  }
1125 
1126  return angleLookupTable.at(
1127  std::min(a, b),
1128  std::max(a, b)
1129  );
1130  }
1131  static constexpr std::array<
1132  std::array<unsigned, 7>,
1133  1
1134  > rotations {{
1135  {{0, 3, 4, 1, 2, 6, 5}} // C2 axial
1136  }};
1137 
1138  static constexpr std::array<
1139  std::array<unsigned, 4>,
1140  2
1141  > tetrahedra {{
1142  {{0, 1, 2, 5}},
1143  {{0, 3, 4, 6}}
1144  }};
1145  static constexpr std::array<unsigned, 7> mirror {{0, 2, 1, 4, 3, 5, 6}};
1146 };
1147 
1176  static constexpr Shape shape = Shape::SquareAntiprism;
1177  static constexpr PointGroup pointGroup = PointGroup::D4d;
1178  static constexpr unsigned size = 8;
1179  static constexpr char stringName[] = "square antiprism";
1180  static constexpr std::array<Temple::Vector, 8> coordinates {{
1181  { 0.607781, 0.607781, 0.511081},
1182  {-0.607781, 0.607781, 0.511081},
1183  {-0.607781, -0.607781, 0.511081},
1184  { 0.607781, -0.607781, 0.511081},
1185  { 0.859533, 0.000000, -0.511081},
1186  { 0.000000, 0.859533, -0.511081},
1187  {-0.859533, 0.000000, -0.511081},
1188  {-0.000000, -0.859533, -0.511081}
1189  }};
1190 
1196  Detail::makeArray<size>(coordinates)
1197  );
1198 
1199  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1200  if(a == b) {
1201  return 0;
1202  }
1203 
1204  return angleLookupTable.at(
1205  std::min(a, b),
1206  std::max(a, b)
1207  );
1208  }
1209  static constexpr std::array<
1210  std::array<unsigned, 8>,
1211  2
1212  > rotations {{
1213  {{3, 0, 1, 2, 7, 4, 5, 6}}, // C4 axial
1214  /* 180° on equatorial axis in plane with 4, 6
1215  *
1216  * 1 5 2
1217  * \ · /
1218  * – 4 ·( )· 6 –––––– equatorial axis
1219  * / · \
1220  * 0 7 3
1221  *
1222  * and 45° anticlockwise on axial axis
1223  *
1224  * 5 2 6
1225  * · | ·
1226  * 1 –( )– 3
1227  * · | ·
1228  * 4 0 7
1229  *
1230  */
1231  {{5, 4, 7, 6, 1, 0, 3, 2}},
1232  }};
1233 
1234  static constexpr std::array<
1235  std::array<unsigned, 4>,
1236  4
1237  > tetrahedra {{
1238  {{0, 1, 4, 5}},
1239  {{1, 2, 5, 6}},
1240  {{2, 3, 6, 7}},
1241  {{3, 0, 7, 4}}
1242  }};
1243  static constexpr std::array<unsigned, 8> mirror {{2, 1, 0, 3, 5, 4, 7, 6}};
1244 };
1245 
1249 struct Cube {
1250  static constexpr Shape shape = Shape::Cube;
1251  static constexpr PointGroup pointGroup = PointGroup::Oh;
1252  static constexpr unsigned size = 8;
1253  static constexpr char stringName[] = "cube";
1255  static constexpr std::array<Temple::Vector, 8> coordinates {{
1256  { 0.577350, 0.577350, 0.577350},
1257  { 0.577350, -0.577350, 0.577350},
1258  { 0.577350, -0.577350, -0.577350},
1259  { 0.577350, 0.577350, -0.577350},
1260  { -0.577350, 0.577350, 0.577350},
1261  { -0.577350, -0.577350, 0.577350},
1262  { -0.577350, -0.577350, -0.577350},
1263  { -0.577350, 0.577350, -0.577350}
1264  }};
1265  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1266  Detail::makeArray<size>(coordinates)
1267  );
1268  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1269  if(a == b) {
1270  return 0;
1271  }
1272 
1273  return angleLookupTable.at(
1274  std::min(a, b),
1275  std::max(a, b)
1276  );
1277  }
1278  static constexpr std::array<
1279  std::array<unsigned, 8>,
1280  2
1281  > rotations {{
1282  {{3, 0, 1, 2, 7, 4, 5, 6}}, // C4
1283  {{4, 5, 1, 0, 7, 6, 2, 3}} // C4'
1284  }};
1285 
1286  static constexpr std::array<
1287  std::array<unsigned, 4>,
1288  2
1289  > tetrahedra {{
1290  {{0, 1, 3, 5}},
1291  {{2, 4, 6, 7}}
1292  }};
1293  static constexpr std::array<unsigned, 8> mirror {{1, 0, 3, 2, 5, 4, 7, 6}};
1294 };
1295 
1300  static constexpr Shape shape = Shape::TrigonalDodecahedron;
1301  static constexpr PointGroup pointGroup = PointGroup::D2d;
1302  static constexpr unsigned size = 8;
1303  static constexpr char stringName[] = "trigonal dodecahedron";
1304  static constexpr std::array<Temple::Vector, 8> coordinates {{
1305  { 0.620913, 0.000000, -0.783880},
1306  { -0.620913, 0.000000, -0.783880},
1307  { 0.000000, 0.620913, 0.783880},
1308  { -0.000000, -0.620913, 0.783880},
1309  { 0.950273, 0.000000, 0.311417},
1310  { -0.950273, 0.000000, 0.311417},
1311  { 0.000000, 0.950273, -0.311417},
1312  { 0.000000, -0.950273, -0.311417}
1313  }};
1314  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1315  Detail::makeArray<size>(coordinates)
1316  );
1317  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1318  if(a == b) {
1319  return 0;
1320  }
1321 
1322  return angleLookupTable.at(
1323  std::min(a, b),
1324  std::max(a, b)
1325  );
1326  }
1327  static constexpr std::array<
1328  std::array<unsigned, 8>,
1329  2
1330  > rotations {{
1331  {1, 0, 3, 2, 5, 4, 7, 6}, // C2z between 01
1332  {2, 3, 0, 1, 6, 7, 4, 5} // C2x + C4z
1333  }};
1334 
1335  static constexpr std::array<
1336  std::array<unsigned, 4>,
1337  2
1338  > tetrahedra {{
1339  {4, 2, 3, 5},
1340  {0, 6, 7, 1}
1341  }};
1342  static constexpr std::array<unsigned, 8> mirror {{0, 1, 3, 2, 4, 5, 7, 6}};
1343 };
1344 
1351  static constexpr Shape shape = Shape::HexagonalBipyramid;
1352  static constexpr PointGroup pointGroup = PointGroup::D6h;
1353  static constexpr unsigned size = 8;
1354  static constexpr char stringName[] = "hexagonal bipyramid";
1355  static constexpr std::array<Temple::Vector, 8> coordinates {{
1356  { 1.000000, 0.000000, 0.000000},
1357  { 0.500000, 0.866025, 0.000000},
1358  {-0.500000, 0.866025, 0.000000},
1359  {-1.000000, 0.000000, 0.000000},
1360  {-0.500000, -0.866025, 0.000000},
1361  { 0.500000, -0.866025, 0.000000},
1362  { 0.000000, 0.000000, 1.000000},
1363  { 0.000000, 0.000000, -1.000000}
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, 8>,
1380  2
1381  > rotations {{
1382  {5, 0, 1, 2, 3, 4, 6, 7}, // axial C6
1383  {0, 5, 4, 3, 2, 1, 7, 6} // C2 around 0-3
1384  }};
1385 
1386  static constexpr std::array<
1387  std::array<unsigned, 4>,
1388  3
1389  > tetrahedra {{
1390  {6, 0, 1, 7},
1391  {6, 4, 5, 7},
1392  {6, 2, 3, 7}
1393  }};
1394  static constexpr std::array<unsigned, 8> mirror {{0, 5, 4, 3, 2, 1, 6, 7}};
1395 };
1396 
1404  static constexpr Shape shape = Shape::TricappedTrigonalPrism;
1405  static constexpr PointGroup pointGroup = PointGroup::D3h;
1406  static constexpr unsigned size = 9;
1407  static constexpr char stringName[] = "tricapped trigonal prism";
1408  static constexpr std::array<Temple::Vector, 9> coordinates {{
1409  { 0.914109572223, -0.182781178690, -0.361931942064},
1410  { 0.293329304506, 0.734642489361, -0.611766566546},
1411  {-0.480176899428, -0.046026929940, 0.875963279468},
1412  {-0.705684904851, 0.704780196051, -0.072757750931},
1413  { 0.370605109670, 0.769162968265, 0.520615194684},
1414  {-0.904030464226, -0.412626217894, -0.111662545460},
1415  {-0.162180419233, -0.247163999394, -0.955304908927},
1416  { 0.063327560246, -0.997971078243, -0.006583851785},
1417  { 0.610701141906, -0.322016246902, 0.723429092590}
1418  }};
1419  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1420  Detail::makeArray<size>(coordinates)
1421  );
1422  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1423  if(a == b) {
1424  return 0;
1425  }
1426 
1427  return angleLookupTable.at(
1428  std::min(a, b),
1429  std::max(a, b)
1430  );
1431  }
1432  static constexpr std::array<
1433  std::array<unsigned, 9>,
1434  2
1435  > rotations {{
1436  {7, 8, 3, 4, 2, 1, 0, 6, 5}, // C3 ccw between 2-4-3
1437  {2, 5, 0, 6, 7, 1, 3, 4, 8} // C2 at 8
1438  }};
1439 
1440  static constexpr std::array<
1441  std::array<unsigned, 4>,
1442  2
1443  > tetrahedra {{
1444  {1, 0, 6, 7},
1445  {5, 2, 3, 4}
1446  }};
1447  static constexpr std::array<unsigned, 9> mirror {{7, 5, 4, 3, 2, 1, 6, 0, 8}};
1448 };
1449 
1456  static constexpr Shape shape = Shape::CappedSquareAntiprism;
1457  static constexpr PointGroup pointGroup = PointGroup::C4v;
1458  static constexpr unsigned size = 9;
1459  static constexpr char stringName[] = "capped square antiprism";
1460  static constexpr std::array<Temple::Vector, 9> coordinates {{
1461  { -0.000000, 0.932111, 0.362172},
1462  { -0.000000, -0.932111, 0.362172},
1463  { 0.932111, -0.000000, 0.362172},
1464  { -0.932111, 0.000000, 0.362172},
1465  { 0.559626, 0.559626, -0.611258},
1466  { 0.559626, -0.559626, -0.611258},
1467  { -0.559626, 0.559626, -0.611258},
1468  { -0.559626, -0.559626, -0.611258},
1469  { 0.000000, 0.000000, 1.000000}
1470  }};
1471  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1472  Detail::makeArray<size>(coordinates)
1473  );
1474  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1475  if(a == b) {
1476  return 0;
1477  }
1478 
1479  return angleLookupTable.at(
1480  std::min(a, b),
1481  std::max(a, b)
1482  );
1483  }
1484  static constexpr std::array<
1485  std::array<unsigned, 9>,
1486  1
1487  > rotations {{
1488  {2, 3, 1, 0, 5, 7, 4, 6, 8}
1489  }};
1490 
1491  static constexpr std::array<
1492  std::array<unsigned, 4>,
1493  2
1494  > tetrahedra {{
1495  {6, 3, 0, 4},
1496  {7, 5, 1, 2}
1497  }};
1498  static constexpr std::array<unsigned, 9> mirror {{0, 1, 3, 2, 6, 7, 4, 5, 8}};
1499 };
1500 
1505  static constexpr Shape shape = Shape::HeptagonalBipyramid;
1506  static constexpr PointGroup pointGroup = PointGroup::D7h;
1507  static constexpr unsigned size = 9;
1508  static constexpr char stringName[] = "heptagonal bipyramid";
1509  static constexpr std::array<Temple::Vector, 9> coordinates {{
1510  { 1.000000, 0.000000, 0.000000},
1511  { 0.623490, 0.781831, 0.000000},
1512  {-0.222521, 0.974928, 0.000000},
1513  {-0.900969, 0.433884, 0.000000},
1514  {-0.900969, -0.433884, 0.000000},
1515  {-0.222521, -0.974928, 0.000000},
1516  { 0.623490, -0.781831, 0.000000},
1517  { 0.000000, 0.000000, 1.000000},
1518  { 0.000000, 0.000000, -1.000000}
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, 9>,
1535  2
1536  > rotations {{
1537  {6, 0, 1, 2, 3, 4, 5, 7, 8}, // axial C7
1538  {0, 6, 5, 4, 3, 2, 1, 8, 7} // C2 around 1 and between 4 and 5
1539  }};
1540 
1541  static constexpr std::array<
1542  std::array<unsigned, 4>,
1543  3
1544  > tetrahedra {{
1545  {8, 1, 0, 7},
1546  {8, 3, 2, 7},
1547  {8, 5, 4, 7}
1548  }};
1549  static constexpr std::array<unsigned, 9> mirror {{0, 6, 5, 4, 3, 2, 1, 7, 8}};
1550 };
1551 
1558  static constexpr Shape shape = Shape::BicappedSquareAntiprism;
1559  static constexpr PointGroup pointGroup = PointGroup::D4h;
1560  static constexpr unsigned size = 10;
1561  static constexpr char stringName[] = "bicapped square antiprism";
1562  static constexpr std::array<Temple::Vector, 10> coordinates {{
1563  { 0.978696890330, 0.074682616274, 0.191245663177},
1564  { 0.537258145625, 0.448413180814, -0.714338368164},
1565  {-0.227939324473, -0.303819959434, -0.925060590777},
1566  { 0.274577116268, 0.833436432027, 0.479573895237},
1567  {-0.599426405232, 0.240685139624, 0.763386303437},
1568  {-0.424664555168, 0.830194107787, -0.361161679833},
1569  {-0.402701180119, -0.893328907767, 0.199487398294},
1570  { 0.552788606831, -0.770301636525, -0.317899583084},
1571  { 0.290107593166, -0.385278374104, 0.876012647646},
1572  {-0.978696887344, -0.074682599351, -0.191245685067}
1573  }};
1574  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1575  Detail::makeArray<size>(coordinates)
1576  );
1577  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1578  if(a == b) {
1579  return 0;
1580  }
1581 
1582  return angleLookupTable.at(
1583  std::min(a, b),
1584  std::max(a, b)
1585  );
1586  }
1587  static constexpr std::array<
1588  std::array<unsigned, 10>,
1589  2
1590  > rotations {{
1591  {0, 7, 6, 1, 5, 2, 4, 8, 3, 9}, // C4z (0-9)
1592  {9, 5, 3, 2, 7, 1, 8, 4, 6, 0} // C2x + C8z
1593  }};
1594 
1595  static constexpr std::array<
1596  std::array<unsigned, 4>,
1597  3
1598  > tetrahedra {{
1599  {0, 6, 8, 7},
1600  {9, 3, 4, 5},
1601  {9, 2, 1, 5}
1602  }};
1603  static constexpr std::array<unsigned, 10> mirror {{0, 1, 5, 7, 6, 2, 4, 3, 8, 9}};
1604 };
1605 
1613  static constexpr Shape shape = Shape::EdgeContractedIcosahedron;
1614  static constexpr PointGroup pointGroup = PointGroup::C2v;
1615  static constexpr unsigned size = 11;
1616  static constexpr char stringName[] = "edge-contracted icosahedron";
1617  static constexpr std::array<Temple::Vector, 11> coordinates {{
1618  { 0.153486836562, -0.831354332797, 0.534127105044},
1619  { 0.092812115769, 0.691598091278, -0.716294626049},
1620  { 0.686120068086, 0.724987503180, 0.060269166267},
1621  { 0.101393837471, 0.257848797505, 0.960850293931},
1622  {-0.143059218646, -0.243142754178, -0.959382958495},
1623  {-0.909929380017, 0.200934944687, -0.362841110384},
1624  {-0.405338453688, 0.872713317547, 0.272162090194},
1625  { 0.896918545883, -0.184616420020, 0.401813264476},
1626  { 0.731466092268, -0.415052523977, -0.541007170195},
1627  {-0.439821168531, -0.864743799130, -0.242436592901},
1628  {-0.773718984882, -0.203685975092, 0.599892453681}
1629  }};
1630  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1631  Detail::makeArray<size>(coordinates)
1632  );
1633  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1634  if(a == b) {
1635  return 0;
1636  }
1637 
1638  return angleLookupTable.at(
1639  std::min(a, b),
1640  std::max(a, b)
1641  );
1642  }
1643  static constexpr std::array<
1644  std::array<unsigned, 11>,
1645  1
1646  > rotations {{
1647  {1, 0, 9, 5, 7, 3, 10, 4, 8, 2, 6} // C2
1648  }};
1649 
1650  static constexpr std::array<
1651  std::array<unsigned, 4>,
1652  3
1653  > tetrahedra {{
1654  {6, 1, 5, 4},
1655  {3, 10, 0, 9},
1656  {1, 2, 8, 7}
1657  }};
1658  static constexpr std::array<unsigned, 11> mirror {{2, 9, 0, 3, 4, 5, 10, 7, 8, 1, 6}};
1659 };
1660 
1664 struct Icosahedron {
1665  static constexpr Shape shape = Shape::Icosahedron;
1666  static constexpr PointGroup pointGroup = PointGroup::Ih;
1667  static constexpr unsigned size = 12;
1668  static constexpr char stringName[] = "icosahedron";
1669  static constexpr std::array<Temple::Vector, 12> coordinates {{
1670  { 0.525731, 0.000000, 0.850651},
1671  { 0.525731, 0.000000, -0.850651},
1672  {-0.525731, 0.000000, 0.850651},
1673  {-0.525731, 0.000000, -0.850651},
1674  { 0.850651, 0.525731, 0.000000},
1675  { 0.850651, -0.525731, 0.000000},
1676  {-0.850651, 0.525731, 0.000000},
1677  {-0.850651, -0.525731, 0.000000},
1678  { 0.000000, 0.850651, 0.525731},
1679  { 0.000000, 0.850651, -0.525731},
1680  { 0.000000, -0.850651, 0.525731},
1681  { 0.000000, -0.850651, -0.525731}
1682  }};
1683  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1684  Detail::makeArray<size>(coordinates)
1685  );
1686  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1687  if(a == b) {
1688  return 0;
1689  }
1690 
1691  return angleLookupTable.at(
1692  std::min(a, b),
1693  std::max(a, b)
1694  );
1695  }
1696  static constexpr std::array<
1697  std::array<unsigned, 12>,
1698  3
1699  > rotations {{
1700  {0, 11, 8, 3, 5, 10, 9, 6, 4, 1, 2, 7}, // C5 around 0-3
1701  {8, 5, 6, 11, 4, 0, 3, 7, 9, 1, 2, 10}, // C5 around 4-7
1702  {2, 3, 0, 1, 7, 6, 5, 4, 10, 11, 8, 9} // C2 between 0-2 / 1-3
1703  }};
1704 
1705  static constexpr std::array<
1706  std::array<unsigned, 4>,
1707  4
1708  > tetrahedra {{
1709  {0, 2, 10, 8},
1710  {1, 3, 9, 11},
1711  {1, 4, 5, 0},
1712  {3, 7, 6, 2}
1713  }};
1714  static constexpr std::array<unsigned, 12> mirror {{0, 1, 2, 3, 5, 4, 7, 6, 10, 11, 8, 9}};
1715 };
1716 
1721  static constexpr Shape shape = Shape::Cuboctahedron;
1722  static constexpr PointGroup pointGroup = PointGroup::Oh;
1723  static constexpr unsigned size = 12;
1724  static constexpr char stringName[] = "cuboctahedron";
1725  static constexpr std::array<Temple::Vector, 12> coordinates {{
1726  { 0.707107, 0.000000, 0.707107},
1727  { 0.707107, 0.000000, -0.707107},
1728  {-0.707107, 0.000000, 0.707107},
1729  {-0.707107, 0.000000, -0.707107},
1730  { 0.707107, 0.707107, 0.000000},
1731  { 0.707107, -0.707107, 0.000000},
1732  {-0.707107, 0.707107, 0.000000},
1733  {-0.707107, -0.707107, 0.000000},
1734  { 0.000000, 0.707107, 0.707107},
1735  { 0.000000, 0.707107, -0.707107},
1736  { 0.000000, -0.707107, 0.707107},
1737  { 0.000000, -0.707107, -0.707107}
1738  }};
1739  static constexpr auto angleLookupTable = Temple::makeUpperTriangularMatrix(
1740  Detail::makeArray<size>(coordinates)
1741  );
1742  static constexpr double angleFunction(const unsigned a, const unsigned b) {
1743  if(a == b) {
1744  return 0;
1745  }
1746 
1747  return angleLookupTable.at(
1748  std::min(a, b),
1749  std::max(a, b)
1750  );
1751  }
1752  static constexpr std::array<
1753  std::array<unsigned, 12>,
1754  3
1755  > rotations {{
1756  {10, 11, 8, 9, 5, 7, 4, 6, 0, 1, 2, 3}, // C4 ccw 0-8-2-10
1757  {2, 0, 3, 1, 8, 10, 9, 11, 6, 4, 7, 5}, // C4 ccw 4-9-6-8
1758  {7, 6, 5, 4, 3, 2, 1, 0, 11, 9, 10, 8}, // C2 along 9-10
1759  }};
1760 
1761  static constexpr std::array<
1762  std::array<unsigned, 4>,
1763  4
1764  > tetrahedra {{
1765  {ORIGIN_PLACEHOLDER, 6, 9, 8},
1766  {ORIGIN_PLACEHOLDER, 4, 1, 0},
1767  {ORIGIN_PLACEHOLDER, 5, 11, 10},
1768  {ORIGIN_PLACEHOLDER, 7, 3, 2}
1769  }};
1770  static constexpr std::array<unsigned, 12> mirror {{8, 9, 10, 11, 4, 6, 5, 7, 0, 1, 2, 3}};
1771 };
1772 
1774 using allShapeDataTypes = std::tuple<
1775  Line,
1776  Bent,
1777  EquilateralTriangle, // 3
1779  T,
1780  Tetrahedron, // 4
1781  Square,
1782  Seesaw,
1784  SquarePyramid, // 5
1786  Pentagon,
1787  Octahedron, // 6
1788  TrigonalPrism,
1790  Hexagon,
1791  PentagonalBipyramid, // 7
1794  SquareAntiprism, // 8
1795  Cube,
1803  Icosahedron, // 12,
1805 >;
1806 
1807 } // namespace Data
1808 } // namespace Shapes
1809 } // namespace Molassembler
1810 } // namespace Scine
1811 
1812 #endif
A square planar symmetry.
Definition: Data.h:323
Equilateral triangle shape (planar)
Definition: Data.h:132
constexpr UpperTriangularMatrix< ValueType, size > makeUpperTriangularMatrix(const ArrayType< ValueType, size > &data)
Helper constructing function that deduces the required type signature.
Definition: UpperTriangularMatrix.h:176
A regular tetrahedron shape.
Definition: Data.h:272
A pentagon shape (planar)
Definition: Data.h:652
A pentagonal pyramid shape, the J2 solid.
Definition: Data.h:850
Trigonal dodecahedron, snub disphenoid shape, spherized J84 solid in D2d.
Definition: Data.h:1299
Line shape.
Definition: Data.h:42
A regular cube.
Definition: Data.h:1249
Capped square antiprism shape, spherized J10 solid in C4v.
Definition: Data.h:1455
A trigonal bipyramid shape, the J12 solid.
Definition: Data.h:582
Preprocessor definitions to alter library compilation behavior.
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:1805
Regular icosahedron shape.
Definition: Data.h:1664
static constexpr std::array< Temple::Vector, 8 > coordinates
[V(CO)7]+ in C2v
Definition: Data.h:1255
Point group enum.
PointGroup
Point groups.
Definition: PointGroups.h:20
A regular octahedron.
Definition: Data.h:705
A face-centered trigonal pyramid shape = trig. pl. + an axial ligand.
Definition: Data.h:453
A seesaw shape.
Definition: Data.h:378
A regular trigonal prism shape.
Definition: Data.h:789
Bent symmetry at 107°
Definition: Data.h:82
Tricapped trigonal prism, spherized J51 solid in D3h.
Definition: Data.h:1403
Regular square antiprism shape.
Definition: Data.h:1175
Hexagon shape (planar)
Definition: Data.h:913
Provides type-level computations for types enumerated in a tuple.
Capped square antiprism shape, spherized J10 solid in C4v.
Definition: Data.h:1504
A square pyramid shape, the J1 solid (central position is square-face centered)
Definition: Data.h:506
static constexpr std::array< Temple::Vector, 7 > coordinates
Definition: Data.h:1109
Mono-vacant tetrahedron shape.
Definition: Data.h:180
A capped octahedron shape.
Definition: Data.h:1045
static constexpr std::array< Temple::Vector, 7 > coordinates
Definition: Data.h:1056
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:1100
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:24
Generate lookup table for a symmetry&#39;s angles.
A pentagonal bipyramid shape, the J13 solid.
Definition: Data.h:966
Bicapped square antiprism shape, spherized J17 shape in D4h.
Definition: Data.h:1557
Edge contracted icosahedron shape.
Definition: Data.h:1612
static constexpr auto angleLookupTable
Definition: Data.h:1195
Regular cuboctahedron shape with Oh symmetry.
Definition: Data.h:1720
Hexagonal bipyramid shape.
Definition: Data.h:1350
A T-shaped symmetry.
Definition: Data.h:223